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/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/messages.h" | 9 #include "src/messages.h" |
10 #include "src/parser.h" | 10 #include "src/parser.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 // ---------------------------------------------------------------------------- | 70 // ---------------------------------------------------------------------------- |
71 // Implementation of Scope | 71 // Implementation of Scope |
72 | 72 |
73 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, | 73 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, |
74 AstValueFactory* ast_value_factory, FunctionKind function_kind) | 74 AstValueFactory* ast_value_factory, FunctionKind function_kind) |
75 : inner_scopes_(4, zone), | 75 : inner_scopes_(4, zone), |
76 variables_(zone), | 76 variables_(zone), |
77 internals_(4, zone), | 77 internals_(4, zone), |
78 temps_(4, zone), | 78 temps_(4, zone), |
79 params_(4, zone), | 79 params_(4, zone), |
| 80 param_positions_(4, zone), |
80 unresolved_(16, zone), | 81 unresolved_(16, zone), |
81 decls_(4, zone), | 82 decls_(4, zone), |
82 module_descriptor_( | 83 module_descriptor_( |
83 scope_type == MODULE_SCOPE ? ModuleDescriptor::New(zone) : NULL), | 84 scope_type == MODULE_SCOPE ? ModuleDescriptor::New(zone) : NULL), |
84 already_resolved_(false), | 85 already_resolved_(false), |
85 ast_value_factory_(ast_value_factory), | 86 ast_value_factory_(ast_value_factory), |
86 zone_(zone), | 87 zone_(zone), |
87 class_declaration_group_start_(-1) { | 88 class_declaration_group_start_(-1) { |
88 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null(), | 89 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null(), |
89 function_kind); | 90 function_kind); |
90 // The outermost scope must be a script scope. | 91 // The outermost scope must be a script scope. |
91 DCHECK(scope_type == SCRIPT_SCOPE || outer_scope != NULL); | 92 DCHECK(scope_type == SCRIPT_SCOPE || outer_scope != NULL); |
92 DCHECK(!HasIllegalRedeclaration()); | 93 DCHECK(!HasIllegalRedeclaration()); |
93 } | 94 } |
94 | 95 |
95 | 96 |
96 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, | 97 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, |
97 Handle<ScopeInfo> scope_info, AstValueFactory* value_factory) | 98 Handle<ScopeInfo> scope_info, AstValueFactory* value_factory) |
98 : inner_scopes_(4, zone), | 99 : inner_scopes_(4, zone), |
99 variables_(zone), | 100 variables_(zone), |
100 internals_(4, zone), | 101 internals_(4, zone), |
101 temps_(4, zone), | 102 temps_(4, zone), |
102 params_(4, zone), | 103 params_(4, zone), |
| 104 param_positions_(4, zone), |
103 unresolved_(16, zone), | 105 unresolved_(16, zone), |
104 decls_(4, zone), | 106 decls_(4, zone), |
105 module_descriptor_(NULL), | 107 module_descriptor_(NULL), |
106 already_resolved_(true), | 108 already_resolved_(true), |
107 ast_value_factory_(value_factory), | 109 ast_value_factory_(value_factory), |
108 zone_(zone), | 110 zone_(zone), |
109 class_declaration_group_start_(-1) { | 111 class_declaration_group_start_(-1) { |
110 SetDefaults(scope_type, NULL, scope_info); | 112 SetDefaults(scope_type, NULL, scope_info); |
111 if (!scope_info.is_null()) { | 113 if (!scope_info.is_null()) { |
112 num_heap_slots_ = scope_info_->ContextLength(); | 114 num_heap_slots_ = scope_info_->ContextLength(); |
113 } | 115 } |
114 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 116 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
115 num_heap_slots_ = Max(num_heap_slots_, | 117 num_heap_slots_ = Max(num_heap_slots_, |
116 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 118 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
117 AddInnerScope(inner_scope); | 119 AddInnerScope(inner_scope); |
118 } | 120 } |
119 | 121 |
120 | 122 |
121 Scope::Scope(Zone* zone, Scope* inner_scope, | 123 Scope::Scope(Zone* zone, Scope* inner_scope, |
122 const AstRawString* catch_variable_name, | 124 const AstRawString* catch_variable_name, |
123 AstValueFactory* value_factory) | 125 AstValueFactory* value_factory) |
124 : inner_scopes_(1, zone), | 126 : inner_scopes_(1, zone), |
125 variables_(zone), | 127 variables_(zone), |
126 internals_(0, zone), | 128 internals_(0, zone), |
127 temps_(0, zone), | 129 temps_(0, zone), |
128 params_(0, zone), | 130 params_(0, zone), |
| 131 param_positions_(0, zone), |
129 unresolved_(0, zone), | 132 unresolved_(0, zone), |
130 decls_(0, zone), | 133 decls_(0, zone), |
131 module_descriptor_(NULL), | 134 module_descriptor_(NULL), |
132 already_resolved_(true), | 135 already_resolved_(true), |
133 ast_value_factory_(value_factory), | 136 ast_value_factory_(value_factory), |
134 zone_(zone), | 137 zone_(zone), |
135 class_declaration_group_start_(-1) { | 138 class_declaration_group_start_(-1) { |
136 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); | 139 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); |
137 AddInnerScope(inner_scope); | 140 AddInnerScope(inner_scope); |
138 ++num_var_or_const_; | 141 ++num_var_or_const_; |
139 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 142 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
140 Variable* variable = variables_.Declare(this, | 143 Variable* variable = variables_.Declare(this, |
141 catch_variable_name, | 144 catch_variable_name, |
142 VAR, | 145 VAR, |
143 Variable::NORMAL, | 146 Variable::NORMAL, |
144 kCreatedInitialized); | 147 kCreatedInitialized); |
145 AllocateHeapSlot(variable); | 148 AllocateHeapSlot(variable); |
146 } | 149 } |
147 | 150 |
148 | 151 |
149 void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope, | 152 void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope, |
150 Handle<ScopeInfo> scope_info, | 153 Handle<ScopeInfo> scope_info, |
151 FunctionKind function_kind) { | 154 FunctionKind function_kind) { |
152 outer_scope_ = outer_scope; | 155 outer_scope_ = outer_scope; |
| 156 function_body_ = nullptr; |
153 scope_type_ = scope_type; | 157 scope_type_ = scope_type; |
154 function_kind_ = function_kind; | 158 function_kind_ = function_kind; |
155 block_scope_is_class_scope_ = false; | 159 block_scope_is_class_scope_ = false; |
156 scope_name_ = ast_value_factory_->empty_string(); | 160 scope_name_ = ast_value_factory_->empty_string(); |
157 dynamics_ = NULL; | 161 dynamics_ = NULL; |
158 receiver_ = NULL; | 162 receiver_ = NULL; |
159 new_target_ = nullptr; | 163 new_target_ = nullptr; |
160 function_ = NULL; | 164 function_ = NULL; |
161 arguments_ = NULL; | 165 arguments_ = NULL; |
162 illegal_redecl_ = NULL; | 166 illegal_redecl_ = NULL; |
(...skipping 24 matching lines...) Expand all Loading... |
187 rest_index_ = -1; | 191 rest_index_ = -1; |
188 scope_info_ = scope_info; | 192 scope_info_ = scope_info; |
189 start_position_ = RelocInfo::kNoPosition; | 193 start_position_ = RelocInfo::kNoPosition; |
190 end_position_ = RelocInfo::kNoPosition; | 194 end_position_ = RelocInfo::kNoPosition; |
191 if (!scope_info.is_null()) { | 195 if (!scope_info.is_null()) { |
192 scope_calls_eval_ = scope_info->CallsEval(); | 196 scope_calls_eval_ = scope_info->CallsEval(); |
193 language_mode_ = scope_info->language_mode(); | 197 language_mode_ = scope_info->language_mode(); |
194 block_scope_is_class_scope_ = scope_info->block_scope_is_class_scope(); | 198 block_scope_is_class_scope_ = scope_info->block_scope_is_class_scope(); |
195 function_kind_ = scope_info->function_kind(); | 199 function_kind_ = scope_info->function_kind(); |
196 } | 200 } |
| 201 if (scope_type == FUNCTION_BODY_SCOPE) { |
| 202 DCHECK_NOT_NULL(outer_scope); |
| 203 DCHECK(outer_scope->is_function_scope()); |
| 204 DCHECK_NULL(outer_scope->function_body_); |
| 205 outer_scope->function_body_ = this; |
| 206 } |
197 } | 207 } |
198 | 208 |
199 | 209 |
200 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 210 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
201 Context* context, Scope* script_scope) { | 211 Context* context, Scope* script_scope) { |
202 // Reconstruct the outer scope chain from a closure's context chain. | 212 // Reconstruct the outer scope chain from a closure's context chain. |
203 Scope* current_scope = NULL; | 213 Scope* current_scope = NULL; |
204 Scope* innermost_scope = NULL; | 214 Scope* innermost_scope = NULL; |
205 bool contains_with = false; | 215 bool contains_with = false; |
206 while (!context->IsNativeContext()) { | 216 while (!context->IsNativeContext()) { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 } | 320 } |
311 | 321 |
312 // Declare convenience variables. | 322 // Declare convenience variables. |
313 // Declare and allocate receiver (even for the script scope, and even | 323 // Declare and allocate receiver (even for the script scope, and even |
314 // if naccesses_ == 0). | 324 // if naccesses_ == 0). |
315 // NOTE: When loading parameters in the script scope, we must take | 325 // NOTE: When loading parameters in the script scope, we must take |
316 // care not to access them as properties of the global object, but | 326 // care not to access them as properties of the global object, but |
317 // instead load them directly from the stack. Currently, the only | 327 // instead load them directly from the stack. Currently, the only |
318 // such parameter is 'this' which is passed on the stack when | 328 // such parameter is 'this' which is passed on the stack when |
319 // invoking scripts | 329 // invoking scripts |
320 if (is_declaration_scope()) { | 330 if (is_declaration_scope() && !is_function_body_scope()) { |
321 DCHECK(!subclass_constructor || is_function_scope()); | 331 DCHECK(!subclass_constructor || is_function_scope()); |
322 Variable* var = variables_.Declare( | 332 Variable* var = variables_.Declare( |
323 this, ast_value_factory_->this_string(), | 333 this, ast_value_factory_->this_string(), |
324 subclass_constructor ? CONST : VAR, Variable::THIS, | 334 subclass_constructor ? CONST : VAR, Variable::THIS, |
325 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | 335 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
326 var->AllocateTo(Variable::PARAMETER, -1); | 336 var->AllocateTo(Variable::PARAMETER, -1); |
327 receiver_ = var; | 337 receiver_ = var; |
328 | 338 |
329 if (subclass_constructor) { | 339 if (subclass_constructor) { |
330 new_target_ = | 340 new_target_ = |
(...skipping 21 matching lines...) Expand all Loading... |
352 | 362 |
353 | 363 |
354 Scope* Scope::FinalizeBlockScope() { | 364 Scope* Scope::FinalizeBlockScope() { |
355 DCHECK(is_block_scope()); | 365 DCHECK(is_block_scope()); |
356 DCHECK(internals_.is_empty()); | 366 DCHECK(internals_.is_empty()); |
357 DCHECK(temps_.is_empty()); | 367 DCHECK(temps_.is_empty()); |
358 DCHECK(params_.is_empty()); | 368 DCHECK(params_.is_empty()); |
359 | 369 |
360 if (num_var_or_const() > 0) return this; | 370 if (num_var_or_const() > 0) return this; |
361 | 371 |
| 372 // If this is the function body scope of a function scope, remove the parent |
| 373 // function body. |
| 374 if (outer_scope_->function_body_ == this) { |
| 375 outer_scope_->function_body_ = nullptr; |
| 376 } |
| 377 |
362 // Remove this scope from outer scope. | 378 // Remove this scope from outer scope. |
363 for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) { | 379 for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) { |
364 if (outer_scope_->inner_scopes_[i] == this) { | 380 if (outer_scope_->inner_scopes_[i] == this) { |
365 outer_scope_->inner_scopes_.Remove(i); | 381 outer_scope_->inner_scopes_.Remove(i); |
366 break; | 382 break; |
367 } | 383 } |
368 } | 384 } |
369 | 385 |
370 // Reparent inner scopes. | 386 // Reparent inner scopes. |
371 for (int i = 0; i < inner_scopes_.length(); i++) { | 387 for (int i = 0; i < inner_scopes_.length(); i++) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 scope != NULL; | 473 scope != NULL; |
458 scope = scope->outer_scope()) { | 474 scope = scope->outer_scope()) { |
459 Variable* var = scope->LookupLocal(name); | 475 Variable* var = scope->LookupLocal(name); |
460 if (var != NULL) return var; | 476 if (var != NULL) return var; |
461 } | 477 } |
462 return NULL; | 478 return NULL; |
463 } | 479 } |
464 | 480 |
465 | 481 |
466 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, | 482 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, |
467 bool is_rest, bool* is_duplicate) { | 483 int pos, bool is_rest, bool* is_duplicate) { |
468 DCHECK(!already_resolved()); | 484 DCHECK(!already_resolved()); |
469 DCHECK(is_function_scope()); | 485 DCHECK(is_function_scope()); |
470 Variable* var = variables_.Declare(this, name, mode, Variable::NORMAL, | 486 Variable* var = variables_.Declare(this, name, mode, Variable::NORMAL, |
471 kCreatedInitialized); | 487 kCreatedInitialized); |
472 if (is_rest) { | 488 if (is_rest) { |
473 DCHECK_NULL(rest_parameter_); | 489 DCHECK_NULL(rest_parameter_); |
474 rest_parameter_ = var; | 490 rest_parameter_ = var; |
475 rest_index_ = num_parameters(); | 491 rest_index_ = num_parameters(); |
476 } | 492 } |
477 // TODO(wingo): Avoid O(n^2) check. | 493 // TODO(wingo): Avoid O(n^2) check. |
478 *is_duplicate = IsDeclaredParameter(name); | 494 *is_duplicate = IsDeclaredParameter(name); |
479 params_.Add(var, zone()); | 495 params_.Add(var, zone()); |
| 496 param_positions_.Add(pos, zone()); |
480 return var; | 497 return var; |
481 } | 498 } |
482 | 499 |
483 | 500 |
484 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, | 501 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, |
485 InitializationFlag init_flag, Variable::Kind kind, | 502 InitializationFlag init_flag, Variable::Kind kind, |
486 MaybeAssignedFlag maybe_assigned_flag, | 503 MaybeAssignedFlag maybe_assigned_flag, |
487 int declaration_group_start) { | 504 int declaration_group_start) { |
488 DCHECK(!already_resolved()); | 505 DCHECK(!already_resolved()); |
489 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 506 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
490 // introduces during variable allocation, INTERNAL variables are allocated | 507 // introduces during variable allocation, INTERNAL variables are allocated |
491 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). | 508 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). |
492 DCHECK(IsDeclaredVariableMode(mode)); | 509 DCHECK(IsDeclaredVariableMode(mode)); |
493 ++num_var_or_const_; | 510 ++num_var_or_const_; |
494 return variables_.Declare(this, name, mode, kind, init_flag, | 511 return variables_.Declare(this, name, mode, kind, init_flag, |
495 maybe_assigned_flag, declaration_group_start); | 512 maybe_assigned_flag, declaration_group_start); |
496 } | 513 } |
497 | 514 |
498 | 515 |
| 516 Variable* Scope::RedeclareLocal(const AstRawString* name, VariableMode mode, |
| 517 InitializationFlag init_flag, |
| 518 Variable::Kind kind, |
| 519 MaybeAssignedFlag maybe_assigned_flag, |
| 520 int declaration_group_start) { |
| 521 variables_.Remove(const_cast<AstRawString*>(name), name->hash()); |
| 522 return DeclareLocal(name, mode, init_flag, kind, maybe_assigned_flag, |
| 523 declaration_group_start); |
| 524 } |
| 525 |
| 526 |
499 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { | 527 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { |
500 DCHECK(is_script_scope()); | 528 DCHECK(is_script_scope()); |
501 return variables_.Declare(this, | 529 return variables_.Declare(this, |
502 name, | 530 name, |
503 DYNAMIC_GLOBAL, | 531 DYNAMIC_GLOBAL, |
504 Variable::NORMAL, | 532 Variable::NORMAL, |
505 kCreatedInitialized); | 533 kCreatedInitialized); |
506 } | 534 } |
507 | 535 |
508 | 536 |
(...skipping 27 matching lines...) Expand all Loading... |
536 name, | 564 name, |
537 TEMPORARY, | 565 TEMPORARY, |
538 Variable::NORMAL, | 566 Variable::NORMAL, |
539 kCreatedInitialized); | 567 kCreatedInitialized); |
540 temps_.Add(var, zone()); | 568 temps_.Add(var, zone()); |
541 return var; | 569 return var; |
542 } | 570 } |
543 | 571 |
544 | 572 |
545 void Scope::AddDeclaration(Declaration* declaration) { | 573 void Scope::AddDeclaration(Declaration* declaration) { |
546 decls_.Add(declaration, zone()); | 574 Scope* target = this; |
| 575 if (is_function_body_scope() && |
| 576 (declaration->mode() == VAR || declaration->IsFunctionDeclaration())) { |
| 577 // Add `var` declarations to outer scope, to make allocation simpler |
| 578 target = outer_scope(); |
| 579 DCHECK(target->is_function_scope()); |
| 580 } |
| 581 target->decls_.Add(declaration, zone()); |
547 } | 582 } |
548 | 583 |
549 | 584 |
550 void Scope::SetIllegalRedeclaration(Expression* expression) { | 585 void Scope::SetIllegalRedeclaration(Expression* expression) { |
551 // Record only the first illegal redeclaration. | 586 // Record only the first illegal redeclaration. |
552 if (!HasIllegalRedeclaration()) { | 587 if (!HasIllegalRedeclaration()) { |
553 illegal_redecl_ = expression; | 588 illegal_redecl_ = expression; |
554 } | 589 } |
555 DCHECK(HasIllegalRedeclaration()); | 590 DCHECK(HasIllegalRedeclaration()); |
556 } | 591 } |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 | 746 |
712 bool Scope::HasLazyCompilableOuterContext() const { | 747 bool Scope::HasLazyCompilableOuterContext() const { |
713 Scope* outer = outer_scope_; | 748 Scope* outer = outer_scope_; |
714 if (outer == NULL) return true; | 749 if (outer == NULL) return true; |
715 // We have to prevent lazy compilation if this scope is inside a with scope | 750 // We have to prevent lazy compilation if this scope is inside a with scope |
716 // and all declaration scopes between them have empty contexts. Such | 751 // and all declaration scopes between them have empty contexts. Such |
717 // declaration scopes may become invisible during scope info deserialization. | 752 // declaration scopes may become invisible during scope info deserialization. |
718 outer = outer->DeclarationScope(); | 753 outer = outer->DeclarationScope(); |
719 bool found_non_trivial_declarations = false; | 754 bool found_non_trivial_declarations = false; |
720 for (const Scope* scope = outer; scope != NULL; scope = scope->outer_scope_) { | 755 for (const Scope* scope = outer; scope != NULL; scope = scope->outer_scope_) { |
721 if (scope->is_with_scope() && !found_non_trivial_declarations) return false; | 756 if ((scope->is_function_body_scope() || scope->is_with_scope()) && |
| 757 !found_non_trivial_declarations) |
| 758 return false; |
722 if (scope->is_block_scope() && !scope->decls_.is_empty()) return false; | 759 if (scope->is_block_scope() && !scope->decls_.is_empty()) return false; |
723 if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) { | 760 if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) { |
724 found_non_trivial_declarations = true; | 761 found_non_trivial_declarations = true; |
725 } | 762 } |
726 } | 763 } |
727 return true; | 764 return true; |
728 } | 765 } |
729 | 766 |
730 | 767 |
731 bool Scope::AllowsLazyCompilation() const { | 768 bool Scope::AllowsLazyCompilation() const { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 static const char* Header(ScopeType scope_type) { | 849 static const char* Header(ScopeType scope_type) { |
813 switch (scope_type) { | 850 switch (scope_type) { |
814 case EVAL_SCOPE: return "eval"; | 851 case EVAL_SCOPE: return "eval"; |
815 case FUNCTION_SCOPE: return "function"; | 852 case FUNCTION_SCOPE: return "function"; |
816 case MODULE_SCOPE: return "module"; | 853 case MODULE_SCOPE: return "module"; |
817 case SCRIPT_SCOPE: return "global"; | 854 case SCRIPT_SCOPE: return "global"; |
818 case CATCH_SCOPE: return "catch"; | 855 case CATCH_SCOPE: return "catch"; |
819 case BLOCK_SCOPE: return "block"; | 856 case BLOCK_SCOPE: return "block"; |
820 case WITH_SCOPE: return "with"; | 857 case WITH_SCOPE: return "with"; |
821 case ARROW_SCOPE: return "arrow"; | 858 case ARROW_SCOPE: return "arrow"; |
| 859 case FUNCTION_BODY_SCOPE: |
| 860 return "function body"; |
822 } | 861 } |
823 UNREACHABLE(); | 862 UNREACHABLE(); |
824 return NULL; | 863 return NULL; |
825 } | 864 } |
826 | 865 |
827 | 866 |
828 static void Indent(int n, const char* str) { | 867 static void Indent(int n, const char* str) { |
829 PrintF("%*s%s", n, "", str); | 868 PrintF("%*s%s", n, "", str); |
830 } | 869 } |
831 | 870 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 Variable* Scope::LookupRecursive(VariableProxy* proxy, | 1053 Variable* Scope::LookupRecursive(VariableProxy* proxy, |
1015 BindingKind* binding_kind, | 1054 BindingKind* binding_kind, |
1016 AstNodeFactory* factory) { | 1055 AstNodeFactory* factory) { |
1017 DCHECK(binding_kind != NULL); | 1056 DCHECK(binding_kind != NULL); |
1018 if (already_resolved() && is_with_scope()) { | 1057 if (already_resolved() && is_with_scope()) { |
1019 // Short-cut: if the scope is deserialized from a scope info, variable | 1058 // Short-cut: if the scope is deserialized from a scope info, variable |
1020 // allocation is already fixed. We can simply return with dynamic lookup. | 1059 // allocation is already fixed. We can simply return with dynamic lookup. |
1021 *binding_kind = DYNAMIC_LOOKUP; | 1060 *binding_kind = DYNAMIC_LOOKUP; |
1022 return NULL; | 1061 return NULL; |
1023 } | 1062 } |
1024 | |
1025 // Try to find the variable in this scope. | 1063 // Try to find the variable in this scope. |
1026 Variable* var = LookupLocal(proxy->raw_name()); | 1064 Variable* var = LookupLocal(proxy->raw_name()); |
1027 | 1065 |
1028 // We found a variable and we are done. (Even if there is an 'eval' in | 1066 // We found a variable and we are done. (Even if there is an 'eval' in |
1029 // this scope which introduces the same variable again, the resulting | 1067 // this scope which introduces the same variable again, the resulting |
1030 // variable remains the same.) | 1068 // variable remains the same.) |
1031 if (var != NULL) { | 1069 if (var != NULL) { |
1032 *binding_kind = BOUND; | 1070 *binding_kind = BOUND; |
1033 return var; | 1071 return var; |
1034 } | 1072 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 *binding_kind = UNBOUND_EVAL_SHADOWED; | 1109 *binding_kind = UNBOUND_EVAL_SHADOWED; |
1072 } | 1110 } |
1073 } | 1111 } |
1074 return var; | 1112 return var; |
1075 } | 1113 } |
1076 | 1114 |
1077 | 1115 |
1078 bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy, | 1116 bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy, |
1079 AstNodeFactory* factory) { | 1117 AstNodeFactory* factory) { |
1080 DCHECK(info->script_scope()->is_script_scope()); | 1118 DCHECK(info->script_scope()->is_script_scope()); |
1081 | |
1082 // If the proxy is already resolved there's nothing to do | 1119 // If the proxy is already resolved there's nothing to do |
1083 // (functions and consts may be resolved by the parser). | 1120 // (functions and consts may be resolved by the parser). |
1084 if (proxy->is_resolved()) return true; | 1121 if (proxy->is_resolved()) return true; |
1085 | 1122 |
1086 // Otherwise, try to resolve the variable. | 1123 // Otherwise, try to resolve the variable. |
1087 BindingKind binding_kind; | 1124 BindingKind binding_kind; |
1088 Variable* var = LookupRecursive(proxy, &binding_kind, factory); | 1125 Variable* var = LookupRecursive(proxy, &binding_kind, factory); |
1089 switch (binding_kind) { | 1126 switch (binding_kind) { |
1090 case BOUND: | 1127 case BOUND: |
1091 // We found a variable binding. | 1128 // We found a variable binding. |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 if (params_[i]->name().is_identical_to( | 1386 if (params_[i]->name().is_identical_to( |
1350 isolate->factory()->arguments_string())) { | 1387 isolate->factory()->arguments_string())) { |
1351 return true; | 1388 return true; |
1352 } | 1389 } |
1353 } | 1390 } |
1354 return false; | 1391 return false; |
1355 } | 1392 } |
1356 | 1393 |
1357 | 1394 |
1358 void Scope::AllocateStackSlot(Variable* var) { | 1395 void Scope::AllocateStackSlot(Variable* var) { |
1359 if (is_block_scope()) { | 1396 if (is_function_body_scope()) { |
| 1397 // Function body variables need to be allocated in the "real" function |
| 1398 // scope, but can't be resolved from it |
| 1399 outer_scope()->AllocateStackSlot(var); |
| 1400 } else if (is_block_scope()) { |
1360 DeclarationScope()->AllocateStackSlot(var); | 1401 DeclarationScope()->AllocateStackSlot(var); |
1361 } else { | 1402 } else { |
1362 var->AllocateTo(Variable::LOCAL, num_stack_slots_++); | 1403 var->AllocateTo(Variable::LOCAL, num_stack_slots_++); |
1363 } | 1404 } |
1364 } | 1405 } |
1365 | 1406 |
1366 | 1407 |
1367 void Scope::AllocateHeapSlot(Variable* var) { | 1408 void Scope::AllocateHeapSlot(Variable* var) { |
| 1409 DCHECK(!is_function_body_scope() || var->scope() == outer_scope()); |
| 1410 if (is_function_body_scope()) return outer_scope()->AllocateHeapSlot(var); |
1368 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++); | 1411 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++); |
1369 } | 1412 } |
1370 | 1413 |
1371 | 1414 |
1372 void Scope::AllocateParameterLocals(Isolate* isolate) { | 1415 void Scope::AllocateParameterLocals(Isolate* isolate) { |
1373 DCHECK(is_function_scope()); | 1416 DCHECK(is_function_scope()); |
1374 Variable* arguments = LookupLocal(ast_value_factory_->arguments_string()); | 1417 Variable* arguments = LookupLocal(ast_value_factory_->arguments_string()); |
1375 // Functions have 'arguments' declared implicitly in all non arrow functions. | 1418 // Functions have 'arguments' declared implicitly in all non arrow functions. |
1376 DCHECK(arguments != nullptr || is_arrow_scope()); | 1419 DCHECK(arguments != nullptr || is_arrow_scope()); |
1377 | 1420 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 if (var->IsUnallocated()) { | 1470 if (var->IsUnallocated()) { |
1428 var->AllocateTo(Variable::PARAMETER, i); | 1471 var->AllocateTo(Variable::PARAMETER, i); |
1429 } | 1472 } |
1430 } | 1473 } |
1431 } | 1474 } |
1432 } | 1475 } |
1433 } | 1476 } |
1434 | 1477 |
1435 | 1478 |
1436 void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) { | 1479 void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) { |
1437 DCHECK(var->scope() == this); | 1480 DCHECK(var->scope() == this || |
| 1481 (is_function_body_scope() && var->scope() == outer_scope())); |
1438 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) || | 1482 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) || |
1439 !var->IsStackLocal()); | 1483 !var->IsStackLocal()); |
1440 if (var->IsUnallocated() && MustAllocate(var)) { | 1484 if (var->IsUnallocated() && MustAllocate(var)) { |
1441 if (MustAllocateInContext(var)) { | 1485 if (MustAllocateInContext(var)) { |
1442 AllocateHeapSlot(var); | 1486 AllocateHeapSlot(var); |
1443 } else { | 1487 } else { |
1444 AllocateStackSlot(var); | 1488 AllocateStackSlot(var); |
1445 } | 1489 } |
1446 } | 1490 } |
1447 } | 1491 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1532 DCHECK(scope->module_descriptor_->IsFrozen()); | 1576 DCHECK(scope->module_descriptor_->IsFrozen()); |
1533 DCHECK_NULL(scope->module_var_); | 1577 DCHECK_NULL(scope->module_var_); |
1534 scope->module_var_ = NewInternal(ast_value_factory_->dot_module_string()); | 1578 scope->module_var_ = NewInternal(ast_value_factory_->dot_module_string()); |
1535 ++num_modules_; | 1579 ++num_modules_; |
1536 } | 1580 } |
1537 } | 1581 } |
1538 } | 1582 } |
1539 | 1583 |
1540 | 1584 |
1541 int Scope::StackLocalCount() const { | 1585 int Scope::StackLocalCount() const { |
| 1586 DCHECK(!function_body() || function_body()->num_stack_slots() == 0); |
1542 return num_stack_slots() - | 1587 return num_stack_slots() - |
1543 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1588 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
1544 } | 1589 } |
1545 | 1590 |
1546 | 1591 |
1547 int Scope::ContextLocalCount() const { | 1592 int Scope::ContextLocalCount() const { |
| 1593 DCHECK(!function_body() || function_body()->num_heap_slots() == 0); |
1548 if (num_heap_slots() == 0) return 0; | 1594 if (num_heap_slots() == 0) return 0; |
1549 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1595 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1550 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1596 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1551 } | 1597 } |
1552 } } // namespace v8::internal | 1598 } } // namespace v8::internal |
OLD | NEW |