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 (factory) { |
547 var_created = true; | 548 DCHECK(!is_being_lazily_parsed_); |
548 if (factory) { | 549 if (created_variable == nullptr) { |
549 VariableProxy* proxy = | 550 VariableProxy* proxy = |
550 factory->NewVariableProxy(name, NORMAL_VARIABLE); | 551 factory->NewVariableProxy(name, NORMAL_VARIABLE); |
551 auto declaration = | 552 auto declaration = |
552 factory->NewVariableDeclaration(proxy, this, kNoSourcePosition); | 553 factory->NewVariableDeclaration(proxy, this, kNoSourcePosition); |
553 // Based on the preceding check, it doesn't matter what we pass as | 554 // Based on the preceding check, it doesn't matter what we pass as |
554 // allow_harmony_restrictive_generators and | 555 // allow_harmony_restrictive_generators and |
555 // sloppy_mode_block_scope_function_redefinition. | 556 // sloppy_mode_block_scope_function_redefinition. |
556 bool ok = true; | 557 bool ok = true; |
557 DeclareVariable(declaration, VAR, | 558 created_variable = DeclareVariable( |
558 Variable::DefaultInitializationFlag(VAR), false, | 559 declaration, VAR, Variable::DefaultInitializationFlag(VAR), false, |
559 nullptr, &ok); | 560 nullptr, &ok); |
560 CHECK(ok); // Based on the preceding check, this should not fail | 561 CHECK(ok); // Based on the preceding check, this should not fail |
561 } else { | |
562 DeclareVariableName(name, VAR); | |
563 } | 562 } |
564 } | |
565 | 563 |
566 if (factory) { | |
567 Expression* assignment = factory->NewAssignment( | 564 Expression* assignment = factory->NewAssignment( |
568 Token::ASSIGN, NewUnresolved(factory, name), | 565 Token::ASSIGN, NewUnresolved(factory, name), |
569 delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition); | 566 delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition); |
570 Statement* statement = | 567 Statement* statement = |
571 factory->NewExpressionStatement(assignment, kNoSourcePosition); | 568 factory->NewExpressionStatement(assignment, kNoSourcePosition); |
572 delegate->set_statement(statement); | 569 delegate->set_statement(statement); |
570 } else { | |
571 DCHECK(is_being_lazily_parsed_); | |
572 if (created_variable == nullptr) { | |
573 created_variable = DeclareVariableName(name, VAR); | |
574 if (created_variable != kDummyPreParserVariable && | |
vogelheim
2017/02/03 18:33:25
In the previous version, this check always happene
marja
2017/02/03 21:03:54
Yeah, we don't need to set_maybe_assigned on the s
| |
575 created_variable != kDummyPreParserLexicalVariable) { | |
576 DCHECK(FLAG_preparser_scope_analysis); | |
577 created_variable->set_maybe_assigned(); | |
578 } | |
579 } | |
573 } | 580 } |
574 } | 581 } |
575 } | 582 } |
576 } | 583 } |
577 | 584 |
578 void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) { | 585 void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) { |
579 RuntimeCallTimerScope runtimeTimer(info->isolate(), | 586 RuntimeCallTimerScope runtimeTimer(info->isolate(), |
580 &RuntimeCallStats::CompileScopeAnalysis); | 587 &RuntimeCallStats::CompileScopeAnalysis); |
581 DCHECK(info->literal() != NULL); | 588 DCHECK(info->literal() != NULL); |
582 DeclarationScope* scope = info->literal()->scope(); | 589 DeclarationScope* scope = info->literal()->scope(); |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1056 // | 1063 // |
1057 // This will lead to multiple declaration nodes for the | 1064 // This will lead to multiple declaration nodes for the |
1058 // same variable if it is declared several times. This is not a | 1065 // 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 | 1066 // semantic issue, but it may be a performance issue since it may |
1060 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls. | 1067 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls. |
1061 decls_.Add(declaration); | 1068 decls_.Add(declaration); |
1062 proxy->BindTo(var); | 1069 proxy->BindTo(var); |
1063 return var; | 1070 return var; |
1064 } | 1071 } |
1065 | 1072 |
1066 void Scope::DeclareVariableName(const AstRawString* name, VariableMode mode) { | 1073 Variable* Scope::DeclareVariableName(const AstRawString* name, |
1074 VariableMode mode) { | |
1067 DCHECK(IsDeclaredVariableMode(mode)); | 1075 DCHECK(IsDeclaredVariableMode(mode)); |
1068 DCHECK(!already_resolved_); | 1076 DCHECK(!already_resolved_); |
1069 DCHECK(GetDeclarationScope()->is_being_lazily_parsed()); | 1077 DCHECK(GetDeclarationScope()->is_being_lazily_parsed()); |
1070 | 1078 |
1071 if (mode == VAR && !is_declaration_scope()) { | 1079 if (mode == VAR && !is_declaration_scope()) { |
1072 return GetDeclarationScope()->DeclareVariableName(name, mode); | 1080 return GetDeclarationScope()->DeclareVariableName(name, mode); |
1073 } | 1081 } |
1074 DCHECK(!is_with_scope()); | 1082 DCHECK(!is_with_scope()); |
1075 DCHECK(!is_eval_scope()); | 1083 DCHECK(!is_eval_scope()); |
1076 // Unlike DeclareVariable, DeclareVariableName allows declaring variables in | 1084 // Unlike DeclareVariable, DeclareVariableName allows declaring variables in |
(...skipping 10 matching lines...) Expand all Loading... | |
1087 DCHECK_NE(var, kDummyPreParserLexicalVariable); | 1095 DCHECK_NE(var, kDummyPreParserLexicalVariable); |
1088 DCHECK_NE(var, kDummyPreParserVariable); | 1096 DCHECK_NE(var, kDummyPreParserVariable); |
1089 if (var == nullptr) { | 1097 if (var == nullptr) { |
1090 var = DeclareLocal(name, mode); | 1098 var = DeclareLocal(name, mode); |
1091 } else if (!IsLexicalVariableMode(var->mode()) && | 1099 } else if (!IsLexicalVariableMode(var->mode()) && |
1092 !IsLexicalVariableMode(mode)) { | 1100 !IsLexicalVariableMode(mode)) { |
1093 DCHECK_EQ(mode, VAR); | 1101 DCHECK_EQ(mode, VAR); |
1094 var->set_maybe_assigned(); | 1102 var->set_maybe_assigned(); |
1095 } | 1103 } |
1096 var->set_is_used(); | 1104 var->set_is_used(); |
1105 return var; | |
1097 } else { | 1106 } else { |
1098 variables_.DeclareName(zone(), name, mode); | 1107 return variables_.DeclareName(zone(), name, mode); |
1099 } | 1108 } |
1100 } | 1109 } |
1101 | 1110 |
1102 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, | 1111 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, |
1103 const AstRawString* name, | 1112 const AstRawString* name, |
1104 int start_position, VariableKind kind) { | 1113 int start_position, VariableKind kind) { |
1105 // Note that we must not share the unresolved variables with | 1114 // Note that we must not share the unresolved variables with |
1106 // the same name because they may be removed selectively via | 1115 // the same name because they may be removed selectively via |
1107 // RemoveUnresolved(). | 1116 // RemoveUnresolved(). |
1108 DCHECK(!already_resolved_); | 1117 DCHECK(!already_resolved_); |
(...skipping 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2222 Variable* function = | 2231 Variable* function = |
2223 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 2232 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
2224 bool is_function_var_in_context = | 2233 bool is_function_var_in_context = |
2225 function != nullptr && function->IsContextSlot(); | 2234 function != nullptr && function->IsContextSlot(); |
2226 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 2235 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
2227 (is_function_var_in_context ? 1 : 0); | 2236 (is_function_var_in_context ? 1 : 0); |
2228 } | 2237 } |
2229 | 2238 |
2230 } // namespace internal | 2239 } // namespace internal |
2231 } // namespace v8 | 2240 } // namespace v8 |
OLD | NEW |