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 |