| 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/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/ast/ast.h" | 10 #include "src/ast/ast.h" |
| 11 #include "src/bootstrapper.h" | 11 #include "src/bootstrapper.h" |
| 12 #include "src/counters.h" | 12 #include "src/counters.h" |
| 13 #include "src/messages.h" | 13 #include "src/messages.h" |
| 14 #include "src/objects-inl.h" | 14 #include "src/objects-inl.h" |
| 15 #include "src/objects/module-info.h" | 15 #include "src/objects/module-info.h" |
| 16 #include "src/parsing/parse-info.h" | 16 #include "src/parsing/parse-info.h" |
| 17 | 17 |
| 18 namespace v8 { | 18 namespace v8 { |
| 19 namespace internal { | 19 namespace internal { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 void* kDummyPreParserVariable = reinterpret_cast<void*>(0x1); | 22 void* kDummyPreParserVariable = reinterpret_cast<void*>(0x1); |
| 23 void* kDummyPreParserLexicalVariable = reinterpret_cast<void*>(0x2); |
| 24 |
| 25 bool IsLexical(Variable* variable) { |
| 26 if (variable == kDummyPreParserLexicalVariable) return true; |
| 27 if (variable == kDummyPreParserVariable) return false; |
| 28 return IsLexicalVariableMode(variable->mode()); |
| 29 } |
| 30 |
| 23 } // namespace | 31 } // namespace |
| 24 | 32 |
| 25 // ---------------------------------------------------------------------------- | 33 // ---------------------------------------------------------------------------- |
| 26 // Implementation of LocalsMap | 34 // Implementation of LocalsMap |
| 27 // | 35 // |
| 28 // Note: We are storing the handle locations as key values in the hash map. | 36 // Note: We are storing the handle locations as key values in the hash map. |
| 29 // When inserting a new variable via Declare(), we rely on the fact that | 37 // When inserting a new variable via Declare(), we rely on the fact that |
| 30 // the handle location remains alive for the duration of that variable | 38 // the handle location remains alive for the duration of that variable |
| 31 // use. Because a Variable holding a handle with the same location exists | 39 // use. Because a Variable holding a handle with the same location exists |
| 32 // this is ensured. | 40 // this is ensured. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 49 if (added) *added = p->value == nullptr; | 57 if (added) *added = p->value == nullptr; |
| 50 if (p->value == nullptr) { | 58 if (p->value == nullptr) { |
| 51 // The variable has not been declared yet -> insert it. | 59 // The variable has not been declared yet -> insert it. |
| 52 DCHECK_EQ(name, p->key); | 60 DCHECK_EQ(name, p->key); |
| 53 p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag, | 61 p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag, |
| 54 maybe_assigned_flag); | 62 maybe_assigned_flag); |
| 55 } | 63 } |
| 56 return reinterpret_cast<Variable*>(p->value); | 64 return reinterpret_cast<Variable*>(p->value); |
| 57 } | 65 } |
| 58 | 66 |
| 59 void VariableMap::DeclareName(Zone* zone, const AstRawString* name) { | 67 void VariableMap::DeclareName(Zone* zone, const AstRawString* name, |
| 68 VariableMode mode) { |
| 60 Entry* p = | 69 Entry* p = |
| 61 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), | 70 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
| 62 ZoneAllocationPolicy(zone)); | 71 ZoneAllocationPolicy(zone)); |
| 63 if (p->value == nullptr) { | 72 if (p->value == nullptr) { |
| 64 // The variable has not been declared yet -> insert it. | 73 // The variable has not been declared yet -> insert it. |
| 65 DCHECK_EQ(name, p->key); | 74 DCHECK_EQ(name, p->key); |
| 66 p->value = kDummyPreParserVariable; | 75 p->value = |
| 76 mode == VAR ? kDummyPreParserVariable : kDummyPreParserLexicalVariable; |
| 67 } | 77 } |
| 68 } | 78 } |
| 69 | 79 |
| 70 void VariableMap::Remove(Variable* var) { | 80 void VariableMap::Remove(Variable* var) { |
| 71 const AstRawString* name = var->raw_name(); | 81 const AstRawString* name = var->raw_name(); |
| 72 ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash()); | 82 ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash()); |
| 73 } | 83 } |
| 74 | 84 |
| 75 void VariableMap::Add(Zone* zone, Variable* var) { | 85 void VariableMap::Add(Zone* zone, Variable* var) { |
| 76 const AstRawString* name = var->raw_name(); | 86 const AstRawString* name = var->raw_name(); |
| 77 Entry* p = | 87 Entry* p = |
| 78 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), | 88 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
| 79 ZoneAllocationPolicy(zone)); | 89 ZoneAllocationPolicy(zone)); |
| 80 DCHECK_NULL(p->value); | 90 DCHECK_NULL(p->value); |
| 81 DCHECK_EQ(name, p->key); | 91 DCHECK_EQ(name, p->key); |
| 82 p->value = var; | 92 p->value = var; |
| 83 } | 93 } |
| 84 | 94 |
| 85 Variable* VariableMap::Lookup(const AstRawString* name) { | 95 Variable* VariableMap::Lookup(const AstRawString* name) { |
| 86 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash()); | 96 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash()); |
| 87 if (p != NULL) { | 97 if (p != NULL) { |
| 88 DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name); | 98 DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name); |
| 89 DCHECK(p->value != NULL); | 99 DCHECK(p->value != NULL); |
| 90 return reinterpret_cast<Variable*>(p->value); | 100 return reinterpret_cast<Variable*>(p->value); |
| 91 } | 101 } |
| 92 return NULL; | 102 return NULL; |
| 93 } | 103 } |
| 94 | 104 |
| 105 void SloppyBlockFunctionMap::Delegate::set_statement(Statement* statement) { |
| 106 if (statement_ != nullptr) { |
| 107 statement_->set_statement(statement); |
| 108 } |
| 109 } |
| 110 |
| 95 SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone) | 111 SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone) |
| 96 : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {} | 112 : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {} |
| 97 | 113 |
| 98 void SloppyBlockFunctionMap::Declare(Zone* zone, const AstRawString* name, | 114 void SloppyBlockFunctionMap::Declare( |
| 99 SloppyBlockFunctionStatement* stmt) { | 115 Zone* zone, const AstRawString* name, |
| 116 SloppyBlockFunctionMap::Delegate* delegate) { |
| 100 // AstRawStrings are unambiguous, i.e., the same string is always represented | 117 // AstRawStrings are unambiguous, i.e., the same string is always represented |
| 101 // by the same AstRawString*. | 118 // by the same AstRawString*. |
| 102 Entry* p = | 119 Entry* p = |
| 103 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), | 120 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
| 104 ZoneAllocationPolicy(zone)); | 121 ZoneAllocationPolicy(zone)); |
| 105 stmt->set_next(static_cast<SloppyBlockFunctionStatement*>(p->value)); | 122 delegate->set_next(static_cast<SloppyBlockFunctionMap::Delegate*>(p->value)); |
| 106 p->value = stmt; | 123 p->value = delegate; |
| 107 } | 124 } |
| 108 | 125 |
| 109 | |
| 110 // ---------------------------------------------------------------------------- | 126 // ---------------------------------------------------------------------------- |
| 111 // Implementation of Scope | 127 // Implementation of Scope |
| 112 | 128 |
| 113 Scope::Scope(Zone* zone) | 129 Scope::Scope(Zone* zone) |
| 114 : zone_(zone), | 130 : zone_(zone), |
| 115 outer_scope_(nullptr), | 131 outer_scope_(nullptr), |
| 116 variables_(zone), | 132 variables_(zone), |
| 117 scope_type_(SCRIPT_SCOPE) { | 133 scope_type_(SCRIPT_SCOPE) { |
| 118 SetDefaults(); | 134 SetDefaults(); |
| 119 } | 135 } |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 | 457 |
| 442 const ModuleScope* Scope::AsModuleScope() const { | 458 const ModuleScope* Scope::AsModuleScope() const { |
| 443 DCHECK(is_module_scope()); | 459 DCHECK(is_module_scope()); |
| 444 return static_cast<const ModuleScope*>(this); | 460 return static_cast<const ModuleScope*>(this); |
| 445 } | 461 } |
| 446 | 462 |
| 447 int Scope::num_parameters() const { | 463 int Scope::num_parameters() const { |
| 448 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; | 464 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; |
| 449 } | 465 } |
| 450 | 466 |
| 467 void DeclarationScope::DeclareSloppyBlockFunction( |
| 468 const AstRawString* name, Scope* scope, |
| 469 SloppyBlockFunctionStatement* statement) { |
| 470 auto* delegate = |
| 471 new (zone()) SloppyBlockFunctionMap::Delegate(scope, statement); |
| 472 sloppy_block_function_map_.Declare(zone(), name, delegate); |
| 473 } |
| 474 |
| 451 void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) { | 475 void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) { |
| 452 DCHECK(is_sloppy(language_mode())); | 476 DCHECK(is_sloppy(language_mode())); |
| 453 DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() || | 477 DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() || |
| 454 (is_block_scope() && outer_scope()->is_function_scope())); | 478 (is_block_scope() && outer_scope()->is_function_scope())); |
| 455 DCHECK(HasSimpleParameters() || is_block_scope()); | 479 DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_); |
| 480 DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_); |
| 481 |
| 456 bool has_simple_parameters = HasSimpleParameters(); | 482 bool has_simple_parameters = HasSimpleParameters(); |
| 457 // For each variable which is used as a function declaration in a sloppy | 483 // For each variable which is used as a function declaration in a sloppy |
| 458 // block, | 484 // block, |
| 459 SloppyBlockFunctionMap* map = sloppy_block_function_map(); | 485 SloppyBlockFunctionMap* map = sloppy_block_function_map(); |
| 460 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { | 486 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { |
| 461 AstRawString* name = static_cast<AstRawString*>(p->key); | 487 AstRawString* name = static_cast<AstRawString*>(p->key); |
| 462 | 488 |
| 463 // If the variable wouldn't conflict with a lexical declaration | 489 // If the variable wouldn't conflict with a lexical declaration |
| 464 // or parameter, | 490 // or parameter, |
| 465 | 491 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 477 } | 503 } |
| 478 } else { | 504 } else { |
| 479 if (IsDeclaredParameter(name)) { | 505 if (IsDeclaredParameter(name)) { |
| 480 continue; | 506 continue; |
| 481 } | 507 } |
| 482 } | 508 } |
| 483 | 509 |
| 484 bool var_created = false; | 510 bool var_created = false; |
| 485 | 511 |
| 486 // Write in assignments to var for each block-scoped function declaration | 512 // Write in assignments to var for each block-scoped function declaration |
| 487 auto delegates = static_cast<SloppyBlockFunctionStatement*>(p->value); | 513 auto delegates = static_cast<SloppyBlockFunctionMap::Delegate*>(p->value); |
| 488 | 514 |
| 489 DeclarationScope* decl_scope = this; | 515 DeclarationScope* decl_scope = this; |
| 490 while (decl_scope->is_eval_scope()) { | 516 while (decl_scope->is_eval_scope()) { |
| 491 decl_scope = decl_scope->outer_scope()->GetDeclarationScope(); | 517 decl_scope = decl_scope->outer_scope()->GetDeclarationScope(); |
| 492 } | 518 } |
| 493 Scope* outer_scope = decl_scope->outer_scope(); | 519 Scope* outer_scope = decl_scope->outer_scope(); |
| 494 | 520 |
| 495 for (SloppyBlockFunctionStatement* delegate = delegates; | 521 for (SloppyBlockFunctionMap::Delegate* delegate = delegates; |
| 496 delegate != nullptr; delegate = delegate->next()) { | 522 delegate != nullptr; delegate = delegate->next()) { |
| 497 // Check if there's a conflict with a lexical declaration | 523 // Check if there's a conflict with a lexical declaration |
| 498 Scope* query_scope = delegate->scope()->outer_scope(); | 524 Scope* query_scope = delegate->scope()->outer_scope(); |
| 499 Variable* var = nullptr; | 525 Variable* var = nullptr; |
| 500 bool should_hoist = true; | 526 bool should_hoist = true; |
| 501 | 527 |
| 502 // Note that we perform this loop for each delegate named 'name', | 528 // Note that we perform this loop for each delegate named 'name', |
| 503 // which may duplicate work if those delegates share scopes. | 529 // which may duplicate work if those delegates share scopes. |
| 504 // It is not sufficient to just do a Lookup on query_scope: for | 530 // It is not sufficient to just do a Lookup on query_scope: for |
| 505 // example, that does not prevent hoisting of the function in | 531 // example, that does not prevent hoisting of the function in |
| 506 // `{ let e; try {} catch (e) { function e(){} } }` | 532 // `{ let e; try {} catch (e) { function e(){} } }` |
| 507 do { | 533 do { |
| 508 var = query_scope->LookupLocal(name); | 534 var = query_scope->LookupLocal(name); |
| 509 if (var != nullptr && IsLexicalVariableMode(var->mode())) { | 535 if (var != nullptr && IsLexical(var)) { |
| 510 should_hoist = false; | 536 should_hoist = false; |
| 511 break; | 537 break; |
| 512 } | 538 } |
| 513 query_scope = query_scope->outer_scope(); | 539 query_scope = query_scope->outer_scope(); |
| 514 } while (query_scope != outer_scope); | 540 } while (query_scope != outer_scope); |
| 515 | 541 |
| 516 if (!should_hoist) continue; | 542 if (!should_hoist) continue; |
| 517 | 543 |
| 518 // Declare a var-style binding for the function in the outer scope | 544 // Declare a var-style binding for the function in the outer scope |
| 519 if (!var_created) { | 545 if (!var_created) { |
| 520 var_created = true; | 546 var_created = true; |
| 521 VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE); | 547 if (factory) { |
| 522 Declaration* declaration = | 548 VariableProxy* proxy = |
| 523 factory->NewVariableDeclaration(proxy, this, kNoSourcePosition); | 549 factory->NewVariableProxy(name, NORMAL_VARIABLE); |
| 524 // Based on the preceding check, it doesn't matter what we pass as | 550 auto declaration = |
| 525 // allow_harmony_restrictive_generators and | 551 factory->NewVariableDeclaration(proxy, this, kNoSourcePosition); |
| 526 // sloppy_mode_block_scope_function_redefinition. | 552 // Based on the preceding check, it doesn't matter what we pass as |
| 527 bool ok = true; | 553 // allow_harmony_restrictive_generators and |
| 528 DeclareVariable(declaration, VAR, | 554 // sloppy_mode_block_scope_function_redefinition. |
| 529 Variable::DefaultInitializationFlag(VAR), false, | 555 bool ok = true; |
| 530 nullptr, &ok); | 556 DeclareVariable(declaration, VAR, |
| 531 CHECK(ok); // Based on the preceding check, this should not fail | 557 Variable::DefaultInitializationFlag(VAR), false, |
| 558 nullptr, &ok); |
| 559 CHECK(ok); // Based on the preceding check, this should not fail |
| 560 } else { |
| 561 DeclareVariableName(name, VAR); |
| 562 } |
| 532 } | 563 } |
| 533 | 564 |
| 534 Expression* assignment = factory->NewAssignment( | 565 if (factory) { |
| 535 Token::ASSIGN, NewUnresolved(factory, name), | 566 Expression* assignment = factory->NewAssignment( |
| 536 delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition); | 567 Token::ASSIGN, NewUnresolved(factory, name), |
| 537 Statement* statement = | 568 delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition); |
| 538 factory->NewExpressionStatement(assignment, kNoSourcePosition); | 569 Statement* statement = |
| 539 delegate->set_statement(statement); | 570 factory->NewExpressionStatement(assignment, kNoSourcePosition); |
| 571 delegate->set_statement(statement); |
| 572 } |
| 540 } | 573 } |
| 541 } | 574 } |
| 542 } | 575 } |
| 543 | 576 |
| 544 void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) { | 577 void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) { |
| 545 RuntimeCallTimerScope runtimeTimer(info->isolate(), | 578 RuntimeCallTimerScope runtimeTimer(info->isolate(), |
| 546 &RuntimeCallStats::CompileScopeAnalysis); | 579 &RuntimeCallStats::CompileScopeAnalysis); |
| 547 DCHECK(info->literal() != NULL); | 580 DCHECK(info->literal() != NULL); |
| 548 DeclarationScope* scope = info->literal()->scope(); | 581 DeclarationScope* scope = info->literal()->scope(); |
| 549 | 582 |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1041 DCHECK(!is_eval_scope()); | 1074 DCHECK(!is_eval_scope()); |
| 1042 // Unlike DeclareVariable, DeclareVariableName allows declaring variables in | 1075 // Unlike DeclareVariable, DeclareVariableName allows declaring variables in |
| 1043 // catch scopes: Parser::RewriteCatchPattern bypasses DeclareVariable by | 1076 // catch scopes: Parser::RewriteCatchPattern bypasses DeclareVariable by |
| 1044 // calling DeclareLocal directly, and it doesn't make sense to add a similar | 1077 // calling DeclareLocal directly, and it doesn't make sense to add a similar |
| 1045 // bypass mechanism for PreParser. | 1078 // bypass mechanism for PreParser. |
| 1046 DCHECK(is_declaration_scope() || (IsLexicalVariableMode(mode) && | 1079 DCHECK(is_declaration_scope() || (IsLexicalVariableMode(mode) && |
| 1047 (is_block_scope() || is_catch_scope()))); | 1080 (is_block_scope() || is_catch_scope()))); |
| 1048 DCHECK(scope_info_.is_null()); | 1081 DCHECK(scope_info_.is_null()); |
| 1049 | 1082 |
| 1050 // Declare the variable in the declaration scope. | 1083 // Declare the variable in the declaration scope. |
| 1051 variables_.DeclareName(zone(), name); | 1084 variables_.DeclareName(zone(), name, mode); |
| 1052 } | 1085 } |
| 1053 | 1086 |
| 1054 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, | 1087 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, |
| 1055 const AstRawString* name, | 1088 const AstRawString* name, |
| 1056 int start_position, VariableKind kind) { | 1089 int start_position, VariableKind kind) { |
| 1057 // Note that we must not share the unresolved variables with | 1090 // Note that we must not share the unresolved variables with |
| 1058 // the same name because they may be removed selectively via | 1091 // the same name because they may be removed selectively via |
| 1059 // RemoveUnresolved(). | 1092 // RemoveUnresolved(). |
| 1060 DCHECK(!already_resolved_); | 1093 DCHECK(!already_resolved_); |
| 1061 DCHECK_EQ(factory->zone(), zone()); | 1094 DCHECK_EQ(factory->zone(), zone()); |
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1640 } | 1673 } |
| 1641 | 1674 |
| 1642 DCHECK(!is_script_scope()); | 1675 DCHECK(!is_script_scope()); |
| 1643 | 1676 |
| 1644 var = outer_scope_->LookupRecursive(proxy, outer_scope_end); | 1677 var = outer_scope_->LookupRecursive(proxy, outer_scope_end); |
| 1645 | 1678 |
| 1646 // The variable could not be resolved statically. | 1679 // The variable could not be resolved statically. |
| 1647 if (var == nullptr) return var; | 1680 if (var == nullptr) return var; |
| 1648 | 1681 |
| 1649 // TODO(marja): Separate LookupRecursive for preparsed scopes better. | 1682 // TODO(marja): Separate LookupRecursive for preparsed scopes better. |
| 1650 if (var == kDummyPreParserVariable) { | 1683 if (var == kDummyPreParserVariable || var == kDummyPreParserLexicalVariable) { |
| 1651 DCHECK(GetDeclarationScope()->is_being_lazily_parsed()); | 1684 DCHECK(GetDeclarationScope()->is_being_lazily_parsed()); |
| 1652 DCHECK(FLAG_lazy_inner_functions); | 1685 DCHECK(FLAG_lazy_inner_functions); |
| 1653 return var; | 1686 return var; |
| 1654 } | 1687 } |
| 1655 | 1688 |
| 1656 if (is_function_scope() && !var->is_dynamic()) { | 1689 if (is_function_scope() && !var->is_dynamic()) { |
| 1657 var->ForceContextAllocation(); | 1690 var->ForceContextAllocation(); |
| 1658 } | 1691 } |
| 1659 // "this" can't be shadowed by "eval"-introduced bindings or by "with" | 1692 // "this" can't be shadowed by "eval"-introduced bindings or by "with" |
| 1660 // scopes. | 1693 // scopes. |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1838 : this; | 1871 : this; |
| 1839 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; | 1872 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; |
| 1840 proxy = next) { | 1873 proxy = next) { |
| 1841 next = proxy->next_unresolved(); | 1874 next = proxy->next_unresolved(); |
| 1842 DCHECK(!proxy->is_resolved()); | 1875 DCHECK(!proxy->is_resolved()); |
| 1843 Variable* var = | 1876 Variable* var = |
| 1844 lookup->LookupRecursive(proxy, max_outer_scope->outer_scope()); | 1877 lookup->LookupRecursive(proxy, max_outer_scope->outer_scope()); |
| 1845 if (var == nullptr) { | 1878 if (var == nullptr) { |
| 1846 proxy->set_next_unresolved(stack); | 1879 proxy->set_next_unresolved(stack); |
| 1847 stack = proxy; | 1880 stack = proxy; |
| 1848 } else if (var != kDummyPreParserVariable) { | 1881 } else if (var != kDummyPreParserVariable && |
| 1882 var != kDummyPreParserLexicalVariable) { |
| 1849 if (info != nullptr) { | 1883 if (info != nullptr) { |
| 1850 // In this case we need to leave scopes in a way that they can be | 1884 // In this case we need to leave scopes in a way that they can be |
| 1851 // allocated. If we resolved variables from lazy parsed scopes, we need | 1885 // allocated. If we resolved variables from lazy parsed scopes, we need |
| 1852 // to context allocate the var. | 1886 // to context allocate the var. |
| 1853 ResolveTo(info, proxy, var); | 1887 ResolveTo(info, proxy, var); |
| 1854 if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation(); | 1888 if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation(); |
| 1855 } else { | 1889 } else { |
| 1856 var->set_is_used(); | 1890 var->set_is_used(); |
| 1857 } | 1891 } |
| 1858 } | 1892 } |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2134 Variable* function = | 2168 Variable* function = |
| 2135 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 2169 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
| 2136 bool is_function_var_in_context = | 2170 bool is_function_var_in_context = |
| 2137 function != nullptr && function->IsContextSlot(); | 2171 function != nullptr && function->IsContextSlot(); |
| 2138 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 2172 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 2139 (is_function_var_in_context ? 1 : 0); | 2173 (is_function_var_in_context ? 1 : 0); |
| 2140 } | 2174 } |
| 2141 | 2175 |
| 2142 } // namespace internal | 2176 } // namespace internal |
| 2143 } // namespace v8 | 2177 } // namespace v8 |
| OLD | NEW |