Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 void BreakableStatementChecker::VisitModuleVariable(ModuleVariable* module) { | 79 void BreakableStatementChecker::VisitModuleVariable(ModuleVariable* module) { |
| 80 } | 80 } |
| 81 | 81 |
| 82 void BreakableStatementChecker::VisitModulePath(ModulePath* module) { | 82 void BreakableStatementChecker::VisitModulePath(ModulePath* module) { |
| 83 } | 83 } |
| 84 | 84 |
| 85 void BreakableStatementChecker::VisitModuleUrl(ModuleUrl* module) { | 85 void BreakableStatementChecker::VisitModuleUrl(ModuleUrl* module) { |
| 86 } | 86 } |
| 87 | 87 |
| 88 | 88 |
| 89 void BreakableStatementChecker::VisitModuleStatement(ModuleStatement* stmt) { | |
| 90 } | |
| 91 | |
| 92 | |
| 89 void BreakableStatementChecker::VisitBlock(Block* stmt) { | 93 void BreakableStatementChecker::VisitBlock(Block* stmt) { |
| 90 } | 94 } |
| 91 | 95 |
| 92 | 96 |
| 93 void BreakableStatementChecker::VisitExpressionStatement( | 97 void BreakableStatementChecker::VisitExpressionStatement( |
| 94 ExpressionStatement* stmt) { | 98 ExpressionStatement* stmt) { |
| 95 // Check if expression is breakable. | 99 // Check if expression is breakable. |
| 96 Visit(stmt->expression()); | 100 Visit(stmt->expression()); |
| 97 } | 101 } |
| 98 | 102 |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 575 | 579 |
| 576 | 580 |
| 577 void FullCodeGenerator::DoTest(const TestContext* context) { | 581 void FullCodeGenerator::DoTest(const TestContext* context) { |
| 578 DoTest(context->condition(), | 582 DoTest(context->condition(), |
| 579 context->true_label(), | 583 context->true_label(), |
| 580 context->false_label(), | 584 context->false_label(), |
| 581 context->fall_through()); | 585 context->fall_through()); |
| 582 } | 586 } |
| 583 | 587 |
| 584 | 588 |
| 589 void FullCodeGenerator::AllocateModules(ZoneList<Declaration*>* declarations) { | |
| 590 ASSERT(scope_->is_global_scope()); | |
| 591 | |
| 592 for (int i = 0; i < declarations->length(); i++) { | |
| 593 ModuleDeclaration* declaration = declarations->at(i)->AsModuleDeclaration(); | |
| 594 if (declaration != NULL) { | |
| 595 ModuleLiteral* module = declaration->module()->AsModuleLiteral(); | |
| 596 if (module != NULL) { | |
| 597 Comment cmnt(masm_, "[ Link nested modules"); | |
| 598 Scope* scope = module->body()->scope(); | |
| 599 Interface* interface = scope->interface(); | |
| 600 ASSERT(interface->IsModule() && interface->IsFrozen()); | |
| 601 | |
| 602 interface->Allocate(scope->module_var()->index()); | |
| 603 | |
| 604 // Set up module context. | |
| 605 ASSERT(scope->interface()->Index() >= 0); | |
| 606 __ push(Immediate(Smi::FromInt(scope->interface()->Index()))); | |
| 607 __ push(Immediate(scope->GetScopeInfo())); | |
| 608 __ CallRuntime(Runtime::kPushModuleContext, 2); | |
| 609 StoreToFrameField(StandardFrameConstants::kContextOffset, | |
| 610 context_register()); | |
| 611 | |
| 612 AllocateModules(scope->declarations()); | |
| 613 | |
| 614 // Pop module context. | |
| 615 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | |
| 616 // Update local stack frame context field. | |
| 617 StoreToFrameField(StandardFrameConstants::kContextOffset, | |
| 618 context_register()); | |
| 619 } | |
| 620 } | |
| 621 } | |
| 622 } | |
| 623 | |
| 624 | |
| 625 // Modules have their own local scope, represented by their own context. | |
| 626 // Module instance objects have an accessor for every export that forwards | |
| 627 // access to the respective slot from the module's context. (Exports that are | |
| 628 // modules themselves, however, are simple data properties.) | |
| 629 // | |
| 630 // All modules have a _hosting_ scope/context, which (currently) is the | |
| 631 // (innermost) enclosing global scope. To deal with recursion, nested modules | |
| 632 // are hosted by the same scope as global ones. | |
| 633 // | |
| 634 // For every (global or nested) module literal, the hosting context has an | |
| 635 // internal slot that points directly to the respective module context. This | |
| 636 // enables quick access to (statically resolved) module members by 2-dimensional | |
| 637 // access through the hosting context. For example, | |
| 638 // | |
| 639 // module A { | |
| 640 // let x; | |
| 641 // module B { let y; } | |
| 642 // } | |
| 643 // module C { let z; } | |
| 644 // | |
| 645 // allocates contexts as follows: | |
| 646 // | |
| 647 // [header| .A | .B | .C | A | C ] (global) | |
| 648 // | | | | |
| 649 // | | +-- [header| z ] (module) | |
| 650 // | | | |
| 651 // | +------- [header| y ] (module) | |
| 652 // | | |
| 653 // +------------ [header| x | B ] (module) | |
| 654 // | |
| 655 // Here, .A, .B, .C are the internal slots pointing to the hosted module | |
| 656 // contexts, whereas A, B, C hold the actual instance objects (note that every | |
| 657 // module context also points to the respective instance object through its | |
| 658 // extension slot in the header). | |
| 659 // | |
| 660 // To deal with arbitrary recursion and aliases between modules, | |
| 661 // they are created and initialized in several stages. Each stage applies to | |
| 662 // all modules in the hosting global scope, including nested ones. | |
| 663 // | |
| 664 // 1. Allocate: for each module _literal_, allocate the module contexts and | |
| 665 // respective instance object and wire them up. This happens in the | |
| 666 // PushModuleContext runtime function, as generated by AllocateModules | |
| 667 // (invoked by VisitDeclarations in the hosting scope). | |
| 668 // | |
| 669 // 2. Bind: for each module _declaration_ (i.e. literals as well as aliases), | |
| 670 // assign the respective instance object to respective local variables. This | |
| 671 // happens in VisitModuleDeclaration, and uses the instance objects created | |
| 672 // in the previous stage. | |
| 673 // For each module _literal_, this phase also constructs a module descriptor | |
| 674 // for the next stage. This happens in VisitModuleLiteral. | |
| 675 // | |
| 676 // 3. Populate: invoke the DeclareModules runtime function to populate each | |
| 677 // _instance_ object with accessors for it exports. This is generated by | |
| 678 // DeclareModules (invoked by VisitDeclarations in the hosting scope again), | |
| 679 // and uses the descriptors generated in the previous stage. | |
| 680 // | |
| 681 // 4. Initialize: execute the module bodies (and other code) in sequence. This | |
| 682 // happens by the separate statements generated for module bodies. To reenter | |
| 683 // the module scopes properly, the parser inserted ModuleStatements. | |
| 684 | |
| 585 void FullCodeGenerator::VisitDeclarations( | 685 void FullCodeGenerator::VisitDeclarations( |
| 586 ZoneList<Declaration*>* declarations) { | 686 ZoneList<Declaration*>* declarations) { |
| 687 Handle<FixedArray> saved_modules = modules_; | |
| 688 int saved_module_index = module_index_; | |
| 587 ZoneList<Handle<Object> >* saved_globals = globals_; | 689 ZoneList<Handle<Object> >* saved_globals = globals_; |
| 588 ZoneList<Handle<Object> > inner_globals(10, zone()); | 690 ZoneList<Handle<Object> > inner_globals(10, zone()); |
| 589 globals_ = &inner_globals; | 691 globals_ = &inner_globals; |
| 590 | 692 |
| 693 if (scope_->num_modules() != 0) { | |
| 694 // This is a scope hosting modules. Allocate a descriptor array to pass | |
| 695 // to the runtime for initialization. | |
| 696 Comment cmnt(masm_, "[ Allocate modules"); | |
| 697 ASSERT(scope_->is_global_scope()); | |
| 698 modules_ = | |
| 699 isolate()->factory()->NewFixedArray(scope_->num_modules(), TENURED); | |
| 700 module_index_ = 0; | |
| 701 | |
| 702 // Generate code for allocating all modules, including nested ones. | |
| 703 // The allocated contexts are stored in internal variables in this scope. | |
| 704 AllocateModules(declarations); | |
| 705 } | |
| 706 | |
| 591 AstVisitor::VisitDeclarations(declarations); | 707 AstVisitor::VisitDeclarations(declarations); |
| 708 | |
| 709 if (scope_->num_modules() != 0) { | |
| 710 // Initialize modules from descriptor array. | |
| 711 ASSERT(module_index_ == modules_->length()); | |
| 712 DeclareModules(modules_); | |
| 713 modules_ = saved_modules; | |
| 714 module_index_ = saved_module_index; | |
| 715 } | |
| 716 | |
| 592 if (!globals_->is_empty()) { | 717 if (!globals_->is_empty()) { |
| 593 // Invoke the platform-dependent code generator to do the actual | 718 // Invoke the platform-dependent code generator to do the actual |
| 594 // declaration the global functions and variables. | 719 // declaration of the global functions and variables. |
| 595 Handle<FixedArray> array = | 720 Handle<FixedArray> array = |
| 596 isolate()->factory()->NewFixedArray(globals_->length(), TENURED); | 721 isolate()->factory()->NewFixedArray(globals_->length(), TENURED); |
| 597 for (int i = 0; i < globals_->length(); ++i) | 722 for (int i = 0; i < globals_->length(); ++i) |
| 598 array->set(i, *globals_->at(i)); | 723 array->set(i, *globals_->at(i)); |
| 599 DeclareGlobals(array); | 724 DeclareGlobals(array); |
| 600 } | 725 } |
| 601 | 726 |
| 602 globals_ = saved_globals; | 727 globals_ = saved_globals; |
| 603 } | 728 } |
| 604 | 729 |
| 605 | 730 |
| 606 void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) { | 731 void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) { |
| 607 // Allocate a module context statically. | |
| 608 Block* block = module->body(); | 732 Block* block = module->body(); |
| 609 Scope* saved_scope = scope(); | 733 Scope* saved_scope = scope(); |
| 610 scope_ = block->scope(); | 734 scope_ = block->scope(); |
| 611 Interface* interface = module->interface(); | 735 Interface* interface = scope_->interface(); |
| 612 Handle<JSModule> instance = interface->Instance(); | |
| 613 | 736 |
| 614 Comment cmnt(masm_, "[ ModuleLiteral"); | 737 Comment cmnt(masm_, "[ ModuleLiteral"); |
| 615 SetStatementPosition(block); | 738 SetStatementPosition(block); |
| 616 | 739 |
| 740 ASSERT(!modules_.is_null()); | |
| 741 ASSERT(module_index_ < modules_->length()); | |
| 742 int index = module_index_++; | |
| 743 | |
| 617 // Set up module context. | 744 // Set up module context. |
| 618 __ Push(instance); | 745 ASSERT(interface->Index() >= 0); |
| 619 __ CallRuntime(Runtime::kPushModuleContext, 1); | 746 __ push(Immediate(Smi::FromInt(interface->Index()))); |
|
Michael Starzinger
2012/11/20 12:05:05
See comment further down the file.
rossberg
2012/11/20 17:23:45
Done.
| |
| 747 __ push(Immediate(Smi::FromInt(0))); | |
| 748 __ CallRuntime(Runtime::kPushModuleContext, 2); | |
| 620 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); | 749 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); |
| 621 | 750 |
| 622 { | 751 { |
| 623 Comment cmnt(masm_, "[ Declarations"); | 752 Comment cmnt(masm_, "[ Declarations"); |
| 624 VisitDeclarations(scope_->declarations()); | 753 VisitDeclarations(scope_->declarations()); |
| 625 } | 754 } |
| 626 | 755 |
| 756 // Populate the module description. The format is: | |
| 757 // | |
| 758 // Index, (Name, VariableMode, Index)* | |
| 759 // | |
| 760 // That is, the first slot is the index of the module's context in the | |
| 761 // host context, then a sequence of triples follows that describes its | |
| 762 // exports. Index is either the slot index in the module context, or | |
| 763 // (for exported modules) the slot index of the referred module's | |
| 764 // context in the host context. | |
|
Sven Panne
2012/11/20 14:39:13
Can we abstract this index magic into a separate c
rossberg
2012/11/20 17:23:45
Done. Of course, in C++ that means thrice as much
| |
| 765 // TODO(rossberg): Cannot yet handle exports of modules declared in | |
| 766 // earlier scripts. | |
| 767 Handle<FixedArray> description = | |
| 768 isolate()->factory()->NewFixedArray(1 + 3 * interface->Length()); | |
| 769 description->set(0, Smi::FromInt(interface->Index())); | |
| 770 int i = 1; | |
| 771 for (Interface::Iterator it = interface->iterator(); | |
| 772 !it.done(); it.Advance()) { | |
| 773 Variable* var = scope_->LocalLookup(it.name()); | |
| 774 description->set(i++, *it.name()); | |
| 775 description->set(i++, Smi::FromInt(var->mode())); | |
| 776 ASSERT((var->mode() == MODULE) == (it.interface()->IsModule())); | |
| 777 if (var->mode() == MODULE) { | |
| 778 ASSERT(it.interface()->IsFrozen()); | |
| 779 ASSERT(it.interface()->Index() >= 0); | |
| 780 description->set(i++, Smi::FromInt(it.interface()->Index())); | |
| 781 } else { | |
| 782 ASSERT(var->index() >= 0); | |
| 783 description->set(i++, Smi::FromInt(var->index())); | |
| 784 } | |
| 785 } | |
| 786 ASSERT(i == description->length()); | |
| 787 modules_->set(index, *description); | |
| 788 | |
| 627 scope_ = saved_scope; | 789 scope_ = saved_scope; |
| 628 // Pop module context. | 790 // Pop module context. |
| 629 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | 791 LoadContextField(context_register(), Context::PREVIOUS_INDEX); |
| 630 // Update local stack frame context field. | 792 // Update local stack frame context field. |
| 631 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); | 793 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); |
| 632 } | 794 } |
| 633 | 795 |
| 634 | 796 |
| 635 void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) { | 797 void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) { |
| 636 // Nothing to do. | 798 // Nothing to do. |
| 637 // The instance object is resolved statically through the module's interface. | 799 // The instance object is resolved statically through the module's interface. |
| 638 } | 800 } |
| 639 | 801 |
| 640 | 802 |
| 641 void FullCodeGenerator::VisitModulePath(ModulePath* module) { | 803 void FullCodeGenerator::VisitModulePath(ModulePath* module) { |
| 642 // Nothing to do. | 804 // Nothing to do. |
| 643 // The instance object is resolved statically through the module's interface. | 805 // The instance object is resolved statically through the module's interface. |
| 644 } | 806 } |
| 645 | 807 |
| 646 | 808 |
| 647 void FullCodeGenerator::VisitModuleUrl(ModuleUrl* decl) { | 809 void FullCodeGenerator::VisitModuleUrl(ModuleUrl* module) { |
| 648 // TODO(rossberg) | 810 // TODO(rossberg): dummy allocation for now. |
| 811 Scope* scope = module->body()->scope(); | |
| 812 Interface* interface = scope_->interface(); | |
| 813 | |
| 814 ASSERT(interface->IsModule() && interface->IsFrozen()); | |
| 815 ASSERT(!modules_.is_null()); | |
| 816 ASSERT(module_index_ < modules_->length()); | |
| 817 interface->Allocate(scope->module_var()->index()); | |
| 818 int index = module_index_++; | |
| 819 | |
| 820 Handle<FixedArray> description = isolate()->factory()->NewFixedArray(2); | |
| 821 description->set(0, Smi::FromInt(interface->Index())); | |
| 822 description->set(1, *scope->GetScopeInfo()); | |
|
Michael Starzinger
2012/11/20 12:05:05
Pattern is not GC-safe.
Sven Panne
2012/11/20 14:39:13
See my comment above about FixedArray. The descrip
rossberg
2012/11/20 17:23:45
Obsolete.
rossberg
2012/11/20 17:23:45
That was actually a bug (leftover from earlier for
| |
| 823 modules_->set(index, *description); | |
| 649 } | 824 } |
| 650 | 825 |
| 651 | 826 |
| 652 int FullCodeGenerator::DeclareGlobalsFlags() { | 827 int FullCodeGenerator::DeclareGlobalsFlags() { |
| 653 ASSERT(DeclareGlobalsLanguageMode::is_valid(language_mode())); | 828 ASSERT(DeclareGlobalsLanguageMode::is_valid(language_mode())); |
| 654 return DeclareGlobalsEvalFlag::encode(is_eval()) | | 829 return DeclareGlobalsEvalFlag::encode(is_eval()) | |
| 655 DeclareGlobalsNativeFlag::encode(is_native()) | | 830 DeclareGlobalsNativeFlag::encode(is_native()) | |
| 656 DeclareGlobalsLanguageMode::encode(language_mode()); | 831 DeclareGlobalsLanguageMode::encode(language_mode()); |
| 657 } | 832 } |
| 658 | 833 |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 897 | 1072 |
| 898 void FullCodeGenerator::VisitBlock(Block* stmt) { | 1073 void FullCodeGenerator::VisitBlock(Block* stmt) { |
| 899 Comment cmnt(masm_, "[ Block"); | 1074 Comment cmnt(masm_, "[ Block"); |
| 900 NestedBlock nested_block(this, stmt); | 1075 NestedBlock nested_block(this, stmt); |
| 901 SetStatementPosition(stmt); | 1076 SetStatementPosition(stmt); |
| 902 | 1077 |
| 903 Scope* saved_scope = scope(); | 1078 Scope* saved_scope = scope(); |
| 904 // Push a block context when entering a block with block scoped variables. | 1079 // Push a block context when entering a block with block scoped variables. |
| 905 if (stmt->scope() != NULL) { | 1080 if (stmt->scope() != NULL) { |
| 906 scope_ = stmt->scope(); | 1081 scope_ = stmt->scope(); |
| 907 if (scope_->is_module_scope()) { | 1082 ASSERT(!scope_->is_module_scope()); |
| 908 // If this block is a module body, then we have already allocated and | 1083 { Comment cmnt(masm_, "[ Extend block context"); |
| 909 // initialized the declarations earlier. Just push the context. | 1084 Handle<ScopeInfo> scope_info = scope_->GetScopeInfo(); |
| 910 ASSERT(!scope_->interface()->Instance().is_null()); | 1085 int heap_slots = scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS; |
| 911 __ Push(scope_->interface()->Instance()); | 1086 __ Push(scope_info); |
| 912 __ CallRuntime(Runtime::kPushModuleContext, 1); | 1087 PushFunctionArgumentForContextAllocation(); |
| 913 StoreToFrameField( | 1088 if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) { |
| 914 StandardFrameConstants::kContextOffset, context_register()); | 1089 FastNewBlockContextStub stub(heap_slots); |
| 915 } else { | 1090 __ CallStub(&stub); |
| 916 { Comment cmnt(masm_, "[ Extend block context"); | 1091 } else { |
| 917 Handle<ScopeInfo> scope_info = scope_->GetScopeInfo(); | 1092 __ CallRuntime(Runtime::kPushBlockContext, 2); |
| 918 int heap_slots = | 1093 } |
| 919 scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS; | |
| 920 __ Push(scope_info); | |
| 921 PushFunctionArgumentForContextAllocation(); | |
| 922 if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) { | |
| 923 FastNewBlockContextStub stub(heap_slots); | |
| 924 __ CallStub(&stub); | |
| 925 } else { | |
| 926 __ CallRuntime(Runtime::kPushBlockContext, 2); | |
| 927 } | |
| 928 | 1094 |
| 929 // Replace the context stored in the frame. | 1095 // Replace the context stored in the frame. |
| 930 StoreToFrameField(StandardFrameConstants::kContextOffset, | 1096 StoreToFrameField(StandardFrameConstants::kContextOffset, |
| 931 context_register()); | 1097 context_register()); |
| 932 } | 1098 } |
| 933 { Comment cmnt(masm_, "[ Declarations"); | 1099 { Comment cmnt(masm_, "[ Declarations"); |
| 934 VisitDeclarations(scope_->declarations()); | 1100 VisitDeclarations(scope_->declarations()); |
| 935 } | |
| 936 } | 1101 } |
| 937 } | 1102 } |
| 1103 | |
| 938 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | 1104 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); |
| 939 VisitStatements(stmt->statements()); | 1105 VisitStatements(stmt->statements()); |
| 940 scope_ = saved_scope; | 1106 scope_ = saved_scope; |
| 941 __ bind(nested_block.break_label()); | 1107 __ bind(nested_block.break_label()); |
| 942 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1108 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 943 | 1109 |
| 944 // Pop block context if necessary. | 1110 // Pop block context if necessary. |
| 945 if (stmt->scope() != NULL) { | 1111 if (stmt->scope() != NULL) { |
| 946 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | 1112 LoadContextField(context_register(), Context::PREVIOUS_INDEX); |
| 947 // Update local stack frame context field. | 1113 // Update local stack frame context field. |
| 948 StoreToFrameField(StandardFrameConstants::kContextOffset, | 1114 StoreToFrameField(StandardFrameConstants::kContextOffset, |
| 949 context_register()); | 1115 context_register()); |
| 950 } | 1116 } |
| 951 } | 1117 } |
| 952 | 1118 |
| 953 | 1119 |
| 1120 void FullCodeGenerator::VisitModuleStatement(ModuleStatement* stmt) { | |
| 1121 Comment cmnt(masm_, "[ Module context"); | |
| 1122 | |
| 1123 __ push(Immediate(Smi::FromInt(stmt->proxy()->interface()->Index()))); | |
|
Michael Starzinger
2012/11/20 12:05:05
You will have a hard time porting this to other ar
rossberg
2012/11/20 17:23:45
Done.
| |
| 1124 __ push(Immediate(Smi::FromInt(0))); | |
| 1125 __ CallRuntime(Runtime::kPushModuleContext, 2); | |
| 1126 StoreToFrameField( | |
| 1127 StandardFrameConstants::kContextOffset, context_register()); | |
| 1128 | |
| 1129 Scope* saved_scope = scope_; | |
| 1130 scope_ = stmt->body()->scope(); | |
| 1131 VisitStatements(stmt->body()->statements()); | |
| 1132 scope_ = saved_scope; | |
| 1133 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | |
| 1134 // Update local stack frame context field. | |
| 1135 StoreToFrameField(StandardFrameConstants::kContextOffset, | |
| 1136 context_register()); | |
| 1137 } | |
| 1138 | |
| 1139 | |
| 954 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | 1140 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { |
| 955 Comment cmnt(masm_, "[ ExpressionStatement"); | 1141 Comment cmnt(masm_, "[ ExpressionStatement"); |
| 956 SetStatementPosition(stmt); | 1142 SetStatementPosition(stmt); |
| 957 VisitForEffect(stmt->expression()); | 1143 VisitForEffect(stmt->expression()); |
| 958 } | 1144 } |
| 959 | 1145 |
| 960 | 1146 |
| 961 void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { | 1147 void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { |
| 962 Comment cmnt(masm_, "[ EmptyStatement"); | 1148 Comment cmnt(masm_, "[ EmptyStatement"); |
| 963 SetStatementPosition(stmt); | 1149 SetStatementPosition(stmt); |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1421 } | 1607 } |
| 1422 | 1608 |
| 1423 return false; | 1609 return false; |
| 1424 } | 1610 } |
| 1425 | 1611 |
| 1426 | 1612 |
| 1427 #undef __ | 1613 #undef __ |
| 1428 | 1614 |
| 1429 | 1615 |
| 1430 } } // namespace v8::internal | 1616 } } // namespace v8::internal |
| OLD | NEW |