Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 #include "usage-analyzer.h" | 39 #include "usage-analyzer.h" |
| 40 | 40 |
| 41 namespace v8 { | 41 namespace v8 { |
| 42 namespace internal { | 42 namespace internal { |
| 43 | 43 |
| 44 | 44 |
| 45 class CodeGenSelector: public AstVisitor { | 45 class CodeGenSelector: public AstVisitor { |
| 46 public: | 46 public: |
| 47 enum CodeGenTag { NORMAL, FAST }; | 47 enum CodeGenTag { NORMAL, FAST }; |
| 48 | 48 |
| 49 CodeGenSelector() : has_supported_syntax_(true) {} | 49 CodeGenSelector() |
| 50 : has_supported_syntax_(true), | |
| 51 location_(Location::Nowhere()) { | |
|
fschneider
2009/10/28 10:06:01
I'm not sure: Should this match the default locati
Kevin Millikin (Chromium)
2009/10/28 11:39:38
Possibly. I wanted it to be nowhere when not insi
| |
| 52 } | |
| 50 | 53 |
| 51 CodeGenTag Select(FunctionLiteral* fun); | 54 CodeGenTag Select(FunctionLiteral* fun); |
| 52 | 55 |
| 53 private: | 56 private: |
| 54 void VisitDeclarations(ZoneList<Declaration*>* decls); | 57 void VisitDeclarations(ZoneList<Declaration*>* decls); |
| 55 void VisitStatements(ZoneList<Statement*>* stmts); | 58 void VisitStatements(ZoneList<Statement*>* stmts); |
| 56 | 59 |
| 60 // Visit an expression in effect context with a desired location of | |
| 61 // nowhere. | |
| 62 void VisitAsEffect(Expression* expr); | |
| 63 | |
| 64 // Visit an expression in value context with a desired location of | |
| 65 // temporary. | |
| 66 void VisitAsValue(Expression* expr); | |
| 67 | |
| 57 // AST node visit functions. | 68 // AST node visit functions. |
| 58 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); | 69 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); |
| 59 AST_NODE_LIST(DECLARE_VISIT) | 70 AST_NODE_LIST(DECLARE_VISIT) |
| 60 #undef DECLARE_VISIT | 71 #undef DECLARE_VISIT |
| 61 | 72 |
| 62 bool has_supported_syntax_; | 73 bool has_supported_syntax_; |
| 63 | 74 |
| 75 // The desired location of the currently visited expression. | |
| 76 Location location_; | |
| 77 | |
| 64 DISALLOW_COPY_AND_ASSIGN(CodeGenSelector); | 78 DISALLOW_COPY_AND_ASSIGN(CodeGenSelector); |
| 65 }; | 79 }; |
| 66 | 80 |
| 67 | 81 |
| 68 static Handle<Code> MakeCode(FunctionLiteral* literal, | 82 static Handle<Code> MakeCode(FunctionLiteral* literal, |
| 69 Handle<Script> script, | 83 Handle<Script> script, |
| 70 Handle<Context> context, | 84 Handle<Context> context, |
| 71 bool is_eval) { | 85 bool is_eval) { |
| 72 ASSERT(literal != NULL); | 86 ASSERT(literal != NULL); |
| 73 | 87 |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 | 506 |
| 493 | 507 |
| 494 void CodeGenSelector::VisitStatements(ZoneList<Statement*>* stmts) { | 508 void CodeGenSelector::VisitStatements(ZoneList<Statement*>* stmts) { |
| 495 for (int i = 0, len = stmts->length(); i < len; i++) { | 509 for (int i = 0, len = stmts->length(); i < len; i++) { |
| 496 Visit(stmts->at(i)); | 510 Visit(stmts->at(i)); |
| 497 CHECK_BAILOUT; | 511 CHECK_BAILOUT; |
| 498 } | 512 } |
| 499 } | 513 } |
| 500 | 514 |
| 501 | 515 |
| 516 void CodeGenSelector::VisitAsEffect(Expression* expr) { | |
| 517 if (location_.is_nowhere()) { | |
| 518 Visit(expr); | |
| 519 } else { | |
| 520 Location saved = location_; | |
| 521 location_ = Location::Nowhere(); | |
| 522 Visit(expr); | |
| 523 location_ = saved; | |
| 524 } | |
| 525 } | |
| 526 | |
| 527 | |
| 528 void CodeGenSelector::VisitAsValue(Expression* expr) { | |
| 529 if (location_.is_temporary()) { | |
| 530 Visit(expr); | |
| 531 } else { | |
| 532 Location saved = location_; | |
| 533 location_ = Location::Temporary(); | |
| 534 Visit(expr); | |
| 535 location_ = saved; | |
| 536 } | |
| 537 } | |
| 538 | |
| 539 | |
| 502 void CodeGenSelector::VisitDeclaration(Declaration* decl) { | 540 void CodeGenSelector::VisitDeclaration(Declaration* decl) { |
| 503 Variable* var = decl->proxy()->var(); | 541 Variable* var = decl->proxy()->var(); |
| 504 if (!var->is_global() || var->mode() == Variable::CONST) { | 542 if (!var->is_global() || var->mode() == Variable::CONST) { |
| 505 BAILOUT("Non-global declaration"); | 543 BAILOUT("Non-global declaration"); |
| 506 } | 544 } |
| 507 } | 545 } |
| 508 | 546 |
| 509 | 547 |
| 510 void CodeGenSelector::VisitBlock(Block* stmt) { | 548 void CodeGenSelector::VisitBlock(Block* stmt) { |
| 511 VisitStatements(stmt->statements()); | 549 VisitStatements(stmt->statements()); |
| 512 } | 550 } |
| 513 | 551 |
| 514 | 552 |
| 515 void CodeGenSelector::VisitExpressionStatement(ExpressionStatement* stmt) { | 553 void CodeGenSelector::VisitExpressionStatement(ExpressionStatement* stmt) { |
| 516 Expression* expr = stmt->expression(); | 554 VisitAsEffect(stmt->expression()); |
| 517 Visit(expr); | |
| 518 CHECK_BAILOUT; | |
| 519 expr->set_location(Location::Nowhere()); | |
| 520 } | 555 } |
| 521 | 556 |
| 522 | 557 |
| 523 void CodeGenSelector::VisitEmptyStatement(EmptyStatement* stmt) { | 558 void CodeGenSelector::VisitEmptyStatement(EmptyStatement* stmt) { |
| 524 // EmptyStatement is supported. | 559 // EmptyStatement is supported. |
| 525 } | 560 } |
| 526 | 561 |
| 527 | 562 |
| 528 void CodeGenSelector::VisitIfStatement(IfStatement* stmt) { | 563 void CodeGenSelector::VisitIfStatement(IfStatement* stmt) { |
| 529 BAILOUT("IfStatement"); | 564 BAILOUT("IfStatement"); |
| 530 } | 565 } |
| 531 | 566 |
| 532 | 567 |
| 533 void CodeGenSelector::VisitContinueStatement(ContinueStatement* stmt) { | 568 void CodeGenSelector::VisitContinueStatement(ContinueStatement* stmt) { |
| 534 BAILOUT("ContinueStatement"); | 569 BAILOUT("ContinueStatement"); |
| 535 } | 570 } |
| 536 | 571 |
| 537 | 572 |
| 538 void CodeGenSelector::VisitBreakStatement(BreakStatement* stmt) { | 573 void CodeGenSelector::VisitBreakStatement(BreakStatement* stmt) { |
| 539 BAILOUT("BreakStatement"); | 574 BAILOUT("BreakStatement"); |
| 540 } | 575 } |
| 541 | 576 |
| 542 | 577 |
| 543 void CodeGenSelector::VisitReturnStatement(ReturnStatement* stmt) { | 578 void CodeGenSelector::VisitReturnStatement(ReturnStatement* stmt) { |
| 544 Visit(stmt->expression()); | 579 VisitAsValue(stmt->expression()); |
| 545 } | 580 } |
| 546 | 581 |
| 547 | 582 |
| 548 void CodeGenSelector::VisitWithEnterStatement(WithEnterStatement* stmt) { | 583 void CodeGenSelector::VisitWithEnterStatement(WithEnterStatement* stmt) { |
| 549 BAILOUT("WithEnterStatement"); | 584 BAILOUT("WithEnterStatement"); |
| 550 } | 585 } |
| 551 | 586 |
| 552 | 587 |
| 553 void CodeGenSelector::VisitWithExitStatement(WithExitStatement* stmt) { | 588 void CodeGenSelector::VisitWithExitStatement(WithExitStatement* stmt) { |
| 554 BAILOUT("WithExitStatement"); | 589 BAILOUT("WithExitStatement"); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 592 | 627 |
| 593 void CodeGenSelector::VisitDebuggerStatement(DebuggerStatement* stmt) { | 628 void CodeGenSelector::VisitDebuggerStatement(DebuggerStatement* stmt) { |
| 594 BAILOUT("DebuggerStatement"); | 629 BAILOUT("DebuggerStatement"); |
| 595 } | 630 } |
| 596 | 631 |
| 597 | 632 |
| 598 void CodeGenSelector::VisitFunctionLiteral(FunctionLiteral* expr) { | 633 void CodeGenSelector::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 599 if (!expr->AllowsLazyCompilation()) { | 634 if (!expr->AllowsLazyCompilation()) { |
| 600 BAILOUT("FunctionLiteral does not allow lazy compilation"); | 635 BAILOUT("FunctionLiteral does not allow lazy compilation"); |
| 601 } | 636 } |
| 637 expr->set_location(location_); | |
| 602 } | 638 } |
| 603 | 639 |
| 604 | 640 |
| 605 void CodeGenSelector::VisitFunctionBoilerplateLiteral( | 641 void CodeGenSelector::VisitFunctionBoilerplateLiteral( |
| 606 FunctionBoilerplateLiteral* expr) { | 642 FunctionBoilerplateLiteral* expr) { |
| 607 BAILOUT("FunctionBoilerplateLiteral"); | 643 BAILOUT("FunctionBoilerplateLiteral"); |
| 608 } | 644 } |
| 609 | 645 |
| 610 | 646 |
| 611 void CodeGenSelector::VisitConditional(Conditional* expr) { | 647 void CodeGenSelector::VisitConditional(Conditional* expr) { |
| 612 BAILOUT("Conditional"); | 648 BAILOUT("Conditional"); |
| 613 } | 649 } |
| 614 | 650 |
| 615 | 651 |
| 616 void CodeGenSelector::VisitSlot(Slot* expr) { | 652 void CodeGenSelector::VisitSlot(Slot* expr) { |
| 617 Slot::Type type = expr->type(); | 653 UNREACHABLE(); |
| 618 if (type != Slot::PARAMETER && type != Slot::LOCAL) { | |
| 619 BAILOUT("non-parameter/non-local slot reference"); | |
| 620 } | |
| 621 } | 654 } |
| 622 | 655 |
| 623 | 656 |
| 624 void CodeGenSelector::VisitVariableProxy(VariableProxy* expr) { | 657 void CodeGenSelector::VisitVariableProxy(VariableProxy* expr) { |
| 625 Expression* rewrite = expr->var()->rewrite(); | 658 Expression* rewrite = expr->var()->rewrite(); |
| 626 if (rewrite != NULL) Visit(rewrite); | 659 // A rewrite of NULL indicates a global variable. |
| 660 if (rewrite != NULL) { | |
| 661 Slot* slot = rewrite->AsSlot(); | |
| 662 if (slot != NULL) { | |
| 663 Slot::Type type = slot->type(); | |
| 664 if (type != Slot::PARAMETER && type != Slot::LOCAL) { | |
| 665 BAILOUT("non-parameter/non-local slot reference"); | |
| 666 } | |
|
William Hesse
2009/10/28 10:28:54
Control flow is tricky here. Reversing sense of s
Kevin Millikin (Chromium)
2009/10/28 11:39:38
I see what you mean. I've changed it.
| |
| 667 } else { | |
| 668 BAILOUT("non-global/non-slot variable reference"); | |
| 669 } | |
| 670 } | |
| 671 expr->set_location(location_); | |
| 627 } | 672 } |
| 628 | 673 |
| 629 | 674 |
| 630 void CodeGenSelector::VisitLiteral(Literal* expr) { | 675 void CodeGenSelector::VisitLiteral(Literal* expr) { |
| 631 // Literals are supported. | 676 expr->set_location(location_); |
| 632 } | 677 } |
| 633 | 678 |
| 634 | 679 |
| 635 void CodeGenSelector::VisitRegExpLiteral(RegExpLiteral* expr) { | 680 void CodeGenSelector::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 636 // RegexpLiterals are supported. | 681 expr->set_location(location_); |
| 637 } | 682 } |
| 638 | 683 |
| 639 | 684 |
| 640 void CodeGenSelector::VisitObjectLiteral(ObjectLiteral* expr) { | 685 void CodeGenSelector::VisitObjectLiteral(ObjectLiteral* expr) { |
| 641 for (int i = 0; i < expr->properties()->length(); i++) { | 686 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); |
| 642 ObjectLiteral::Property* property = expr->properties()->at(i); | 687 |
| 643 Visit(property->key()); | 688 for (int i = 0, len = properties->length(); i < len; i++) { |
| 644 CHECK_BAILOUT; | 689 ObjectLiteral::Property* property = properties->at(i); |
| 645 Visit(property->value()); | 690 if (property->IsCompileTimeValue()) continue; |
| 691 | |
| 692 switch (property->kind()) { | |
| 693 case ObjectLiteral::Property::CONSTANT: | |
| 694 UNREACHABLE(); | |
| 695 | |
| 696 // For (non-compile-time) materialized literals and computed | |
| 697 // properties with symbolic keys we will use an IC and therefore not | |
| 698 // generate code for the key. | |
| 699 case ObjectLiteral::Property::COMPUTED: // Fall through. | |
| 700 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | |
| 701 if (property->key()->handle()->IsSymbol()) { | |
| 702 break; | |
| 703 } | |
| 704 // Fall through. | |
| 705 | |
| 706 // In all other cases we need the key's value on the stack | |
| 707 // for a runtime call. (Relies on TEMP meaning STACK.) | |
| 708 case ObjectLiteral::Property::GETTER: // Fall through. | |
| 709 case ObjectLiteral::Property::SETTER: // Fall through. | |
| 710 case ObjectLiteral::Property::PROTOTYPE: | |
| 711 VisitAsValue(property->key()); | |
| 712 CHECK_BAILOUT; | |
| 713 break; | |
| 714 } | |
| 715 VisitAsValue(property->value()); | |
| 646 CHECK_BAILOUT; | 716 CHECK_BAILOUT; |
| 647 } | 717 } |
| 718 expr->set_location(location_); | |
| 648 } | 719 } |
| 649 | 720 |
| 650 | 721 |
| 651 void CodeGenSelector::VisitArrayLiteral(ArrayLiteral* expr) { | 722 void CodeGenSelector::VisitArrayLiteral(ArrayLiteral* expr) { |
| 652 ZoneList<Expression*>* subexprs = expr->values(); | 723 ZoneList<Expression*>* subexprs = expr->values(); |
| 653 for (int i = 0, len = subexprs->length(); i < len; i++) { | 724 for (int i = 0, len = subexprs->length(); i < len; i++) { |
| 654 Expression* subexpr = subexprs->at(i); | 725 Expression* subexpr = subexprs->at(i); |
| 655 if (subexpr->AsLiteral() != NULL) continue; | 726 if (subexpr->AsLiteral() != NULL) continue; |
| 656 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 727 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
| 657 Visit(subexpr); | 728 VisitAsValue(subexpr); |
| 658 CHECK_BAILOUT; | 729 CHECK_BAILOUT; |
| 659 } | 730 } |
| 731 expr->set_location(location_); | |
| 660 } | 732 } |
| 661 | 733 |
| 662 | 734 |
| 663 void CodeGenSelector::VisitCatchExtensionObject(CatchExtensionObject* expr) { | 735 void CodeGenSelector::VisitCatchExtensionObject(CatchExtensionObject* expr) { |
| 664 BAILOUT("CatchExtensionObject"); | 736 BAILOUT("CatchExtensionObject"); |
| 665 } | 737 } |
| 666 | 738 |
| 667 | 739 |
| 668 void CodeGenSelector::VisitAssignment(Assignment* expr) { | 740 void CodeGenSelector::VisitAssignment(Assignment* expr) { |
| 669 // We support plain non-compound assignments to parameters and | 741 // We support plain non-compound assignments to parameters and |
| 670 // non-context (stack-allocated) locals. | 742 // non-context (stack-allocated) locals. |
| 671 if (expr->starts_initialization_block()) BAILOUT("initialization block"); | 743 if (expr->starts_initialization_block() || |
| 744 expr->ends_initialization_block()) { | |
| 745 BAILOUT("initialization block start"); | |
| 746 } | |
| 672 | 747 |
| 673 Token::Value op = expr->op(); | 748 Token::Value op = expr->op(); |
| 674 if (op == Token::INIT_CONST) BAILOUT("initialize constant"); | 749 if (op == Token::INIT_CONST) BAILOUT("initialize constant"); |
| 675 if (op != Token::ASSIGN && op != Token::INIT_VAR) { | 750 if (op != Token::ASSIGN && op != Token::INIT_VAR) { |
| 676 BAILOUT("compound assignment"); | 751 BAILOUT("compound assignment"); |
| 677 } | 752 } |
| 678 | 753 |
| 679 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 754 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| 680 if (var == NULL) BAILOUT("non-variable assignment"); | 755 if (var == NULL) BAILOUT("non-variable assignment"); |
| 681 | 756 |
| 682 if (!var->is_global()) { | 757 if (!var->is_global()) { |
| 683 ASSERT(var->slot() != NULL); | 758 ASSERT(var->slot() != NULL); |
| 684 Slot::Type type = var->slot()->type(); | 759 Slot::Type type = var->slot()->type(); |
| 685 if (type != Slot::PARAMETER && type != Slot::LOCAL) { | 760 if (type != Slot::PARAMETER && type != Slot::LOCAL) { |
| 686 BAILOUT("non-parameter/non-local slot assignment"); | 761 BAILOUT("non-parameter/non-local slot assignment"); |
| 687 } | 762 } |
| 688 } | 763 } |
| 689 | 764 |
| 690 Visit(expr->value()); | 765 VisitAsValue(expr->value()); |
| 766 expr->set_location(location_); | |
| 691 } | 767 } |
| 692 | 768 |
| 693 | 769 |
| 694 void CodeGenSelector::VisitThrow(Throw* expr) { | 770 void CodeGenSelector::VisitThrow(Throw* expr) { |
| 695 BAILOUT("Throw"); | 771 BAILOUT("Throw"); |
| 696 } | 772 } |
| 697 | 773 |
| 698 | 774 |
| 699 void CodeGenSelector::VisitProperty(Property* expr) { | 775 void CodeGenSelector::VisitProperty(Property* expr) { |
| 700 Visit(expr->obj()); | 776 Visit(expr->obj()); |
| 701 CHECK_BAILOUT; | 777 CHECK_BAILOUT; |
| 702 Visit(expr->key()); | 778 Visit(expr->key()); |
|
fschneider
2009/10/28 10:06:01
Also set location here:
expr->set_location(locati
Kevin Millikin (Chromium)
2009/10/28 11:39:38
You're right. Svn update can't rewrite these :)
| |
| 703 } | 779 } |
| 704 | 780 |
| 705 | 781 |
| 706 void CodeGenSelector::VisitCall(Call* expr) { | 782 void CodeGenSelector::VisitCall(Call* expr) { |
| 707 Expression* fun = expr->expression(); | 783 Expression* fun = expr->expression(); |
| 708 ZoneList<Expression*>* args = expr->arguments(); | 784 ZoneList<Expression*>* args = expr->arguments(); |
| 709 Variable* var = fun->AsVariableProxy()->AsVariable(); | 785 Variable* var = fun->AsVariableProxy()->AsVariable(); |
| 710 | 786 |
| 711 // Check for supported calls | 787 // Check for supported calls |
| 712 if (var != NULL && var->is_possibly_eval()) { | 788 if (var != NULL && var->is_possibly_eval()) { |
| 713 BAILOUT("Call to a function named 'eval'"); | 789 BAILOUT("Call to a function named 'eval'"); |
| 714 } else if (var != NULL && !var->is_this() && var->is_global()) { | 790 } else if (var != NULL && !var->is_this() && var->is_global()) { |
| 715 // ---------------------------------- | 791 // ---------------------------------- |
| 716 // JavaScript example: 'foo(1, 2, 3)' // foo is global | 792 // JavaScript example: 'foo(1, 2, 3)' // foo is global |
| 717 // ---------------------------------- | 793 // ---------------------------------- |
| 718 } else { | 794 } else { |
| 719 BAILOUT("Call to a non-global function"); | 795 BAILOUT("Call to a non-global function"); |
| 720 } | 796 } |
| 721 // Check all arguments to the call | 797 // Check all arguments to the call. (Relies on TEMP meaning STACK.) |
| 722 for (int i = 0; i < args->length(); i++) { | 798 for (int i = 0; i < args->length(); i++) { |
| 723 Visit(args->at(i)); | 799 VisitAsValue(args->at(i)); |
| 724 CHECK_BAILOUT; | 800 CHECK_BAILOUT; |
| 725 } | 801 } |
| 802 expr->set_location(location_); | |
| 726 } | 803 } |
| 727 | 804 |
| 728 | 805 |
| 729 void CodeGenSelector::VisitCallNew(CallNew* expr) { | 806 void CodeGenSelector::VisitCallNew(CallNew* expr) { |
| 730 Visit(expr->expression()); | 807 Visit(expr->expression()); |
| 731 CHECK_BAILOUT; | 808 CHECK_BAILOUT; |
| 732 ZoneList<Expression*>* args = expr->arguments(); | 809 ZoneList<Expression*>* args = expr->arguments(); |
| 733 // Check all arguments to the call | 810 // Check all arguments to the call |
| 734 for (int i = 0; i < args->length(); i++) { | 811 for (int i = 0; i < args->length(); i++) { |
| 735 Visit(args->at(i)); | 812 Visit(args->at(i)); |
| 736 CHECK_BAILOUT; | 813 CHECK_BAILOUT; |
| 737 } | 814 } |
|
fschneider
2009/10/28 10:06:01
Also set location here: expr->set_location(locatio
| |
| 738 } | 815 } |
| 739 | 816 |
| 740 | 817 |
| 741 void CodeGenSelector::VisitCallRuntime(CallRuntime* expr) { | 818 void CodeGenSelector::VisitCallRuntime(CallRuntime* expr) { |
| 742 // In case of JS runtime function bail out. | 819 // In case of JS runtime function bail out. |
| 743 if (expr->function() == NULL) BAILOUT("CallRuntime"); | 820 if (expr->function() == NULL) BAILOUT("call JS runtime function"); |
| 744 // Check for inline runtime call | 821 // Check for inline runtime call |
| 745 if (expr->name()->Get(0) == '_' && | 822 if (expr->name()->Get(0) == '_' && |
| 746 CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) { | 823 CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) { |
| 747 BAILOUT("InlineRuntimeCall"); | 824 BAILOUT("inlined runtime call"); |
| 748 } | 825 } |
| 826 // Check all arguments to the call. (Relies on TEMP meaning STACK.) | |
| 749 for (int i = 0; i < expr->arguments()->length(); i++) { | 827 for (int i = 0; i < expr->arguments()->length(); i++) { |
| 750 Visit(expr->arguments()->at(i)); | 828 VisitAsValue(expr->arguments()->at(i)); |
| 751 CHECK_BAILOUT; | 829 CHECK_BAILOUT; |
| 752 } | 830 } |
| 831 expr->set_location(location_); | |
| 753 } | 832 } |
| 754 | 833 |
| 755 | 834 |
| 756 void CodeGenSelector::VisitUnaryOperation(UnaryOperation* expr) { | 835 void CodeGenSelector::VisitUnaryOperation(UnaryOperation* expr) { |
| 757 BAILOUT("UnaryOperation"); | 836 BAILOUT("UnaryOperation"); |
| 758 } | 837 } |
| 759 | 838 |
| 760 | 839 |
| 761 void CodeGenSelector::VisitCountOperation(CountOperation* expr) { | 840 void CodeGenSelector::VisitCountOperation(CountOperation* expr) { |
| 762 BAILOUT("CountOperation"); | 841 BAILOUT("CountOperation"); |
| 763 } | 842 } |
| 764 | 843 |
| 765 | 844 |
| 766 void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) { | 845 void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) { |
| 767 switch (expr->op()) { | 846 switch (expr->op()) { |
| 768 case Token::OR: | 847 case Token::OR: |
| 769 Visit(expr->left()); | 848 VisitAsValue(expr->left()); |
| 770 CHECK_BAILOUT; | 849 CHECK_BAILOUT; |
| 850 // The location for the right subexpression is the same as for the | |
| 851 // whole expression. | |
| 771 Visit(expr->right()); | 852 Visit(expr->right()); |
| 772 break; | 853 break; |
| 773 | 854 |
| 774 default: | 855 default: |
| 775 BAILOUT("Unsupported binary operation"); | 856 BAILOUT("Unsupported binary operation"); |
| 776 } | 857 } |
| 858 expr->set_location(location_); | |
| 777 } | 859 } |
| 778 | 860 |
| 779 | 861 |
| 780 void CodeGenSelector::VisitCompareOperation(CompareOperation* expr) { | 862 void CodeGenSelector::VisitCompareOperation(CompareOperation* expr) { |
| 781 BAILOUT("CompareOperation"); | 863 BAILOUT("CompareOperation"); |
| 782 } | 864 } |
| 783 | 865 |
| 784 | 866 |
| 785 void CodeGenSelector::VisitThisFunction(ThisFunction* expr) { | 867 void CodeGenSelector::VisitThisFunction(ThisFunction* expr) { |
| 786 BAILOUT("ThisFunction"); | 868 BAILOUT("ThisFunction"); |
| 787 } | 869 } |
| 788 | 870 |
| 789 #undef BAILOUT | 871 #undef BAILOUT |
| 790 #undef CHECK_BAILOUT | 872 #undef CHECK_BAILOUT |
| 791 | 873 |
| 792 | 874 |
| 793 } } // namespace v8::internal | 875 } } // namespace v8::internal |
| OLD | NEW |