| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/ast.h" | 7 #include "src/ast.h" |
| 8 #include "src/ast-numbering.h" | 8 #include "src/ast-numbering.h" |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 void BreakableStatementChecker::VisitVariableDeclaration( | 34 void BreakableStatementChecker::VisitVariableDeclaration( |
| 35 VariableDeclaration* decl) { | 35 VariableDeclaration* decl) { |
| 36 } | 36 } |
| 37 | 37 |
| 38 | 38 |
| 39 void BreakableStatementChecker::VisitFunctionDeclaration( | 39 void BreakableStatementChecker::VisitFunctionDeclaration( |
| 40 FunctionDeclaration* decl) { | 40 FunctionDeclaration* decl) { |
| 41 } | 41 } |
| 42 | 42 |
| 43 | 43 |
| 44 void BreakableStatementChecker::VisitModuleDeclaration( | |
| 45 ModuleDeclaration* decl) { | |
| 46 } | |
| 47 | |
| 48 | |
| 49 void BreakableStatementChecker::VisitImportDeclaration( | 44 void BreakableStatementChecker::VisitImportDeclaration( |
| 50 ImportDeclaration* decl) { | 45 ImportDeclaration* decl) { |
| 51 } | 46 } |
| 52 | 47 |
| 53 | 48 |
| 54 void BreakableStatementChecker::VisitExportDeclaration( | 49 void BreakableStatementChecker::VisitExportDeclaration( |
| 55 ExportDeclaration* decl) { | 50 ExportDeclaration* decl) { |
| 56 } | 51 } |
| 57 | 52 |
| 58 | 53 |
| 59 void BreakableStatementChecker::VisitModuleLiteral(ModuleLiteral* module) { | |
| 60 } | |
| 61 | |
| 62 | |
| 63 void BreakableStatementChecker::VisitModulePath(ModulePath* module) { | |
| 64 } | |
| 65 | |
| 66 | |
| 67 void BreakableStatementChecker::VisitModuleUrl(ModuleUrl* module) { | |
| 68 } | |
| 69 | |
| 70 | |
| 71 void BreakableStatementChecker::VisitModuleStatement(ModuleStatement* stmt) { | |
| 72 } | |
| 73 | |
| 74 | |
| 75 void BreakableStatementChecker::VisitBlock(Block* stmt) { | 54 void BreakableStatementChecker::VisitBlock(Block* stmt) { |
| 76 } | 55 } |
| 77 | 56 |
| 78 | 57 |
| 79 void BreakableStatementChecker::VisitExpressionStatement( | 58 void BreakableStatementChecker::VisitExpressionStatement( |
| 80 ExpressionStatement* stmt) { | 59 ExpressionStatement* stmt) { |
| 81 // Check if expression is breakable. | 60 // Check if expression is breakable. |
| 82 Visit(stmt->expression()); | 61 Visit(stmt->expression()); |
| 83 } | 62 } |
| 84 | 63 |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 | 606 |
| 628 | 607 |
| 629 void FullCodeGenerator::DoTest(const TestContext* context) { | 608 void FullCodeGenerator::DoTest(const TestContext* context) { |
| 630 DoTest(context->condition(), | 609 DoTest(context->condition(), |
| 631 context->true_label(), | 610 context->true_label(), |
| 632 context->false_label(), | 611 context->false_label(), |
| 633 context->fall_through()); | 612 context->fall_through()); |
| 634 } | 613 } |
| 635 | 614 |
| 636 | 615 |
| 637 void FullCodeGenerator::AllocateModules(ZoneList<Declaration*>* declarations) { | |
| 638 DCHECK(scope_->is_script_scope()); | |
| 639 | |
| 640 for (int i = 0; i < declarations->length(); i++) { | |
| 641 ModuleDeclaration* declaration = declarations->at(i)->AsModuleDeclaration(); | |
| 642 if (declaration != NULL) { | |
| 643 ModuleLiteral* module = declaration->module()->AsModuleLiteral(); | |
| 644 if (module != NULL) { | |
| 645 Comment cmnt(masm_, "[ Link nested modules"); | |
| 646 Scope* scope = module->body()->scope(); | |
| 647 DCHECK(scope->module()->IsFrozen()); | |
| 648 | |
| 649 scope->module()->Allocate(scope->module_var()->index()); | |
| 650 | |
| 651 // Set up module context. | |
| 652 DCHECK(scope->module()->Index() >= 0); | |
| 653 __ Push(Smi::FromInt(scope->module()->Index())); | |
| 654 __ Push(scope->GetScopeInfo(isolate())); | |
| 655 __ CallRuntime(Runtime::kPushModuleContext, 2); | |
| 656 StoreToFrameField(StandardFrameConstants::kContextOffset, | |
| 657 context_register()); | |
| 658 | |
| 659 AllocateModules(scope->declarations()); | |
| 660 | |
| 661 // Pop module context. | |
| 662 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | |
| 663 // Update local stack frame context field. | |
| 664 StoreToFrameField(StandardFrameConstants::kContextOffset, | |
| 665 context_register()); | |
| 666 } | |
| 667 } | |
| 668 } | |
| 669 } | |
| 670 | |
| 671 | |
| 672 // Modules have their own local scope, represented by their own context. | |
| 673 // Module instance objects have an accessor for every export that forwards | |
| 674 // access to the respective slot from the module's context. (Exports that are | |
| 675 // modules themselves, however, are simple data properties.) | |
| 676 // | |
| 677 // All modules have a _hosting_ scope/context, which (currently) is the | |
| 678 // enclosing script scope. To deal with recursion, nested modules are hosted | |
| 679 // by the same scope as global ones. | |
| 680 // | |
| 681 // For every (global or nested) module literal, the hosting context has an | |
| 682 // internal slot that points directly to the respective module context. This | |
| 683 // enables quick access to (statically resolved) module members by 2-dimensional | |
| 684 // access through the hosting context. For example, | |
| 685 // | |
| 686 // module A { | |
| 687 // let x; | |
| 688 // module B { let y; } | |
| 689 // } | |
| 690 // module C { let z; } | |
| 691 // | |
| 692 // allocates contexts as follows: | |
| 693 // | |
| 694 // [header| .A | .B | .C | A | C ] (global) | |
| 695 // | | | | |
| 696 // | | +-- [header| z ] (module) | |
| 697 // | | | |
| 698 // | +------- [header| y ] (module) | |
| 699 // | | |
| 700 // +------------ [header| x | B ] (module) | |
| 701 // | |
| 702 // Here, .A, .B, .C are the internal slots pointing to the hosted module | |
| 703 // contexts, whereas A, B, C hold the actual instance objects (note that every | |
| 704 // module context also points to the respective instance object through its | |
| 705 // extension slot in the header). | |
| 706 // | |
| 707 // To deal with arbitrary recursion and aliases between modules, | |
| 708 // they are created and initialized in several stages. Each stage applies to | |
| 709 // all modules in the hosting script scope, including nested ones. | |
| 710 // | |
| 711 // 1. Allocate: for each module _literal_, allocate the module contexts and | |
| 712 // respective instance object and wire them up. This happens in the | |
| 713 // PushModuleContext runtime function, as generated by AllocateModules | |
| 714 // (invoked by VisitDeclarations in the hosting scope). | |
| 715 // | |
| 716 // 2. Bind: for each module _declaration_ (i.e. literals as well as aliases), | |
| 717 // assign the respective instance object to respective local variables. This | |
| 718 // happens in VisitModuleDeclaration, and uses the instance objects created | |
| 719 // in the previous stage. | |
| 720 // For each module _literal_, this phase also constructs a module descriptor | |
| 721 // for the next stage. This happens in VisitModuleLiteral. | |
| 722 // | |
| 723 // 3. Populate: invoke the DeclareModules runtime function to populate each | |
| 724 // _instance_ object with accessors for it exports. This is generated by | |
| 725 // DeclareModules (invoked by VisitDeclarations in the hosting scope again), | |
| 726 // and uses the descriptors generated in the previous stage. | |
| 727 // | |
| 728 // 4. Initialize: execute the module bodies (and other code) in sequence. This | |
| 729 // happens by the separate statements generated for module bodies. To reenter | |
| 730 // the module scopes properly, the parser inserted ModuleStatements. | |
| 731 | |
| 732 void FullCodeGenerator::VisitDeclarations( | 616 void FullCodeGenerator::VisitDeclarations( |
| 733 ZoneList<Declaration*>* declarations) { | 617 ZoneList<Declaration*>* declarations) { |
| 734 Handle<FixedArray> saved_modules = modules_; | |
| 735 int saved_module_index = module_index_; | |
| 736 ZoneList<Handle<Object> >* saved_globals = globals_; | 618 ZoneList<Handle<Object> >* saved_globals = globals_; |
| 737 ZoneList<Handle<Object> > inner_globals(10, zone()); | 619 ZoneList<Handle<Object> > inner_globals(10, zone()); |
| 738 globals_ = &inner_globals; | 620 globals_ = &inner_globals; |
| 739 | 621 |
| 740 if (scope_->num_modules() != 0) { | |
| 741 // This is a scope hosting modules. Allocate a descriptor array to pass | |
| 742 // to the runtime for initialization. | |
| 743 Comment cmnt(masm_, "[ Allocate modules"); | |
| 744 DCHECK(scope_->is_script_scope()); | |
| 745 modules_ = | |
| 746 isolate()->factory()->NewFixedArray(scope_->num_modules(), TENURED); | |
| 747 module_index_ = 0; | |
| 748 | |
| 749 // Generate code for allocating all modules, including nested ones. | |
| 750 // The allocated contexts are stored in internal variables in this scope. | |
| 751 AllocateModules(declarations); | |
| 752 } | |
| 753 | |
| 754 AstVisitor::VisitDeclarations(declarations); | 622 AstVisitor::VisitDeclarations(declarations); |
| 755 | 623 |
| 756 if (scope_->num_modules() != 0) { | |
| 757 // TODO(ES6): This step, which creates module instance objects, | |
| 758 // can probably be delayed until an "import *" declaration | |
| 759 // reifies a module instance. Until imports are implemented, | |
| 760 // we skip it altogether. | |
| 761 // | |
| 762 // Initialize modules from descriptor array. | |
| 763 // DCHECK(module_index_ == modules_->length()); | |
| 764 // DeclareModules(modules_); | |
| 765 modules_ = saved_modules; | |
| 766 module_index_ = saved_module_index; | |
| 767 } | |
| 768 | |
| 769 if (!globals_->is_empty()) { | 624 if (!globals_->is_empty()) { |
| 770 // Invoke the platform-dependent code generator to do the actual | 625 // Invoke the platform-dependent code generator to do the actual |
| 771 // declaration of the global functions and variables. | 626 // declaration of the global functions and variables. |
| 772 Handle<FixedArray> array = | 627 Handle<FixedArray> array = |
| 773 isolate()->factory()->NewFixedArray(globals_->length(), TENURED); | 628 isolate()->factory()->NewFixedArray(globals_->length(), TENURED); |
| 774 for (int i = 0; i < globals_->length(); ++i) | 629 for (int i = 0; i < globals_->length(); ++i) |
| 775 array->set(i, *globals_->at(i)); | 630 array->set(i, *globals_->at(i)); |
| 776 DeclareGlobals(array); | 631 DeclareGlobals(array); |
| 777 } | 632 } |
| 778 | 633 |
| 779 globals_ = saved_globals; | 634 globals_ = saved_globals; |
| 780 } | 635 } |
| 781 | 636 |
| 782 | 637 |
| 783 void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) { | |
| 784 Block* block = module->body(); | |
| 785 Scope* saved_scope = scope(); | |
| 786 scope_ = block->scope(); | |
| 787 ModuleDescriptor* descriptor = scope_->module(); | |
| 788 | |
| 789 Comment cmnt(masm_, "[ ModuleLiteral"); | |
| 790 SetStatementPosition(block); | |
| 791 | |
| 792 DCHECK(!modules_.is_null()); | |
| 793 DCHECK(module_index_ < modules_->length()); | |
| 794 int index = module_index_++; | |
| 795 | |
| 796 // Set up module context. | |
| 797 DCHECK(descriptor->Index() >= 0); | |
| 798 __ Push(Smi::FromInt(descriptor->Index())); | |
| 799 __ Push(Smi::FromInt(0)); | |
| 800 __ CallRuntime(Runtime::kPushModuleContext, 2); | |
| 801 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); | |
| 802 | |
| 803 { | |
| 804 Comment cmnt(masm_, "[ Declarations"); | |
| 805 VisitDeclarations(scope_->declarations()); | |
| 806 } | |
| 807 | |
| 808 // Populate the module description. | |
| 809 Handle<ModuleInfo> description = | |
| 810 ModuleInfo::Create(isolate(), descriptor, scope_); | |
| 811 modules_->set(index, *description); | |
| 812 | |
| 813 scope_ = saved_scope; | |
| 814 // Pop module context. | |
| 815 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | |
| 816 // Update local stack frame context field. | |
| 817 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); | |
| 818 } | |
| 819 | |
| 820 | |
| 821 // TODO(adamk): Delete ModulePath. | |
| 822 void FullCodeGenerator::VisitModulePath(ModulePath* module) { | |
| 823 } | |
| 824 | |
| 825 | |
| 826 // TODO(adamk): Delete ModuleUrl. | |
| 827 void FullCodeGenerator::VisitModuleUrl(ModuleUrl* module) { | |
| 828 } | |
| 829 | |
| 830 | |
| 831 int FullCodeGenerator::DeclareGlobalsFlags() { | 638 int FullCodeGenerator::DeclareGlobalsFlags() { |
| 832 DCHECK(DeclareGlobalsLanguageMode::is_valid(language_mode())); | 639 DCHECK(DeclareGlobalsLanguageMode::is_valid(language_mode())); |
| 833 return DeclareGlobalsEvalFlag::encode(is_eval()) | | 640 return DeclareGlobalsEvalFlag::encode(is_eval()) | |
| 834 DeclareGlobalsNativeFlag::encode(is_native()) | | 641 DeclareGlobalsNativeFlag::encode(is_native()) | |
| 835 DeclareGlobalsLanguageMode::encode(language_mode()); | 642 DeclareGlobalsLanguageMode::encode(language_mode()); |
| 836 } | 643 } |
| 837 | 644 |
| 838 | 645 |
| 839 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { | 646 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { |
| 840 CodeGenerator::RecordPositions(masm_, fun->start_position()); | 647 CodeGenerator::RecordPositions(masm_, fun->start_position()); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 | 861 |
| 1055 { | 862 { |
| 1056 EnterBlockScopeIfNeeded block_scope_state( | 863 EnterBlockScopeIfNeeded block_scope_state( |
| 1057 this, stmt->scope(), stmt->EntryId(), stmt->DeclsId(), stmt->ExitId()); | 864 this, stmt->scope(), stmt->EntryId(), stmt->DeclsId(), stmt->ExitId()); |
| 1058 VisitStatements(stmt->statements()); | 865 VisitStatements(stmt->statements()); |
| 1059 __ bind(nested_block.break_label()); | 866 __ bind(nested_block.break_label()); |
| 1060 } | 867 } |
| 1061 } | 868 } |
| 1062 | 869 |
| 1063 | 870 |
| 1064 void FullCodeGenerator::VisitModuleStatement(ModuleStatement* stmt) { | |
| 1065 Comment cmnt(masm_, "[ Module context"); | |
| 1066 | |
| 1067 DCHECK(stmt->body()->scope()->is_module_scope()); | |
| 1068 | |
| 1069 __ Push(Smi::FromInt(stmt->body()->scope()->module()->Index())); | |
| 1070 __ Push(Smi::FromInt(0)); | |
| 1071 __ CallRuntime(Runtime::kPushModuleContext, 2); | |
| 1072 StoreToFrameField( | |
| 1073 StandardFrameConstants::kContextOffset, context_register()); | |
| 1074 | |
| 1075 Scope* saved_scope = scope_; | |
| 1076 scope_ = stmt->body()->scope(); | |
| 1077 VisitStatements(stmt->body()->statements()); | |
| 1078 scope_ = saved_scope; | |
| 1079 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | |
| 1080 // Update local stack frame context field. | |
| 1081 StoreToFrameField(StandardFrameConstants::kContextOffset, | |
| 1082 context_register()); | |
| 1083 } | |
| 1084 | |
| 1085 | |
| 1086 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | 871 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { |
| 1087 Comment cmnt(masm_, "[ ExpressionStatement"); | 872 Comment cmnt(masm_, "[ ExpressionStatement"); |
| 1088 SetStatementPosition(stmt); | 873 SetStatementPosition(stmt); |
| 1089 VisitForEffect(stmt->expression()); | 874 VisitForEffect(stmt->expression()); |
| 1090 } | 875 } |
| 1091 | 876 |
| 1092 | 877 |
| 1093 void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { | 878 void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { |
| 1094 Comment cmnt(masm_, "[ EmptyStatement"); | 879 Comment cmnt(masm_, "[ EmptyStatement"); |
| 1095 SetStatementPosition(stmt); | 880 SetStatementPosition(stmt); |
| (...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1857 } | 1642 } |
| 1858 codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS); | 1643 codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS); |
| 1859 codegen_->scope_ = saved_scope_; | 1644 codegen_->scope_ = saved_scope_; |
| 1860 } | 1645 } |
| 1861 | 1646 |
| 1862 | 1647 |
| 1863 #undef __ | 1648 #undef __ |
| 1864 | 1649 |
| 1865 | 1650 |
| 1866 } } // namespace v8::internal | 1651 } } // namespace v8::internal |
| OLD | NEW |