Chromium Code Reviews| 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" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 if (added) *added = p->value == nullptr; | 59 if (added) *added = p->value == nullptr; |
| 60 if (p->value == nullptr) { | 60 if (p->value == nullptr) { |
| 61 // The variable has not been declared yet -> insert it. | 61 // The variable has not been declared yet -> insert it. |
| 62 DCHECK_EQ(name, p->key); | 62 DCHECK_EQ(name, p->key); |
| 63 p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag, | 63 p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag, |
| 64 maybe_assigned_flag); | 64 maybe_assigned_flag); |
| 65 } | 65 } |
| 66 return reinterpret_cast<Variable*>(p->value); | 66 return reinterpret_cast<Variable*>(p->value); |
| 67 } | 67 } |
| 68 | 68 |
| 69 void VariableMap::DeclareName(Zone* zone, const AstRawString* name, | 69 Variable* VariableMap::DeclareName(Zone* zone, const AstRawString* name, |
| 70 VariableMode mode) { | 70 VariableMode mode) { |
| 71 Entry* p = | 71 Entry* p = |
| 72 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), | 72 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
| 73 ZoneAllocationPolicy(zone)); | 73 ZoneAllocationPolicy(zone)); |
| 74 if (p->value == nullptr) { | 74 if (p->value == nullptr) { |
| 75 // The variable has not been declared yet -> insert it. | 75 // The variable has not been declared yet -> insert it. |
| 76 DCHECK_EQ(name, p->key); | 76 DCHECK_EQ(name, p->key); |
| 77 p->value = | 77 p->value = |
| 78 mode == VAR ? kDummyPreParserVariable : kDummyPreParserLexicalVariable; | 78 mode == VAR ? kDummyPreParserVariable : kDummyPreParserLexicalVariable; |
| 79 } | 79 } |
| 80 return reinterpret_cast<Variable*>(p->value); | |
| 80 } | 81 } |
| 81 | 82 |
| 82 void VariableMap::Remove(Variable* var) { | 83 void VariableMap::Remove(Variable* var) { |
| 83 const AstRawString* name = var->raw_name(); | 84 const AstRawString* name = var->raw_name(); |
| 84 ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash()); | 85 ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash()); |
| 85 } | 86 } |
| 86 | 87 |
| 87 void VariableMap::Add(Zone* zone, Variable* var) { | 88 void VariableMap::Add(Zone* zone, Variable* var) { |
| 88 const AstRawString* name = var->raw_name(); | 89 const AstRawString* name = var->raw_name(); |
| 89 Entry* p = | 90 Entry* p = |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 501 if (!has_simple_parameters) { | 502 if (!has_simple_parameters) { |
| 502 if (outer_scope_->LookupLocal(name) != nullptr) { | 503 if (outer_scope_->LookupLocal(name) != nullptr) { |
| 503 continue; | 504 continue; |
| 504 } | 505 } |
| 505 } else { | 506 } else { |
| 506 if (IsDeclaredParameter(name)) { | 507 if (IsDeclaredParameter(name)) { |
| 507 continue; | 508 continue; |
| 508 } | 509 } |
| 509 } | 510 } |
| 510 | 511 |
| 511 bool var_created = false; | 512 Variable* created_variable = nullptr; |
| 512 | 513 |
| 513 // Write in assignments to var for each block-scoped function declaration | 514 // Write in assignments to var for each block-scoped function declaration |
| 514 auto delegates = static_cast<SloppyBlockFunctionMap::Delegate*>(p->value); | 515 auto delegates = static_cast<SloppyBlockFunctionMap::Delegate*>(p->value); |
| 515 | 516 |
| 516 DeclarationScope* decl_scope = this; | 517 DeclarationScope* decl_scope = this; |
| 517 while (decl_scope->is_eval_scope()) { | 518 while (decl_scope->is_eval_scope()) { |
| 518 decl_scope = decl_scope->outer_scope()->GetDeclarationScope(); | 519 decl_scope = decl_scope->outer_scope()->GetDeclarationScope(); |
| 519 } | 520 } |
| 520 Scope* outer_scope = decl_scope->outer_scope(); | 521 Scope* outer_scope = decl_scope->outer_scope(); |
| 521 | 522 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 536 if (var != nullptr && IsLexical(var)) { | 537 if (var != nullptr && IsLexical(var)) { |
| 537 should_hoist = false; | 538 should_hoist = false; |
| 538 break; | 539 break; |
| 539 } | 540 } |
| 540 query_scope = query_scope->outer_scope(); | 541 query_scope = query_scope->outer_scope(); |
| 541 } while (query_scope != outer_scope); | 542 } while (query_scope != outer_scope); |
| 542 | 543 |
| 543 if (!should_hoist) continue; | 544 if (!should_hoist) continue; |
| 544 | 545 |
| 545 // Declare a var-style binding for the function in the outer scope | 546 // Declare a var-style binding for the function in the outer scope |
| 546 if (!var_created) { | 547 if (created_variable == nullptr) { |
| 547 var_created = true; | |
| 548 if (factory) { | 548 if (factory) { |
| 549 VariableProxy* proxy = | 549 VariableProxy* proxy = |
| 550 factory->NewVariableProxy(name, NORMAL_VARIABLE); | 550 factory->NewVariableProxy(name, NORMAL_VARIABLE); |
| 551 auto declaration = | 551 auto declaration = |
| 552 factory->NewVariableDeclaration(proxy, this, kNoSourcePosition); | 552 factory->NewVariableDeclaration(proxy, this, kNoSourcePosition); |
| 553 // Based on the preceding check, it doesn't matter what we pass as | 553 // Based on the preceding check, it doesn't matter what we pass as |
| 554 // allow_harmony_restrictive_generators and | 554 // allow_harmony_restrictive_generators and |
| 555 // sloppy_mode_block_scope_function_redefinition. | 555 // sloppy_mode_block_scope_function_redefinition. |
| 556 bool ok = true; | 556 bool ok = true; |
| 557 DeclareVariable(declaration, VAR, | 557 created_variable = DeclareVariable( |
| 558 Variable::DefaultInitializationFlag(VAR), false, | 558 declaration, VAR, Variable::DefaultInitializationFlag(VAR), false, |
| 559 nullptr, &ok); | 559 nullptr, &ok); |
| 560 CHECK(ok); // Based on the preceding check, this should not fail | 560 CHECK(ok); // Based on the preceding check, this should not fail |
| 561 } else { | 561 } else { |
| 562 DeclareVariableName(name, VAR); | 562 created_variable = DeclareVariableName(name, VAR); |
| 563 } | 563 } |
| 564 } | 564 } |
| 565 | 565 |
| 566 if (factory) { | 566 if (factory) { |
| 567 Expression* assignment = factory->NewAssignment( | 567 Expression* assignment = factory->NewAssignment( |
| 568 Token::ASSIGN, NewUnresolved(factory, name), | 568 Token::ASSIGN, NewUnresolved(factory, name), |
| 569 delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition); | 569 delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition); |
| 570 Statement* statement = | 570 Statement* statement = |
| 571 factory->NewExpressionStatement(assignment, kNoSourcePosition); | 571 factory->NewExpressionStatement(assignment, kNoSourcePosition); |
| 572 delegate->set_statement(statement); | 572 delegate->set_statement(statement); |
| 573 } else if (created_variable != kDummyPreParserVariable && | |
| 574 created_variable != kDummyPreParserLexicalVariable) { | |
| 575 created_variable->set_maybe_assigned(); | |
|
marja
2017/02/02 11:56:17
The Variable passing is needed to be able to do th
vogelheim
2017/02/02 19:00:42
I can't parse that sentence. Care to explain?
marja
2017/02/03 21:03:01
I need to return Variable* and transmit it up unti
| |
| 573 } | 576 } |
|
vogelheim
2017/02/02 19:00:42
I don't really understand what this whole block do
marja
2017/02/03 21:03:01
This creates the assignmentstatement which assigns
| |
| 574 } | 577 } |
| 575 } | 578 } |
| 576 } | 579 } |
| 577 | 580 |
| 578 void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) { | 581 void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) { |
| 579 RuntimeCallTimerScope runtimeTimer(info->isolate(), | 582 RuntimeCallTimerScope runtimeTimer(info->isolate(), |
| 580 &RuntimeCallStats::CompileScopeAnalysis); | 583 &RuntimeCallStats::CompileScopeAnalysis); |
| 581 DCHECK(info->literal() != NULL); | 584 DCHECK(info->literal() != NULL); |
| 582 DeclarationScope* scope = info->literal()->scope(); | 585 DeclarationScope* scope = info->literal()->scope(); |
| 583 | 586 |
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1056 // | 1059 // |
| 1057 // This will lead to multiple declaration nodes for the | 1060 // This will lead to multiple declaration nodes for the |
| 1058 // same variable if it is declared several times. This is not a | 1061 // same variable if it is declared several times. This is not a |
| 1059 // semantic issue, but it may be a performance issue since it may | 1062 // semantic issue, but it may be a performance issue since it may |
| 1060 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls. | 1063 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls. |
| 1061 decls_.Add(declaration); | 1064 decls_.Add(declaration); |
| 1062 proxy->BindTo(var); | 1065 proxy->BindTo(var); |
| 1063 return var; | 1066 return var; |
| 1064 } | 1067 } |
| 1065 | 1068 |
| 1066 void Scope::DeclareVariableName(const AstRawString* name, VariableMode mode) { | 1069 Variable* Scope::DeclareVariableName(const AstRawString* name, |
| 1070 VariableMode mode) { | |
| 1067 DCHECK(IsDeclaredVariableMode(mode)); | 1071 DCHECK(IsDeclaredVariableMode(mode)); |
| 1068 DCHECK(!already_resolved_); | 1072 DCHECK(!already_resolved_); |
| 1069 DCHECK(GetDeclarationScope()->is_being_lazily_parsed()); | 1073 DCHECK(GetDeclarationScope()->is_being_lazily_parsed()); |
| 1070 | 1074 |
| 1071 if (mode == VAR && !is_declaration_scope()) { | 1075 if (mode == VAR && !is_declaration_scope()) { |
| 1072 return GetDeclarationScope()->DeclareVariableName(name, mode); | 1076 return GetDeclarationScope()->DeclareVariableName(name, mode); |
| 1073 } | 1077 } |
| 1074 DCHECK(!is_with_scope()); | 1078 DCHECK(!is_with_scope()); |
| 1075 DCHECK(!is_eval_scope()); | 1079 DCHECK(!is_eval_scope()); |
| 1076 // Unlike DeclareVariable, DeclareVariableName allows declaring variables in | 1080 // Unlike DeclareVariable, DeclareVariableName allows declaring variables in |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1087 DCHECK_NE(var, kDummyPreParserLexicalVariable); | 1091 DCHECK_NE(var, kDummyPreParserLexicalVariable); |
| 1088 DCHECK_NE(var, kDummyPreParserVariable); | 1092 DCHECK_NE(var, kDummyPreParserVariable); |
| 1089 if (var == nullptr) { | 1093 if (var == nullptr) { |
| 1090 var = DeclareLocal(name, mode); | 1094 var = DeclareLocal(name, mode); |
| 1091 } else if (!IsLexicalVariableMode(var->mode()) && | 1095 } else if (!IsLexicalVariableMode(var->mode()) && |
| 1092 !IsLexicalVariableMode(mode)) { | 1096 !IsLexicalVariableMode(mode)) { |
| 1093 DCHECK_EQ(mode, VAR); | 1097 DCHECK_EQ(mode, VAR); |
| 1094 var->set_maybe_assigned(); | 1098 var->set_maybe_assigned(); |
| 1095 } | 1099 } |
| 1096 var->set_is_used(); | 1100 var->set_is_used(); |
| 1101 return var; | |
| 1097 } else { | 1102 } else { |
| 1098 variables_.DeclareName(zone(), name, mode); | 1103 return variables_.DeclareName(zone(), name, mode); |
| 1099 } | 1104 } |
| 1100 } | 1105 } |
| 1101 | 1106 |
| 1102 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, | 1107 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, |
| 1103 const AstRawString* name, | 1108 const AstRawString* name, |
| 1104 int start_position, VariableKind kind) { | 1109 int start_position, VariableKind kind) { |
| 1105 // Note that we must not share the unresolved variables with | 1110 // Note that we must not share the unresolved variables with |
| 1106 // the same name because they may be removed selectively via | 1111 // the same name because they may be removed selectively via |
| 1107 // RemoveUnresolved(). | 1112 // RemoveUnresolved(). |
| 1108 DCHECK(!already_resolved_); | 1113 DCHECK(!already_resolved_); |
| (...skipping 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2222 Variable* function = | 2227 Variable* function = |
| 2223 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 2228 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
| 2224 bool is_function_var_in_context = | 2229 bool is_function_var_in_context = |
| 2225 function != nullptr && function->IsContextSlot(); | 2230 function != nullptr && function->IsContextSlot(); |
| 2226 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 2231 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 2227 (is_function_var_in_context ? 1 : 0); | 2232 (is_function_var_in_context ? 1 : 0); |
| 2228 } | 2233 } |
| 2229 | 2234 |
| 2230 } // namespace internal | 2235 } // namespace internal |
| 2231 } // namespace v8 | 2236 } // namespace v8 |
| OLD | NEW |