| 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 } | 101 } |
| 102 | 102 |
| 103 | 103 |
| 104 // ---------------------------------------------------------------------------- | 104 // ---------------------------------------------------------------------------- |
| 105 // Implementation of Scope | 105 // Implementation of Scope |
| 106 | 106 |
| 107 Scope::Scope(Scope* outer_scope, ScopeType type, Zone* zone) | 107 Scope::Scope(Scope* outer_scope, ScopeType type, Zone* zone) |
| 108 : isolate_(Isolate::Current()), | 108 : isolate_(Isolate::Current()), |
| 109 inner_scopes_(4, zone), | 109 inner_scopes_(4, zone), |
| 110 variables_(zone), | 110 variables_(zone), |
| 111 internals_(4, zone), |
| 111 temps_(4, zone), | 112 temps_(4, zone), |
| 112 params_(4, zone), | 113 params_(4, zone), |
| 113 unresolved_(16, zone), | 114 unresolved_(16, zone), |
| 114 decls_(4, zone), | 115 decls_(4, zone), |
| 115 interface_(FLAG_harmony_modules && | 116 interface_(FLAG_harmony_modules && |
| 116 (type == MODULE_SCOPE || type == GLOBAL_SCOPE) | 117 (type == MODULE_SCOPE || type == GLOBAL_SCOPE) |
| 117 ? Interface::NewModule(zone) : NULL), | 118 ? Interface::NewModule(zone) : NULL), |
| 118 already_resolved_(false), | 119 already_resolved_(false), |
| 119 zone_(zone) { | 120 zone_(zone) { |
| 120 SetDefaults(type, outer_scope, Handle<ScopeInfo>::null()); | 121 SetDefaults(type, outer_scope, Handle<ScopeInfo>::null()); |
| 121 // The outermost scope must be a global scope. | 122 // The outermost scope must be a global scope. |
| 122 ASSERT(type == GLOBAL_SCOPE || outer_scope != NULL); | 123 ASSERT(type == GLOBAL_SCOPE || outer_scope != NULL); |
| 123 ASSERT(!HasIllegalRedeclaration()); | 124 ASSERT(!HasIllegalRedeclaration()); |
| 124 } | 125 } |
| 125 | 126 |
| 126 | 127 |
| 127 Scope::Scope(Scope* inner_scope, | 128 Scope::Scope(Scope* inner_scope, |
| 128 ScopeType type, | 129 ScopeType type, |
| 129 Handle<ScopeInfo> scope_info, | 130 Handle<ScopeInfo> scope_info, |
| 130 Zone* zone) | 131 Zone* zone) |
| 131 : isolate_(Isolate::Current()), | 132 : isolate_(Isolate::Current()), |
| 132 inner_scopes_(4, zone), | 133 inner_scopes_(4, zone), |
| 133 variables_(zone), | 134 variables_(zone), |
| 135 internals_(4, zone), |
| 134 temps_(4, zone), | 136 temps_(4, zone), |
| 135 params_(4, zone), | 137 params_(4, zone), |
| 136 unresolved_(16, zone), | 138 unresolved_(16, zone), |
| 137 decls_(4, zone), | 139 decls_(4, zone), |
| 138 interface_(NULL), | 140 interface_(NULL), |
| 139 already_resolved_(true), | 141 already_resolved_(true), |
| 140 zone_(zone) { | 142 zone_(zone) { |
| 141 SetDefaults(type, NULL, scope_info); | 143 SetDefaults(type, NULL, scope_info); |
| 142 if (!scope_info.is_null()) { | 144 if (!scope_info.is_null()) { |
| 143 num_heap_slots_ = scope_info_->ContextLength(); | 145 num_heap_slots_ = scope_info_->ContextLength(); |
| 144 } | 146 } |
| 145 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 147 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
| 146 num_heap_slots_ = Max(num_heap_slots_, | 148 num_heap_slots_ = Max(num_heap_slots_, |
| 147 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 149 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
| 148 AddInnerScope(inner_scope); | 150 AddInnerScope(inner_scope); |
| 149 } | 151 } |
| 150 | 152 |
| 151 | 153 |
| 152 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name, Zone* zone) | 154 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name, Zone* zone) |
| 153 : isolate_(Isolate::Current()), | 155 : isolate_(Isolate::Current()), |
| 154 inner_scopes_(1, zone), | 156 inner_scopes_(1, zone), |
| 155 variables_(zone), | 157 variables_(zone), |
| 158 internals_(0, zone), |
| 156 temps_(0, zone), | 159 temps_(0, zone), |
| 157 params_(0, zone), | 160 params_(0, zone), |
| 158 unresolved_(0, zone), | 161 unresolved_(0, zone), |
| 159 decls_(0, zone), | 162 decls_(0, zone), |
| 160 interface_(NULL), | 163 interface_(NULL), |
| 161 already_resolved_(true), | 164 already_resolved_(true), |
| 162 zone_(zone) { | 165 zone_(zone) { |
| 163 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); | 166 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); |
| 164 AddInnerScope(inner_scope); | 167 AddInnerScope(inner_scope); |
| 165 ++num_var_or_const_; | 168 ++num_var_or_const_; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 190 scope_calls_eval_ = false; | 193 scope_calls_eval_ = false; |
| 191 // Inherit the strict mode from the parent scope. | 194 // Inherit the strict mode from the parent scope. |
| 192 language_mode_ = (outer_scope != NULL) | 195 language_mode_ = (outer_scope != NULL) |
| 193 ? outer_scope->language_mode_ : CLASSIC_MODE; | 196 ? outer_scope->language_mode_ : CLASSIC_MODE; |
| 194 outer_scope_calls_non_strict_eval_ = false; | 197 outer_scope_calls_non_strict_eval_ = false; |
| 195 inner_scope_calls_eval_ = false; | 198 inner_scope_calls_eval_ = false; |
| 196 force_eager_compilation_ = false; | 199 force_eager_compilation_ = false; |
| 197 num_var_or_const_ = 0; | 200 num_var_or_const_ = 0; |
| 198 num_stack_slots_ = 0; | 201 num_stack_slots_ = 0; |
| 199 num_heap_slots_ = 0; | 202 num_heap_slots_ = 0; |
| 203 num_modules_ = 0; |
| 204 module_var_ = NULL, |
| 200 scope_info_ = scope_info; | 205 scope_info_ = scope_info; |
| 201 start_position_ = RelocInfo::kNoPosition; | 206 start_position_ = RelocInfo::kNoPosition; |
| 202 end_position_ = RelocInfo::kNoPosition; | 207 end_position_ = RelocInfo::kNoPosition; |
| 203 if (!scope_info.is_null()) { | 208 if (!scope_info.is_null()) { |
| 204 scope_calls_eval_ = scope_info->CallsEval(); | 209 scope_calls_eval_ = scope_info->CallsEval(); |
| 205 language_mode_ = scope_info->language_mode(); | 210 language_mode_ = scope_info->language_mode(); |
| 206 } | 211 } |
| 207 } | 212 } |
| 208 | 213 |
| 209 | 214 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 VAR, | 373 VAR, |
| 369 true, | 374 true, |
| 370 Variable::ARGUMENTS, | 375 Variable::ARGUMENTS, |
| 371 kCreatedInitialized); | 376 kCreatedInitialized); |
| 372 } | 377 } |
| 373 } | 378 } |
| 374 | 379 |
| 375 | 380 |
| 376 Scope* Scope::FinalizeBlockScope() { | 381 Scope* Scope::FinalizeBlockScope() { |
| 377 ASSERT(is_block_scope()); | 382 ASSERT(is_block_scope()); |
| 383 ASSERT(internals_.is_empty()); |
| 378 ASSERT(temps_.is_empty()); | 384 ASSERT(temps_.is_empty()); |
| 379 ASSERT(params_.is_empty()); | 385 ASSERT(params_.is_empty()); |
| 380 | 386 |
| 381 if (num_var_or_const() > 0) return this; | 387 if (num_var_or_const() > 0) return this; |
| 382 | 388 |
| 383 // Remove this scope from outer scope. | 389 // Remove this scope from outer scope. |
| 384 for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) { | 390 for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) { |
| 385 if (outer_scope_->inner_scopes_[i] == this) { | 391 if (outer_scope_->inner_scopes_[i] == this) { |
| 386 outer_scope_->inner_scopes_.Remove(i); | 392 outer_scope_->inner_scopes_.Remove(i); |
| 387 break; | 393 break; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 // was just added before, so we search backwards. | 514 // was just added before, so we search backwards. |
| 509 for (int i = unresolved_.length(); i-- > 0;) { | 515 for (int i = unresolved_.length(); i-- > 0;) { |
| 510 if (unresolved_[i] == var) { | 516 if (unresolved_[i] == var) { |
| 511 unresolved_.Remove(i); | 517 unresolved_.Remove(i); |
| 512 return; | 518 return; |
| 513 } | 519 } |
| 514 } | 520 } |
| 515 } | 521 } |
| 516 | 522 |
| 517 | 523 |
| 524 Variable* Scope::NewInternal(Handle<String> name) { |
| 525 ASSERT(!already_resolved()); |
| 526 Variable* var = new(zone()) Variable(this, |
| 527 name, |
| 528 INTERNAL, |
| 529 false, |
| 530 Variable::NORMAL, |
| 531 kCreatedInitialized); |
| 532 internals_.Add(var, zone()); |
| 533 return var; |
| 534 } |
| 535 |
| 536 |
| 518 Variable* Scope::NewTemporary(Handle<String> name) { | 537 Variable* Scope::NewTemporary(Handle<String> name) { |
| 519 ASSERT(!already_resolved()); | 538 ASSERT(!already_resolved()); |
| 520 Variable* var = new(zone()) Variable(this, | 539 Variable* var = new(zone()) Variable(this, |
| 521 name, | 540 name, |
| 522 TEMPORARY, | 541 TEMPORARY, |
| 523 true, | 542 true, |
| 524 Variable::NORMAL, | 543 Variable::NORMAL, |
| 525 kCreatedInitialized); | 544 kCreatedInitialized); |
| 526 temps_.Add(var, zone()); | 545 temps_.Add(var, zone()); |
| 527 return var; | 546 return var; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 Variable* var_; | 627 Variable* var_; |
| 609 int order_; | 628 int order_; |
| 610 }; | 629 }; |
| 611 | 630 |
| 612 | 631 |
| 613 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, | 632 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, |
| 614 ZoneList<Variable*>* context_locals) { | 633 ZoneList<Variable*>* context_locals) { |
| 615 ASSERT(stack_locals != NULL); | 634 ASSERT(stack_locals != NULL); |
| 616 ASSERT(context_locals != NULL); | 635 ASSERT(context_locals != NULL); |
| 617 | 636 |
| 637 // Collect internals which are always allocated on the heap. |
| 638 for (int i = 0; i < internals_.length(); i++) { |
| 639 Variable* var = internals_[i]; |
| 640 if (var->is_used()) { |
| 641 ASSERT(var->IsContextSlot()); |
| 642 context_locals->Add(var, zone()); |
| 643 } |
| 644 } |
| 645 |
| 618 // Collect temporaries which are always allocated on the stack. | 646 // Collect temporaries which are always allocated on the stack. |
| 619 for (int i = 0; i < temps_.length(); i++) { | 647 for (int i = 0; i < temps_.length(); i++) { |
| 620 Variable* var = temps_[i]; | 648 Variable* var = temps_[i]; |
| 621 if (var->is_used()) { | 649 if (var->is_used()) { |
| 622 ASSERT(var->IsStackLocal()); | 650 ASSERT(var->IsStackLocal()); |
| 623 stack_locals->Add(var, zone()); | 651 stack_locals->Add(var, zone()); |
| 624 } | 652 } |
| 625 } | 653 } |
| 626 | 654 |
| 655 // Collect declared local variables. |
| 627 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 656 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
| 628 | |
| 629 // Collect declared local variables. | |
| 630 for (VariableMap::Entry* p = variables_.Start(); | 657 for (VariableMap::Entry* p = variables_.Start(); |
| 631 p != NULL; | 658 p != NULL; |
| 632 p = variables_.Next(p)) { | 659 p = variables_.Next(p)) { |
| 633 Variable* var = reinterpret_cast<Variable*>(p->value); | 660 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 634 if (var->is_used()) { | 661 if (var->is_used()) { |
| 635 vars.Add(VarAndOrder(var, p->order), zone()); | 662 vars.Add(VarAndOrder(var, p->order), zone()); |
| 636 } | 663 } |
| 637 } | 664 } |
| 638 vars.Sort(VarAndOrder::Compare); | 665 vars.Sort(VarAndOrder::Compare); |
| 639 int var_count = vars.length(); | 666 int var_count = vars.length(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 652 AstNodeFactory<AstNullVisitor>* factory) { | 679 AstNodeFactory<AstNullVisitor>* factory) { |
| 653 // 1) Propagate scope information. | 680 // 1) Propagate scope information. |
| 654 bool outer_scope_calls_non_strict_eval = false; | 681 bool outer_scope_calls_non_strict_eval = false; |
| 655 if (outer_scope_ != NULL) { | 682 if (outer_scope_ != NULL) { |
| 656 outer_scope_calls_non_strict_eval = | 683 outer_scope_calls_non_strict_eval = |
| 657 outer_scope_->outer_scope_calls_non_strict_eval() | | 684 outer_scope_->outer_scope_calls_non_strict_eval() | |
| 658 outer_scope_->calls_non_strict_eval(); | 685 outer_scope_->calls_non_strict_eval(); |
| 659 } | 686 } |
| 660 PropagateScopeInfo(outer_scope_calls_non_strict_eval); | 687 PropagateScopeInfo(outer_scope_calls_non_strict_eval); |
| 661 | 688 |
| 662 // 2) Resolve variables. | 689 // 2) Allocate module instances. |
| 690 if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) { |
| 691 ASSERT(num_modules_ == 0); |
| 692 AllocateModulesRecursively(this); |
| 693 } |
| 694 |
| 695 // 3) Resolve variables. |
| 663 if (!ResolveVariablesRecursively(info, factory)) return false; | 696 if (!ResolveVariablesRecursively(info, factory)) return false; |
| 664 | 697 |
| 665 // 3) Allocate variables. | 698 // 4) Allocate variables. |
| 666 AllocateVariablesRecursively(); | 699 AllocateVariablesRecursively(); |
| 667 | 700 |
| 668 // 4) Allocate and link module instance objects. | |
| 669 if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) { | |
| 670 AllocateModules(info); | |
| 671 LinkModules(info); | |
| 672 } | |
| 673 | |
| 674 return true; | 701 return true; |
| 675 } | 702 } |
| 676 | 703 |
| 677 | 704 |
| 678 bool Scope::HasTrivialContext() const { | 705 bool Scope::HasTrivialContext() const { |
| 679 // A function scope has a trivial context if it always is the global | 706 // A function scope has a trivial context if it always is the global |
| 680 // context. We iteratively scan out the context chain to see if | 707 // context. We iteratively scan out the context chain to see if |
| 681 // there is anything that makes this scope non-trivial; otherwise we | 708 // there is anything that makes this scope non-trivial; otherwise we |
| 682 // return true. | 709 // return true. |
| 683 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { | 710 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 int Scope::ContextChainLength(Scope* scope) { | 762 int Scope::ContextChainLength(Scope* scope) { |
| 736 int n = 0; | 763 int n = 0; |
| 737 for (Scope* s = this; s != scope; s = s->outer_scope_) { | 764 for (Scope* s = this; s != scope; s = s->outer_scope_) { |
| 738 ASSERT(s != NULL); // scope must be in the scope chain | 765 ASSERT(s != NULL); // scope must be in the scope chain |
| 739 if (s->num_heap_slots() > 0) n++; | 766 if (s->num_heap_slots() > 0) n++; |
| 740 } | 767 } |
| 741 return n; | 768 return n; |
| 742 } | 769 } |
| 743 | 770 |
| 744 | 771 |
| 772 Scope* Scope::GlobalScope() { |
| 773 Scope* scope = this; |
| 774 while (!scope->is_global_scope()) { |
| 775 scope = scope->outer_scope(); |
| 776 } |
| 777 return scope; |
| 778 } |
| 779 |
| 780 |
| 745 Scope* Scope::DeclarationScope() { | 781 Scope* Scope::DeclarationScope() { |
| 746 Scope* scope = this; | 782 Scope* scope = this; |
| 747 while (!scope->is_declaration_scope()) { | 783 while (!scope->is_declaration_scope()) { |
| 748 scope = scope->outer_scope(); | 784 scope = scope->outer_scope(); |
| 749 } | 785 } |
| 750 return scope; | 786 return scope; |
| 751 } | 787 } |
| 752 | 788 |
| 753 | 789 |
| 754 Handle<ScopeInfo> Scope::GetScopeInfo() { | 790 Handle<ScopeInfo> Scope::GetScopeInfo() { |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 Indent(n1, "// function var\n"); | 944 Indent(n1, "// function var\n"); |
| 909 if (function_ != NULL) { | 945 if (function_ != NULL) { |
| 910 PrintVar(n1, function_->proxy()->var()); | 946 PrintVar(n1, function_->proxy()->var()); |
| 911 } | 947 } |
| 912 | 948 |
| 913 Indent(n1, "// temporary vars\n"); | 949 Indent(n1, "// temporary vars\n"); |
| 914 for (int i = 0; i < temps_.length(); i++) { | 950 for (int i = 0; i < temps_.length(); i++) { |
| 915 PrintVar(n1, temps_[i]); | 951 PrintVar(n1, temps_[i]); |
| 916 } | 952 } |
| 917 | 953 |
| 954 Indent(n1, "// internal vars\n"); |
| 955 for (int i = 0; i < internals_.length(); i++) { |
| 956 PrintVar(n1, internals_[i]); |
| 957 } |
| 958 |
| 918 Indent(n1, "// local vars\n"); | 959 Indent(n1, "// local vars\n"); |
| 919 PrintMap(n1, &variables_); | 960 PrintMap(n1, &variables_); |
| 920 | 961 |
| 921 Indent(n1, "// dynamic vars\n"); | 962 Indent(n1, "// dynamic vars\n"); |
| 922 if (dynamics_ != NULL) { | 963 if (dynamics_ != NULL) { |
| 923 PrintMap(n1, dynamics_->GetMap(DYNAMIC)); | 964 PrintMap(n1, dynamics_->GetMap(DYNAMIC)); |
| 924 PrintMap(n1, dynamics_->GetMap(DYNAMIC_LOCAL)); | 965 PrintMap(n1, dynamics_->GetMap(DYNAMIC_LOCAL)); |
| 925 PrintMap(n1, dynamics_->GetMap(DYNAMIC_GLOBAL)); | 966 PrintMap(n1, dynamics_->GetMap(DYNAMIC_GLOBAL)); |
| 926 } | 967 } |
| 927 | 968 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1058 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); | 1099 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); |
| 1059 break; | 1100 break; |
| 1060 | 1101 |
| 1061 case DYNAMIC_LOOKUP: | 1102 case DYNAMIC_LOOKUP: |
| 1062 // The variable could not be resolved statically. | 1103 // The variable could not be resolved statically. |
| 1063 var = NonLocal(proxy->name(), DYNAMIC); | 1104 var = NonLocal(proxy->name(), DYNAMIC); |
| 1064 break; | 1105 break; |
| 1065 } | 1106 } |
| 1066 | 1107 |
| 1067 ASSERT(var != NULL); | 1108 ASSERT(var != NULL); |
| 1068 proxy->BindTo(var); | |
| 1069 | 1109 |
| 1070 if (FLAG_harmony_modules) { | 1110 if (FLAG_harmony_modules) { |
| 1071 bool ok; | 1111 bool ok; |
| 1072 #ifdef DEBUG | 1112 #ifdef DEBUG |
| 1073 if (FLAG_print_interface_details) | 1113 if (FLAG_print_interface_details) |
| 1074 PrintF("# Resolve %s:\n", var->name()->ToAsciiArray()); | 1114 PrintF("# Resolve %s:\n", var->name()->ToAsciiArray()); |
| 1075 #endif | 1115 #endif |
| 1076 proxy->interface()->Unify(var->interface(), zone(), &ok); | 1116 proxy->interface()->Unify(var->interface(), zone(), &ok); |
| 1077 if (!ok) { | 1117 if (!ok) { |
| 1078 #ifdef DEBUG | 1118 #ifdef DEBUG |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1094 Factory* factory = isolate->factory(); | 1134 Factory* factory = isolate->factory(); |
| 1095 Handle<JSArray> array = factory->NewJSArray(1); | 1135 Handle<JSArray> array = factory->NewJSArray(1); |
| 1096 USE(JSObject::SetElement(array, 0, var->name(), NONE, kStrictMode)); | 1136 USE(JSObject::SetElement(array, 0, var->name(), NONE, kStrictMode)); |
| 1097 Handle<Object> result = | 1137 Handle<Object> result = |
| 1098 factory->NewSyntaxError("module_type_error", array); | 1138 factory->NewSyntaxError("module_type_error", array); |
| 1099 isolate->Throw(*result, &location); | 1139 isolate->Throw(*result, &location); |
| 1100 return false; | 1140 return false; |
| 1101 } | 1141 } |
| 1102 } | 1142 } |
| 1103 | 1143 |
| 1144 proxy->BindTo(var); |
| 1145 |
| 1104 return true; | 1146 return true; |
| 1105 } | 1147 } |
| 1106 | 1148 |
| 1107 | 1149 |
| 1108 bool Scope::ResolveVariablesRecursively( | 1150 bool Scope::ResolveVariablesRecursively( |
| 1109 CompilationInfo* info, | 1151 CompilationInfo* info, |
| 1110 AstNodeFactory<AstNullVisitor>* factory) { | 1152 AstNodeFactory<AstNullVisitor>* factory) { |
| 1111 ASSERT(info->global_scope()->is_global_scope()); | 1153 ASSERT(info->global_scope()->is_global_scope()); |
| 1112 | 1154 |
| 1113 // Resolve unresolved variables for this scope. | 1155 // Resolve unresolved variables for this scope. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 | 1210 |
| 1169 bool Scope::MustAllocateInContext(Variable* var) { | 1211 bool Scope::MustAllocateInContext(Variable* var) { |
| 1170 // If var is accessed from an inner scope, or if there is a possibility | 1212 // If var is accessed from an inner scope, or if there is a possibility |
| 1171 // that it might be accessed from the current or an inner scope (through | 1213 // that it might be accessed from the current or an inner scope (through |
| 1172 // an eval() call or a runtime with lookup), it must be allocated in the | 1214 // an eval() call or a runtime with lookup), it must be allocated in the |
| 1173 // context. | 1215 // context. |
| 1174 // | 1216 // |
| 1175 // Exceptions: temporary variables are never allocated in a context; | 1217 // Exceptions: temporary variables are never allocated in a context; |
| 1176 // catch-bound variables are always allocated in a context. | 1218 // catch-bound variables are always allocated in a context. |
| 1177 if (var->mode() == TEMPORARY) return false; | 1219 if (var->mode() == TEMPORARY) return false; |
| 1220 if (var->mode() == INTERNAL) return true; |
| 1178 if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; | 1221 if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; |
| 1179 if (is_global_scope() && IsLexicalVariableMode(var->mode())) return true; | 1222 if (is_global_scope() && IsLexicalVariableMode(var->mode())) return true; |
| 1180 return var->has_forced_context_allocation() || | 1223 return var->has_forced_context_allocation() || |
| 1181 scope_calls_eval_ || | 1224 scope_calls_eval_ || |
| 1182 inner_scope_calls_eval_ || | 1225 inner_scope_calls_eval_ || |
| 1183 scope_contains_with_; | 1226 scope_contains_with_; |
| 1184 } | 1227 } |
| 1185 | 1228 |
| 1186 | 1229 |
| 1187 bool Scope::HasArgumentsParameter() { | 1230 bool Scope::HasArgumentsParameter() { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 } | 1317 } |
| 1275 } | 1318 } |
| 1276 | 1319 |
| 1277 | 1320 |
| 1278 void Scope::AllocateNonParameterLocals() { | 1321 void Scope::AllocateNonParameterLocals() { |
| 1279 // All variables that have no rewrite yet are non-parameter locals. | 1322 // All variables that have no rewrite yet are non-parameter locals. |
| 1280 for (int i = 0; i < temps_.length(); i++) { | 1323 for (int i = 0; i < temps_.length(); i++) { |
| 1281 AllocateNonParameterLocal(temps_[i]); | 1324 AllocateNonParameterLocal(temps_[i]); |
| 1282 } | 1325 } |
| 1283 | 1326 |
| 1327 for (int i = 0; i < internals_.length(); i++) { |
| 1328 AllocateNonParameterLocal(internals_[i]); |
| 1329 } |
| 1330 |
| 1284 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 1331 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
| 1285 | |
| 1286 for (VariableMap::Entry* p = variables_.Start(); | 1332 for (VariableMap::Entry* p = variables_.Start(); |
| 1287 p != NULL; | 1333 p != NULL; |
| 1288 p = variables_.Next(p)) { | 1334 p = variables_.Next(p)) { |
| 1289 Variable* var = reinterpret_cast<Variable*>(p->value); | 1335 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 1290 vars.Add(VarAndOrder(var, p->order), zone()); | 1336 vars.Add(VarAndOrder(var, p->order), zone()); |
| 1291 } | 1337 } |
| 1292 | |
| 1293 vars.Sort(VarAndOrder::Compare); | 1338 vars.Sort(VarAndOrder::Compare); |
| 1294 int var_count = vars.length(); | 1339 int var_count = vars.length(); |
| 1295 for (int i = 0; i < var_count; i++) { | 1340 for (int i = 0; i < var_count; i++) { |
| 1296 AllocateNonParameterLocal(vars[i].var()); | 1341 AllocateNonParameterLocal(vars[i].var()); |
| 1297 } | 1342 } |
| 1298 | 1343 |
| 1299 // For now, function_ must be allocated at the very end. If it gets | 1344 // For now, function_ must be allocated at the very end. If it gets |
| 1300 // allocated in the context, it must be the last slot in the context, | 1345 // allocated in the context, it must be the last slot in the context, |
| 1301 // because of the current ScopeInfo implementation (see | 1346 // because of the current ScopeInfo implementation (see |
| 1302 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1347 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1335 // need the minimal number of slots if we must have a context. | 1380 // need the minimal number of slots if we must have a context. |
| 1336 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1381 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
| 1337 num_heap_slots_ = 0; | 1382 num_heap_slots_ = 0; |
| 1338 } | 1383 } |
| 1339 | 1384 |
| 1340 // Allocation done. | 1385 // Allocation done. |
| 1341 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1386 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
| 1342 } | 1387 } |
| 1343 | 1388 |
| 1344 | 1389 |
| 1390 void Scope::AllocateModulesRecursively(Scope* host_scope) { |
| 1391 if (already_resolved()) return; |
| 1392 if (is_module_scope()) { |
| 1393 ASSERT(interface_->IsFrozen()); |
| 1394 const char raw_name[] = ".module"; |
| 1395 Handle<String> name = isolate_->factory()->LookupSymbol( |
| 1396 Vector<const char>(raw_name, StrLength(raw_name))); |
| 1397 ASSERT(module_var_ == NULL); |
| 1398 module_var_ = host_scope->NewInternal(name); |
| 1399 ++host_scope->num_modules_; |
| 1400 } |
| 1401 |
| 1402 for (int i = 0; i < inner_scopes_.length(); i++) { |
| 1403 Scope* inner_scope = inner_scopes_.at(i); |
| 1404 inner_scope->AllocateModulesRecursively(host_scope); |
| 1405 } |
| 1406 } |
| 1407 |
| 1408 |
| 1345 int Scope::StackLocalCount() const { | 1409 int Scope::StackLocalCount() const { |
| 1346 return num_stack_slots() - | 1410 return num_stack_slots() - |
| 1347 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1411 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
| 1348 } | 1412 } |
| 1349 | 1413 |
| 1350 | 1414 |
| 1351 int Scope::ContextLocalCount() const { | 1415 int Scope::ContextLocalCount() const { |
| 1352 if (num_heap_slots() == 0) return 0; | 1416 if (num_heap_slots() == 0) return 0; |
| 1353 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1417 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1354 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1418 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
| 1355 } | 1419 } |
| 1356 | 1420 |
| 1357 | |
| 1358 void Scope::AllocateModules(CompilationInfo* info) { | |
| 1359 ASSERT(is_global_scope() || is_module_scope()); | |
| 1360 | |
| 1361 if (is_module_scope()) { | |
| 1362 ASSERT(interface_->IsFrozen()); | |
| 1363 ASSERT(scope_info_.is_null()); | |
| 1364 | |
| 1365 // TODO(rossberg): This has to be the initial compilation of this code. | |
| 1366 // We currently do not allow recompiling any module definitions. | |
| 1367 Handle<ScopeInfo> scope_info = GetScopeInfo(); | |
| 1368 Factory* factory = info->isolate()->factory(); | |
| 1369 Handle<Context> context = factory->NewModuleContext(scope_info); | |
| 1370 Handle<JSModule> instance = factory->NewJSModule(context, scope_info); | |
| 1371 context->set_module(*instance); | |
| 1372 | |
| 1373 bool ok; | |
| 1374 interface_->MakeSingleton(instance, &ok); | |
| 1375 ASSERT(ok); | |
| 1376 } | |
| 1377 | |
| 1378 // Allocate nested modules. | |
| 1379 for (int i = 0; i < inner_scopes_.length(); i++) { | |
| 1380 Scope* inner_scope = inner_scopes_.at(i); | |
| 1381 if (inner_scope->is_module_scope()) { | |
| 1382 inner_scope->AllocateModules(info); | |
| 1383 } | |
| 1384 } | |
| 1385 } | |
| 1386 | |
| 1387 | |
| 1388 void Scope::LinkModules(CompilationInfo* info) { | |
| 1389 ASSERT(is_global_scope() || is_module_scope()); | |
| 1390 | |
| 1391 if (is_module_scope()) { | |
| 1392 Handle<JSModule> instance = interface_->Instance(); | |
| 1393 | |
| 1394 // Populate the module instance object. | |
| 1395 const PropertyAttributes ro_attr = | |
| 1396 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE | DONT_ENUM); | |
| 1397 const PropertyAttributes rw_attr = | |
| 1398 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM); | |
| 1399 for (Interface::Iterator it = interface_->iterator(); | |
| 1400 !it.done(); it.Advance()) { | |
| 1401 if (it.interface()->IsModule()) { | |
| 1402 Handle<Object> value = it.interface()->Instance(); | |
| 1403 ASSERT(!value.is_null()); | |
| 1404 JSReceiver::SetProperty( | |
| 1405 instance, it.name(), value, ro_attr, kStrictMode); | |
| 1406 } else { | |
| 1407 Variable* var = LocalLookup(it.name()); | |
| 1408 ASSERT(var != NULL && var->IsContextSlot()); | |
| 1409 PropertyAttributes attr = var->is_const_mode() ? ro_attr : rw_attr; | |
| 1410 Handle<AccessorInfo> info = | |
| 1411 Accessors::MakeModuleExport(it.name(), var->index(), attr); | |
| 1412 Handle<Object> result = SetAccessor(instance, info); | |
| 1413 ASSERT(!(result.is_null() || result->IsUndefined())); | |
| 1414 USE(result); | |
| 1415 } | |
| 1416 } | |
| 1417 USE(JSObject::PreventExtensions(instance)); | |
| 1418 } | |
| 1419 | |
| 1420 // Link nested modules. | |
| 1421 for (int i = 0; i < inner_scopes_.length(); i++) { | |
| 1422 Scope* inner_scope = inner_scopes_.at(i); | |
| 1423 if (inner_scope->is_module_scope()) { | |
| 1424 inner_scope->LinkModules(info); | |
| 1425 } | |
| 1426 } | |
| 1427 } | |
| 1428 | |
| 1429 | |
| 1430 } } // namespace v8::internal | 1421 } } // namespace v8::internal |
| OLD | NEW |