| 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 |