Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: src/ast/scopes.cc

Issue 2670633003: [parser] Skipping inner funcs: produce the same scopes / variables for sloppy block funcs. (Closed)
Patch Set: code review (vogelheim@) Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ast/scopes.h ('k') | src/parsing/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | src/parsing/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698