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 |