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 #ifndef V8_AST_SCOPES_H_ | 5 #ifndef V8_AST_SCOPES_H_ |
6 #define V8_AST_SCOPES_H_ | 6 #define V8_AST_SCOPES_H_ |
7 | 7 |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/base/hashmap.h" | 9 #include "src/base/hashmap.h" |
10 #include "src/globals.h" | 10 #include "src/globals.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 | 77 |
78 // Global invariants after AST construction: Each reference (i.e. identifier) | 78 // Global invariants after AST construction: Each reference (i.e. identifier) |
79 // to a JavaScript variable (including global properties) is represented by a | 79 // to a JavaScript variable (including global properties) is represented by a |
80 // VariableProxy node. Immediately after AST construction and before variable | 80 // VariableProxy node. Immediately after AST construction and before variable |
81 // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a | 81 // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a |
82 // corresponding variable (though some are bound during parse time). Variable | 82 // corresponding variable (though some are bound during parse time). Variable |
83 // allocation binds each unresolved VariableProxy to one Variable and assigns | 83 // allocation binds each unresolved VariableProxy to one Variable and assigns |
84 // a location. Note that many VariableProxy nodes may refer to the same Java- | 84 // a location. Note that many VariableProxy nodes may refer to the same Java- |
85 // Script variable. | 85 // Script variable. |
86 | 86 |
87 class DeclarationScope; | |
88 | |
89 // JS environments are represented in the parser using two scope classes, Scope | |
90 // and its subclass DeclarationScope. DeclarationScope is used for any scope | |
91 // that hosts 'var' declarations. This includes script, module, eval, varblock, | |
92 // and function scope. All fields required by such scopes are only available on | |
93 // DeclarationScope. | |
94 class Scope: public ZoneObject { | 87 class Scope: public ZoneObject { |
95 public: | 88 public: |
96 // --------------------------------------------------------------------------- | 89 // --------------------------------------------------------------------------- |
97 // Construction | 90 // Construction |
98 | 91 |
99 Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type); | 92 Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, |
100 | 93 FunctionKind function_kind = kNormalFunction); |
101 #ifdef DEBUG | |
102 // The scope name is only used for printing/debugging. | |
103 void SetScopeName(const AstRawString* scope_name) { | |
104 scope_name_ = scope_name; | |
105 } | |
106 #endif | |
107 | |
108 // TODO(verwaest): Is this needed on Scope? | |
109 int num_parameters() const; | |
110 | |
111 DeclarationScope* AsDeclarationScope(); | |
112 const DeclarationScope* AsDeclarationScope() const; | |
113 | 94 |
114 class Snapshot final BASE_EMBEDDED { | 95 class Snapshot final BASE_EMBEDDED { |
115 public: | 96 public: |
116 explicit Snapshot(Scope* scope); | 97 explicit Snapshot(Scope* scope) |
| 98 : outer_scope_(scope), |
| 99 top_inner_scope_(scope->inner_scope_), |
| 100 top_unresolved_(scope->unresolved_), |
| 101 top_temp_(scope->ClosureScope()->temps_.length()) {} |
117 | 102 |
118 void Reparent(DeclarationScope* new_parent) const; | 103 void Reparent(Scope* new_parent) const; |
119 | 104 |
120 private: | 105 private: |
121 Scope* outer_scope_; | 106 Scope* outer_scope_; |
122 Scope* top_inner_scope_; | 107 Scope* top_inner_scope_; |
123 VariableProxy* top_unresolved_; | 108 VariableProxy* top_unresolved_; |
124 int top_temp_; | 109 int top_temp_; |
125 }; | 110 }; |
126 | 111 |
127 // Compute top scope and allocate variables. For lazy compilation the top | 112 // Compute top scope and allocate variables. For lazy compilation the top |
128 // scope only contains the single lazily compiled function, so this | 113 // scope only contains the single lazily compiled function, so this |
129 // doesn't re-allocate variables repeatedly. | 114 // doesn't re-allocate variables repeatedly. |
130 static bool Analyze(ParseInfo* info); | 115 static bool Analyze(ParseInfo* info); |
131 | 116 |
132 enum class DeserializationMode { kDeserializeOffHeap, kKeepScopeInfo }; | 117 enum class DeserializationMode { kDeserializeOffHeap, kKeepScopeInfo }; |
133 | 118 |
134 static Scope* DeserializeScopeChain(Isolate* isolate, Zone* zone, | 119 static Scope* DeserializeScopeChain(Isolate* isolate, Zone* zone, |
135 Context* context, Scope* script_scope, | 120 Context* context, Scope* script_scope, |
136 AstValueFactory* ast_value_factory, | 121 AstValueFactory* ast_value_factory, |
137 DeserializationMode deserialization_mode); | 122 DeserializationMode deserialization_mode); |
138 | 123 |
| 124 #ifdef DEBUG |
| 125 // The scope name is only used for printing/debugging. |
| 126 void SetScopeName(const AstRawString* scope_name) { |
| 127 scope_name_ = scope_name; |
| 128 } |
| 129 #endif |
| 130 |
| 131 void DeclareThis(AstValueFactory* ast_value_factory); |
| 132 void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory); |
| 133 |
139 // Checks if the block scope is redundant, i.e. it does not contain any | 134 // Checks if the block scope is redundant, i.e. it does not contain any |
140 // block scoped declarations. In that case it is removed from the scope | 135 // block scoped declarations. In that case it is removed from the scope |
141 // tree and its children are reparented. | 136 // tree and its children are reparented. |
142 Scope* FinalizeBlockScope(); | 137 Scope* FinalizeBlockScope(); |
143 | 138 |
144 // Inserts outer_scope into this scope's scope chain (and removes this | 139 // Inserts outer_scope into this scope's scope chain (and removes this |
145 // from the current outer_scope_'s inner scope list). | 140 // from the current outer_scope_'s inner scope list). |
146 // Assumes outer_scope_ is non-null. | 141 // Assumes outer_scope_ is non-null. |
147 void ReplaceOuterScope(Scope* outer_scope); | 142 void ReplaceOuterScope(Scope* outer_scope); |
148 | 143 |
149 // Propagates any eagerly-gathered scope usage flags (such as calls_eval()) | 144 // Propagates any eagerly-gathered scope usage flags (such as calls_eval()) |
150 // to the passed-in scope. | 145 // to the passed-in scope. |
151 void PropagateUsageFlagsToScope(Scope* other); | 146 void PropagateUsageFlagsToScope(Scope* other); |
152 | 147 |
153 Zone* zone() const { return variables_.zone(); } | 148 Zone* zone() const { return variables_.zone(); } |
154 | 149 |
155 // --------------------------------------------------------------------------- | 150 // --------------------------------------------------------------------------- |
156 // Declarations | 151 // Declarations |
157 | 152 |
158 // Lookup a variable in this scope. Returns the variable or NULL if not found. | 153 // Lookup a variable in this scope. Returns the variable or NULL if not found. |
159 Variable* LookupLocal(const AstRawString* name); | 154 Variable* LookupLocal(const AstRawString* name); |
160 | 155 |
| 156 // This lookup corresponds to a lookup in the "intermediate" scope sitting |
| 157 // between this scope and the outer scope. (ECMA-262, 3rd., requires that |
| 158 // the name of named function literal is kept in an intermediate scope |
| 159 // in between this scope and the next outer scope.) |
| 160 Variable* LookupFunctionVar(const AstRawString* name, |
| 161 AstNodeFactory* factory); |
| 162 |
161 // Lookup a variable in this scope or outer scopes. | 163 // Lookup a variable in this scope or outer scopes. |
162 // Returns the variable or NULL if not found. | 164 // Returns the variable or NULL if not found. |
163 Variable* Lookup(const AstRawString* name); | 165 Variable* Lookup(const AstRawString* name); |
164 | 166 |
| 167 // Declare the function variable for a function literal. This variable |
| 168 // is in an intermediate scope between this function scope and the the |
| 169 // outer scope. Only possible for function scopes; at most one variable. |
| 170 void DeclareFunctionVar(VariableDeclaration* declaration) { |
| 171 DCHECK(is_function_scope()); |
| 172 // Handle implicit declaration of the function name in named function |
| 173 // expressions before other declarations. |
| 174 decls_.InsertAt(0, declaration, zone()); |
| 175 function_ = declaration; |
| 176 } |
| 177 |
| 178 // Declare a parameter in this scope. When there are duplicated |
| 179 // parameters the rightmost one 'wins'. However, the implementation |
| 180 // expects all parameters to be declared and from left to right. |
| 181 Variable* DeclareParameter(const AstRawString* name, VariableMode mode, |
| 182 bool is_optional, bool is_rest, bool* is_duplicate, |
| 183 AstValueFactory* ast_value_factory); |
| 184 |
165 // Declare a local variable in this scope. If the variable has been | 185 // Declare a local variable in this scope. If the variable has been |
166 // declared before, the previously declared variable is returned. | 186 // declared before, the previously declared variable is returned. |
167 Variable* DeclareLocal(const AstRawString* name, VariableMode mode, | 187 Variable* DeclareLocal(const AstRawString* name, VariableMode mode, |
168 InitializationFlag init_flag, Variable::Kind kind, | 188 InitializationFlag init_flag, Variable::Kind kind, |
169 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned); | 189 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned); |
170 | 190 |
171 // Declarations list. | 191 // Declare an implicit global variable in this scope which must be a |
172 ZoneList<Declaration*>* declarations() { return &decls_; } | 192 // script scope. The variable was introduced (possibly from an inner |
| 193 // scope) by a reference to an unresolved variable with no intervening |
| 194 // with statements or eval calls. |
| 195 Variable* DeclareDynamicGlobal(const AstRawString* name); |
173 | 196 |
174 // Create a new unresolved variable. | 197 // Create a new unresolved variable. |
175 VariableProxy* NewUnresolved(AstNodeFactory* factory, | 198 VariableProxy* NewUnresolved(AstNodeFactory* factory, |
176 const AstRawString* name, | 199 const AstRawString* name, |
177 Variable::Kind kind = Variable::NORMAL, | 200 Variable::Kind kind = Variable::NORMAL, |
178 int start_position = kNoSourcePosition, | 201 int start_position = kNoSourcePosition, |
179 int end_position = kNoSourcePosition) { | 202 int end_position = kNoSourcePosition) { |
180 // Note that we must not share the unresolved variables with | 203 // Note that we must not share the unresolved variables with |
181 // the same name because they may be removed selectively via | 204 // the same name because they may be removed selectively via |
182 // RemoveUnresolved(). | 205 // RemoveUnresolved(). |
(...skipping 19 matching lines...) Expand all Loading... |
202 // addition introduced a new unresolved variable which may end up being | 225 // addition introduced a new unresolved variable which may end up being |
203 // allocated globally as a "ghost" variable. RemoveUnresolved removes | 226 // allocated globally as a "ghost" variable. RemoveUnresolved removes |
204 // such a variable again if it was added; otherwise this is a no-op. | 227 // such a variable again if it was added; otherwise this is a no-op. |
205 bool RemoveUnresolved(VariableProxy* var); | 228 bool RemoveUnresolved(VariableProxy* var); |
206 | 229 |
207 // Creates a new temporary variable in this scope's TemporaryScope. The | 230 // Creates a new temporary variable in this scope's TemporaryScope. The |
208 // name is only used for printing and cannot be used to find the variable. | 231 // name is only used for printing and cannot be used to find the variable. |
209 // In particular, the only way to get hold of the temporary is by keeping the | 232 // In particular, the only way to get hold of the temporary is by keeping the |
210 // Variable* around. The name should not clash with a legitimate variable | 233 // Variable* around. The name should not clash with a legitimate variable |
211 // names. | 234 // names. |
212 // TODO(verwaest): Move to DeclarationScope? | |
213 Variable* NewTemporary(const AstRawString* name); | 235 Variable* NewTemporary(const AstRawString* name); |
214 | 236 |
| 237 // Remove a temporary variable. This is for adjusting the scope of |
| 238 // temporaries used when desugaring parameter initializers. |
| 239 // Returns the index at which it was found in this scope, or -1 if |
| 240 // it was not found. |
| 241 int RemoveTemporary(Variable* var); |
| 242 |
| 243 // Adds a temporary variable in this scope's TemporaryScope. This is for |
| 244 // adjusting the scope of temporaries used when desugaring parameter |
| 245 // initializers. |
| 246 void AddTemporary(Variable* var) { |
| 247 // Temporaries are only placed in ClosureScopes. |
| 248 DCHECK_EQ(ClosureScope(), this); |
| 249 temps_.Add(var, zone()); |
| 250 } |
| 251 |
215 // Adds the specific declaration node to the list of declarations in | 252 // Adds the specific declaration node to the list of declarations in |
216 // this scope. The declarations are processed as part of entering | 253 // this scope. The declarations are processed as part of entering |
217 // the scope; see codegen.cc:ProcessDeclarations. | 254 // the scope; see codegen.cc:ProcessDeclarations. |
218 void AddDeclaration(Declaration* declaration); | 255 void AddDeclaration(Declaration* declaration); |
219 | 256 |
220 // --------------------------------------------------------------------------- | 257 // --------------------------------------------------------------------------- |
221 // Illegal redeclaration support. | 258 // Illegal redeclaration support. |
222 | 259 |
223 // Check if the scope has conflicting var | 260 // Check if the scope has conflicting var |
224 // declarations, i.e. a var declaration that has been hoisted from a nested | 261 // declarations, i.e. a var declaration that has been hoisted from a nested |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 // Predicates. | 351 // Predicates. |
315 | 352 |
316 // Specific scope types. | 353 // Specific scope types. |
317 bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; } | 354 bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; } |
318 bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; } | 355 bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; } |
319 bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; } | 356 bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; } |
320 bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; } | 357 bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; } |
321 bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; } | 358 bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; } |
322 bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; } | 359 bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; } |
323 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; } | 360 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; } |
| 361 bool is_arrow_scope() const { |
| 362 return is_function_scope() && IsArrowFunction(function_kind_); |
| 363 } |
324 bool is_declaration_scope() const { return is_declaration_scope_; } | 364 bool is_declaration_scope() const { return is_declaration_scope_; } |
325 | 365 |
| 366 void set_is_declaration_scope() { is_declaration_scope_ = true; } |
| 367 |
326 // Information about which scopes calls eval. | 368 // Information about which scopes calls eval. |
327 bool calls_eval() const { return scope_calls_eval_; } | 369 bool calls_eval() const { return scope_calls_eval_; } |
328 bool calls_sloppy_eval() const { | 370 bool calls_sloppy_eval() const { |
329 return scope_calls_eval_ && is_sloppy(language_mode_); | 371 return scope_calls_eval_ && is_sloppy(language_mode_); |
330 } | 372 } |
331 bool outer_scope_calls_sloppy_eval() const { | 373 bool outer_scope_calls_sloppy_eval() const { |
332 return outer_scope_calls_sloppy_eval_; | 374 return outer_scope_calls_sloppy_eval_; |
333 } | 375 } |
334 bool asm_module() const { return asm_module_; } | 376 bool asm_module() const { return asm_module_; } |
335 bool asm_function() const { return asm_function_; } | 377 bool asm_function() const { return asm_function_; } |
336 | 378 |
337 // Is this scope inside a with statement. | 379 // Is this scope inside a with statement. |
338 bool inside_with() const { return scope_inside_with_; } | 380 bool inside_with() const { return scope_inside_with_; } |
339 | 381 |
340 // Does this scope access "super" property (super.foo). | 382 // Does this scope access "super" property (super.foo). |
341 bool uses_super_property() const { return scope_uses_super_property_; } | 383 bool uses_super_property() const { return scope_uses_super_property_; } |
342 // Does this scope have the potential to execute declarations non-linearly? | 384 // Does this scope have the potential to execute declarations non-linearly? |
343 bool is_nonlinear() const { return scope_nonlinear_; } | 385 bool is_nonlinear() const { return scope_nonlinear_; } |
344 | 386 |
345 // Whether this needs to be represented by a runtime context. | 387 // Whether this needs to be represented by a runtime context. |
346 bool NeedsContext() const { | 388 bool NeedsContext() const { |
347 // Catch and module scopes always have heap slots. | 389 // Catch and module scopes always have heap slots. |
348 DCHECK(!is_catch_scope() || num_heap_slots() > 0); | 390 DCHECK(!is_catch_scope() || num_heap_slots() > 0); |
349 DCHECK(!is_module_scope() || num_heap_slots() > 0); | 391 DCHECK(!is_module_scope() || num_heap_slots() > 0); |
350 return is_with_scope() || num_heap_slots() > 0; | 392 return is_with_scope() || num_heap_slots() > 0; |
351 } | 393 } |
352 | 394 |
| 395 bool NeedsHomeObject() const { |
| 396 return scope_uses_super_property_ || |
| 397 ((scope_calls_eval_ || inner_scope_calls_eval_) && |
| 398 (IsConciseMethod(function_kind()) || |
| 399 IsAccessorFunction(function_kind()) || |
| 400 IsClassConstructor(function_kind()))); |
| 401 } |
| 402 |
353 // --------------------------------------------------------------------------- | 403 // --------------------------------------------------------------------------- |
354 // Accessors. | 404 // Accessors. |
355 | 405 |
356 // The type of this scope. | 406 // The type of this scope. |
357 ScopeType scope_type() const { return scope_type_; } | 407 ScopeType scope_type() const { return scope_type_; } |
358 | 408 |
| 409 FunctionKind function_kind() const { return function_kind_; } |
| 410 |
359 // The language mode of this scope. | 411 // The language mode of this scope. |
360 LanguageMode language_mode() const { return language_mode_; } | 412 LanguageMode language_mode() const { return language_mode_; } |
361 | 413 |
| 414 // The variable corresponding to the 'this' value. |
| 415 Variable* receiver() { |
| 416 DCHECK(has_this_declaration()); |
| 417 DCHECK_NOT_NULL(receiver_); |
| 418 return receiver_; |
| 419 } |
| 420 |
| 421 // TODO(wingo): Add a GLOBAL_SCOPE scope type which will lexically allocate |
| 422 // "this" (and no other variable) on the native context. Script scopes then |
| 423 // will not have a "this" declaration. |
| 424 bool has_this_declaration() const { |
| 425 return (is_function_scope() && !is_arrow_scope()) || is_module_scope(); |
| 426 } |
| 427 |
| 428 // The variable corresponding to the 'new.target' value. |
| 429 Variable* new_target_var() { return new_target_; } |
| 430 |
| 431 // The variable holding the function literal for named function |
| 432 // literals, or NULL. Only valid for function scopes. |
| 433 VariableDeclaration* function() const { |
| 434 DCHECK(is_function_scope()); |
| 435 return function_; |
| 436 } |
| 437 |
| 438 // Parameters. The left-most parameter has index 0. |
| 439 // Only valid for function scopes. |
| 440 Variable* parameter(int index) const { |
| 441 DCHECK(is_function_scope()); |
| 442 return params_[index]; |
| 443 } |
| 444 |
| 445 // Returns the default function arity excluding default or rest parameters. |
| 446 int default_function_length() const { return arity_; } |
| 447 |
| 448 // Returns the number of formal parameters, up to but not including the |
| 449 // rest parameter index (if the function has rest parameters), i.e. it |
| 450 // says 2 for |
| 451 // |
| 452 // function foo(a, b) { ... } |
| 453 // |
| 454 // and |
| 455 // |
| 456 // function foo(a, b, ...c) { ... } |
| 457 // |
| 458 // but for |
| 459 // |
| 460 // function foo(a, b, c = 1) { ... } |
| 461 // |
| 462 // we return 3 here. |
| 463 int num_parameters() const { |
| 464 return has_rest_parameter() ? params_.length() - 1 : params_.length(); |
| 465 } |
| 466 |
| 467 // A function can have at most one rest parameter. Returns Variable* or NULL. |
| 468 Variable* rest_parameter(int* index) const { |
| 469 *index = rest_index_; |
| 470 if (rest_index_ < 0) return NULL; |
| 471 return rest_parameter_; |
| 472 } |
| 473 |
| 474 bool has_rest_parameter() const { return rest_index_ >= 0; } |
| 475 |
| 476 bool has_simple_parameters() const { |
| 477 return has_simple_parameters_; |
| 478 } |
| 479 |
| 480 // TODO(caitp): manage this state in a better way. PreParser must be able to |
| 481 // communicate that the scope is non-simple, without allocating any parameters |
| 482 // as the Parser does. This is necessary to ensure that TC39's proposed early |
| 483 // error can be reported consistently regardless of whether lazily parsed or |
| 484 // not. |
| 485 void SetHasNonSimpleParameters() { |
| 486 DCHECK(is_function_scope()); |
| 487 has_simple_parameters_ = false; |
| 488 } |
| 489 |
| 490 // Retrieve `IsSimpleParameterList` of current or outer function. |
| 491 bool HasSimpleParameters() { |
| 492 Scope* scope = ClosureScope(); |
| 493 return !scope->is_function_scope() || scope->has_simple_parameters(); |
| 494 } |
| 495 |
| 496 // The local variable 'arguments' if we need to allocate it; NULL otherwise. |
| 497 Variable* arguments() const { |
| 498 DCHECK(!is_arrow_scope() || arguments_ == nullptr); |
| 499 return arguments_; |
| 500 } |
| 501 |
| 502 Variable* this_function_var() const { |
| 503 // This is only used in derived constructors atm. |
| 504 DCHECK(this_function_ == nullptr || |
| 505 (is_function_scope() && (IsClassConstructor(function_kind()) || |
| 506 IsConciseMethod(function_kind()) || |
| 507 IsAccessorFunction(function_kind())))); |
| 508 return this_function_; |
| 509 } |
| 510 |
| 511 // Declarations list. |
| 512 ZoneList<Declaration*>* declarations() { return &decls_; } |
| 513 |
362 // inner_scope() and sibling() together implement the inner scope list of a | 514 // inner_scope() and sibling() together implement the inner scope list of a |
363 // scope. Inner scope points to the an inner scope of the function, and | 515 // scope. Inner scope points to the an inner scope of the function, and |
364 // "sibling" points to a next inner scope of the outer scope of this scope. | 516 // "sibling" points to a next inner scope of the outer scope of this scope. |
365 Scope* inner_scope() const { return inner_scope_; } | 517 Scope* inner_scope() const { return inner_scope_; } |
366 Scope* sibling() const { return sibling_; } | 518 Scope* sibling() const { return sibling_; } |
367 | 519 |
368 // The scope immediately surrounding this scope, or NULL. | 520 // The scope immediately surrounding this scope, or NULL. |
369 Scope* outer_scope() const { return outer_scope_; } | 521 Scope* outer_scope() const { return outer_scope_; } |
370 | 522 |
| 523 // The ModuleDescriptor for this scope; only for module scopes. |
| 524 ModuleDescriptor* module() const { return module_descriptor_; } |
| 525 |
371 const AstRawString* catch_variable_name() const { | 526 const AstRawString* catch_variable_name() const { |
372 DCHECK(is_catch_scope()); | 527 DCHECK(is_catch_scope()); |
373 DCHECK_EQ(1, num_var()); | 528 DCHECK_EQ(1, num_var()); |
374 return static_cast<AstRawString*>(variables_.Start()->key); | 529 return static_cast<AstRawString*>(variables_.Start()->key); |
375 } | 530 } |
376 | 531 |
377 // --------------------------------------------------------------------------- | 532 // --------------------------------------------------------------------------- |
378 // Variable allocation. | 533 // Variable allocation. |
379 | 534 |
380 // Collect stack and context allocated local variables in this scope. Note | 535 // Collect stack and context allocated local variables in this scope. Note |
(...skipping 29 matching lines...) Expand all Loading... |
410 | 565 |
411 // The number of contexts between this and scope; zero if this == scope. | 566 // The number of contexts between this and scope; zero if this == scope. |
412 int ContextChainLength(Scope* scope); | 567 int ContextChainLength(Scope* scope); |
413 | 568 |
414 // The maximum number of nested contexts required for this scope and any inner | 569 // The maximum number of nested contexts required for this scope and any inner |
415 // scopes. | 570 // scopes. |
416 int MaxNestedContextChainLength(); | 571 int MaxNestedContextChainLength(); |
417 | 572 |
418 // Find the first function, script, eval or (declaration) block scope. This is | 573 // Find the first function, script, eval or (declaration) block scope. This is |
419 // the scope where var declarations will be hoisted to in the implementation. | 574 // the scope where var declarations will be hoisted to in the implementation. |
420 DeclarationScope* GetDeclarationScope(); | 575 Scope* DeclarationScope(); |
421 | 576 |
422 // Find the first non-block declaration scope. This should be either a script, | 577 // Find the first non-block declaration scope. This should be either a script, |
423 // function, or eval scope. Same as DeclarationScope(), but skips declaration | 578 // function, or eval scope. Same as DeclarationScope(), but skips |
424 // "block" scopes. Used for differentiating associated function objects (i.e., | 579 // declaration "block" scopes. Used for differentiating associated |
425 // the scope for which a function prologue allocates a context) or declaring | 580 // function objects (i.e., the scope for which a function prologue allocates |
426 // temporaries. | 581 // a context) or declaring temporaries. |
427 DeclarationScope* GetClosureScope(); | 582 Scope* ClosureScope(); |
428 | 583 |
429 // Find the first (non-arrow) function or script scope. This is where | 584 // Find the first (non-arrow) function or script scope. This is where |
430 // 'this' is bound, and what determines the function kind. | 585 // 'this' is bound, and what determines the function kind. |
431 DeclarationScope* GetReceiverScope(); | 586 Scope* ReceiverScope(); |
432 | 587 |
433 Handle<ScopeInfo> GetScopeInfo(Isolate* isolate); | 588 Handle<ScopeInfo> GetScopeInfo(Isolate* isolate); |
434 | 589 |
435 Handle<StringSet> CollectNonLocals(Handle<StringSet> non_locals); | 590 Handle<StringSet> CollectNonLocals(Handle<StringSet> non_locals); |
436 | 591 |
437 // --------------------------------------------------------------------------- | 592 // --------------------------------------------------------------------------- |
438 // Strict mode support. | 593 // Strict mode support. |
439 bool IsDeclared(const AstRawString* name) { | 594 bool IsDeclared(const AstRawString* name) { |
440 // During formal parameter list parsing the scope only contains | 595 // During formal parameter list parsing the scope only contains |
441 // two variables inserted at initialization: "this" and "arguments". | 596 // two variables inserted at initialization: "this" and "arguments". |
442 // "this" is an invalid parameter name and "arguments" is invalid parameter | 597 // "this" is an invalid parameter name and "arguments" is invalid parameter |
443 // name in strict mode. Therefore looking up with the map which includes | 598 // name in strict mode. Therefore looking up with the map which includes |
444 // "this" and "arguments" in addition to all formal parameters is safe. | 599 // "this" and "arguments" in addition to all formal parameters is safe. |
445 return variables_.Lookup(name) != NULL; | 600 return variables_.Lookup(name) != NULL; |
446 } | 601 } |
447 | 602 |
| 603 bool IsDeclaredParameter(const AstRawString* name) { |
| 604 // If IsSimpleParameterList is false, duplicate parameters are not allowed, |
| 605 // however `arguments` may be allowed if function is not strict code. Thus, |
| 606 // the assumptions explained above do not hold. |
| 607 return params_.Contains(variables_.Lookup(name)); |
| 608 } |
| 609 |
448 int num_var() const { return variables_.occupancy(); } | 610 int num_var() const { return variables_.occupancy(); } |
449 | 611 |
| 612 SloppyBlockFunctionMap* sloppy_block_function_map() { |
| 613 return &sloppy_block_function_map_; |
| 614 } |
| 615 |
| 616 // To be called during parsing. Do just enough scope analysis that we can |
| 617 // discard the Scope for lazily compiled functions. In particular, this |
| 618 // records variables which cannot be resolved inside the Scope (we don't yet |
| 619 // know what they will resolve to since the outer Scopes are incomplete) and |
| 620 // migrates them into migrate_to. |
| 621 void AnalyzePartially(Scope* migrate_to, AstNodeFactory* ast_node_factory); |
| 622 |
450 // --------------------------------------------------------------------------- | 623 // --------------------------------------------------------------------------- |
451 // Debugging. | 624 // Debugging. |
452 | 625 |
453 #ifdef DEBUG | 626 #ifdef DEBUG |
454 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively | 627 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively |
455 | 628 |
456 // Check that the scope has positions assigned. | 629 // Check that the scope has positions assigned. |
457 void CheckScopePositions(); | 630 void CheckScopePositions(); |
458 | 631 |
459 // Check that all Scopes in the scope tree use the same Zone. | 632 // Check that all Scopes in the scope tree use the same Zone. |
460 void CheckZones(); | 633 void CheckZones(); |
461 #endif | 634 #endif |
462 | 635 |
463 // Retrieve `IsSimpleParameterList` of current or outer function. | 636 // --------------------------------------------------------------------------- |
464 bool HasSimpleParameters(); | 637 // Implementation. |
465 | |
466 private: | 638 private: |
467 // Scope tree. | 639 // Scope tree. |
468 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL | 640 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL |
469 Scope* inner_scope_; // an inner scope of this scope | 641 Scope* inner_scope_; // an inner scope of this scope |
470 Scope* sibling_; // a sibling inner scope of the outer scope of this scope. | 642 Scope* sibling_; // a sibling inner scope of the outer scope of this scope. |
471 | 643 |
| 644 // Debugging support. |
| 645 #ifdef DEBUG |
| 646 const AstRawString* scope_name_; |
| 647 #endif |
| 648 |
472 // The variables declared in this scope: | 649 // The variables declared in this scope: |
473 // | 650 // |
474 // All user-declared variables (incl. parameters). For script scopes | 651 // All user-declared variables (incl. parameters). For script scopes |
475 // variables may be implicitly 'declared' by being used (possibly in | 652 // variables may be implicitly 'declared' by being used (possibly in |
476 // an inner scope) with no intervening with statements or eval calls. | 653 // an inner scope) with no intervening with statements or eval calls. |
477 VariableMap variables_; | 654 VariableMap variables_; |
| 655 // Compiler-allocated (user-invisible) temporaries. Due to the implementation |
| 656 // of RemoveTemporary(), may contain nulls, which must be skipped-over during |
| 657 // allocation and printing. |
| 658 ZoneList<Variable*> temps_; |
| 659 // Parameter list in source order. |
| 660 ZoneList<Variable*> params_; |
478 // Variables that must be looked up dynamically. | 661 // Variables that must be looked up dynamically. |
479 DynamicScopePart* dynamics_; | 662 DynamicScopePart* dynamics_; |
480 // Unresolved variables referred to from this scope. The proxies themselves | 663 // Unresolved variables referred to from this scope. The proxies themselves |
481 // form a linked list of all unresolved proxies. | 664 // form a linked list of all unresolved proxies. |
482 VariableProxy* unresolved_; | 665 VariableProxy* unresolved_; |
483 // Declarations. | 666 // Declarations. |
484 ZoneList<Declaration*> decls_; | 667 ZoneList<Declaration*> decls_; |
| 668 // Convenience variable. |
| 669 Variable* receiver_; |
| 670 // Function variable, if any; function scopes only. |
| 671 VariableDeclaration* function_; |
| 672 // new.target variable, function scopes only. |
| 673 Variable* new_target_; |
| 674 // Convenience variable; function scopes only. |
| 675 Variable* arguments_; |
| 676 // Convenience variable; Subclass constructor only |
| 677 Variable* this_function_; |
| 678 // Module descriptor; module scopes only. |
| 679 ModuleDescriptor* module_descriptor_; |
485 | 680 |
486 // Serialized scope info support. | 681 // Map of function names to lists of functions defined in sloppy blocks |
487 Handle<ScopeInfo> scope_info_; | 682 SloppyBlockFunctionMap sloppy_block_function_map_; |
488 // Debugging support. | |
489 #ifdef DEBUG | |
490 const AstRawString* scope_name_; | |
491 #endif | |
492 | |
493 // Source positions. | |
494 int start_position_; | |
495 int end_position_; | |
496 | |
497 // Computed via AllocateVariables; function, block and catch scopes only. | |
498 int num_stack_slots_; | |
499 int num_heap_slots_; | |
500 int num_global_slots_; | |
501 | 683 |
502 // The scope type. | 684 // The scope type. |
503 const ScopeType scope_type_; | 685 const ScopeType scope_type_; |
| 686 // If the scope is a function scope, this is the function kind. |
| 687 const FunctionKind function_kind_; |
504 | 688 |
505 // Scope-specific information computed during parsing. | 689 // Scope-specific information computed during parsing. |
506 // | 690 // |
507 // The language mode of this scope. | 691 // The language mode of this scope. |
508 STATIC_ASSERT(LANGUAGE_END == 3); | 692 STATIC_ASSERT(LANGUAGE_END == 3); |
509 LanguageMode language_mode_ : 2; | 693 LanguageMode language_mode_ : 2; |
510 // This scope is inside a 'with' of some outer scope. | 694 // This scope is inside a 'with' of some outer scope. |
511 bool scope_inside_with_ : 1; | 695 bool scope_inside_with_ : 1; |
512 // This scope or a nested catch scope or with scope contain an 'eval' call. At | 696 // This scope or a nested catch scope or with scope contain an 'eval' call. At |
513 // the 'eval' call site this scope is the declaration scope. | 697 // the 'eval' call site this scope is the declaration scope. |
(...skipping 18 matching lines...) Expand all Loading... |
532 bool force_context_allocation_ : 1; | 716 bool force_context_allocation_ : 1; |
533 | 717 |
534 // True if it doesn't need scope resolution (e.g., if the scope was | 718 // True if it doesn't need scope resolution (e.g., if the scope was |
535 // constructed based on a serialized scope info or a catch context). | 719 // constructed based on a serialized scope info or a catch context). |
536 bool already_resolved_ : 1; | 720 bool already_resolved_ : 1; |
537 bool already_resolved() { return already_resolved_; } | 721 bool already_resolved() { return already_resolved_; } |
538 | 722 |
539 // True if it holds 'var' declarations. | 723 // True if it holds 'var' declarations. |
540 bool is_declaration_scope_ : 1; | 724 bool is_declaration_scope_ : 1; |
541 | 725 |
| 726 // Source positions. |
| 727 int start_position_; |
| 728 int end_position_; |
| 729 |
| 730 // Computed via AllocateVariables; function, block and catch scopes only. |
| 731 int num_stack_slots_; |
| 732 int num_heap_slots_; |
| 733 int num_global_slots_; |
| 734 |
| 735 // Info about the parameter list of a function. |
| 736 int arity_; |
| 737 int rest_index_; |
| 738 Variable* rest_parameter_; |
| 739 |
| 740 // Serialized scope info support. |
| 741 Handle<ScopeInfo> scope_info_; |
| 742 |
542 // Create a non-local variable with a given name. | 743 // Create a non-local variable with a given name. |
543 // These variables are looked up dynamically at runtime. | 744 // These variables are looked up dynamically at runtime. |
544 Variable* NonLocal(const AstRawString* name, VariableMode mode); | 745 Variable* NonLocal(const AstRawString* name, VariableMode mode); |
545 | 746 |
546 // Variable resolution. | 747 // Variable resolution. |
547 // Possible results of a recursive variable lookup telling if and how a | 748 // Possible results of a recursive variable lookup telling if and how a |
548 // variable is bound. These are returned in the output parameter *binding_kind | 749 // variable is bound. These are returned in the output parameter *binding_kind |
549 // of the LookupRecursive function. | 750 // of the LookupRecursive function. |
550 enum BindingKind { | 751 enum BindingKind { |
551 // The variable reference could be statically resolved to a variable binding | 752 // The variable reference could be statically resolved to a variable binding |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 AstNodeFactory* factory, | 798 AstNodeFactory* factory, |
598 Scope* max_outer_scope = nullptr); | 799 Scope* max_outer_scope = nullptr); |
599 MUST_USE_RESULT | 800 MUST_USE_RESULT |
600 bool ResolveVariable(ParseInfo* info, VariableProxy* proxy, | 801 bool ResolveVariable(ParseInfo* info, VariableProxy* proxy, |
601 AstNodeFactory* factory); | 802 AstNodeFactory* factory); |
602 MUST_USE_RESULT | 803 MUST_USE_RESULT |
603 bool ResolveVariablesRecursively(ParseInfo* info, AstNodeFactory* factory); | 804 bool ResolveVariablesRecursively(ParseInfo* info, AstNodeFactory* factory); |
604 | 805 |
605 // Tries to resolve local variables inside max_outer_scope; migrates those | 806 // Tries to resolve local variables inside max_outer_scope; migrates those |
606 // which cannot be resolved into migrate_to. | 807 // which cannot be resolved into migrate_to. |
607 void MigrateUnresolvableLocals(DeclarationScope* migrate_to, | 808 void MigrateUnresolvableLocals(Scope* migrate_to, |
608 AstNodeFactory* ast_node_factory, | 809 AstNodeFactory* ast_node_factory, |
609 DeclarationScope* max_outer_scope); | 810 Scope* max_outer_scope); |
610 | 811 |
611 // Scope analysis. | 812 // Scope analysis. |
612 void PropagateScopeInfo(bool outer_scope_calls_sloppy_eval); | 813 void PropagateScopeInfo(bool outer_scope_calls_sloppy_eval); |
613 bool HasTrivialContext() const; | 814 bool HasTrivialContext() const; |
614 | 815 |
615 // Predicates. | 816 // Predicates. |
616 bool MustAllocate(Variable* var); | 817 bool MustAllocate(Variable* var); |
617 bool MustAllocateInContext(Variable* var); | 818 bool MustAllocateInContext(Variable* var); |
618 | 819 |
619 // Variable allocation. | 820 // Variable allocation. |
620 void AllocateStackSlot(Variable* var); | 821 void AllocateStackSlot(Variable* var); |
621 void AllocateHeapSlot(Variable* var); | 822 void AllocateHeapSlot(Variable* var); |
| 823 void AllocateParameterLocals(); |
622 void AllocateNonParameterLocal(Variable* var, | 824 void AllocateNonParameterLocal(Variable* var, |
623 AstValueFactory* ast_value_factory); | 825 AstValueFactory* ast_value_factory); |
624 void AllocateDeclaredGlobal(Variable* var, | 826 void AllocateDeclaredGlobal(Variable* var, |
625 AstValueFactory* ast_value_factory); | 827 AstValueFactory* ast_value_factory); |
626 void AllocateNonParameterLocalsAndDeclaredGlobals( | 828 void AllocateNonParameterLocalsAndDeclaredGlobals( |
627 AstValueFactory* ast_value_factory); | 829 AstValueFactory* ast_value_factory); |
628 void AllocateVariablesRecursively(AstValueFactory* ast_value_factory); | 830 void AllocateVariablesRecursively(AstValueFactory* ast_value_factory); |
| 831 void AllocateParameter(Variable* var, int index); |
| 832 void AllocateReceiver(); |
| 833 |
| 834 // Resolve and fill in the allocation information for all variables |
| 835 // in this scopes. Must be called *after* all scopes have been |
| 836 // processed (parsed) to ensure that unresolved variables can be |
| 837 // resolved properly. |
| 838 // |
| 839 // In the case of code compiled and run using 'eval', the context |
| 840 // parameter is the context in which eval was called. In all other |
| 841 // cases the context parameter is an empty handle. |
| 842 MUST_USE_RESULT |
| 843 bool AllocateVariables(ParseInfo* info, AstNodeFactory* factory); |
629 | 844 |
630 // Construct a scope based on the scope info. | 845 // Construct a scope based on the scope info. |
631 Scope(Zone* zone, Scope* inner_scope, ScopeType type, | 846 Scope(Zone* zone, Scope* inner_scope, ScopeType type, |
632 Handle<ScopeInfo> scope_info); | 847 Handle<ScopeInfo> scope_info); |
633 | 848 |
634 // Construct a catch scope with a binding for the name. | 849 // Construct a catch scope with a binding for the name. |
635 Scope(Zone* zone, Scope* inner_scope, | 850 Scope(Zone* zone, Scope* inner_scope, |
636 const AstRawString* catch_variable_name); | 851 const AstRawString* catch_variable_name); |
637 | 852 |
638 void AddInnerScope(Scope* inner_scope) { | 853 void AddInnerScope(Scope* inner_scope) { |
(...skipping 17 matching lines...) Expand all Loading... |
656 return; | 871 return; |
657 } | 872 } |
658 } | 873 } |
659 } | 874 } |
660 | 875 |
661 void SetDefaults(); | 876 void SetDefaults(); |
662 | 877 |
663 void DeserializeScopeInfo(Isolate* isolate, | 878 void DeserializeScopeInfo(Isolate* isolate, |
664 AstValueFactory* ast_value_factory); | 879 AstValueFactory* ast_value_factory); |
665 | 880 |
666 friend class DeclarationScope; | |
667 }; | |
668 | |
669 class DeclarationScope : public Scope { | |
670 public: | |
671 DeclarationScope(Zone* zone, Scope* outer_scope, ScopeType scope_type, | |
672 FunctionKind function_kind = kNormalFunction); | |
673 DeclarationScope(Zone* zone, Scope* inner_scope, ScopeType scope_type, | |
674 Handle<ScopeInfo> scope_info); | |
675 | |
676 bool IsDeclaredParameter(const AstRawString* name) { | |
677 // If IsSimpleParameterList is false, duplicate parameters are not allowed, | |
678 // however `arguments` may be allowed if function is not strict code. Thus, | |
679 // the assumptions explained above do not hold. | |
680 return params_.Contains(variables_.Lookup(name)); | |
681 } | |
682 | |
683 FunctionKind function_kind() const { return function_kind_; } | |
684 | |
685 bool is_arrow_scope() const { | |
686 return is_function_scope() && IsArrowFunction(function_kind_); | |
687 } | |
688 | |
689 bool NeedsHomeObject() const { | |
690 return scope_uses_super_property_ || | |
691 ((scope_calls_eval_ || inner_scope_calls_eval_) && | |
692 (IsConciseMethod(function_kind()) || | |
693 IsAccessorFunction(function_kind()) || | |
694 IsClassConstructor(function_kind()))); | |
695 } | |
696 | |
697 // The ModuleDescriptor for this scope; only for module scopes. | |
698 // TODO(verwaest): Move to ModuleScope? | |
699 ModuleDescriptor* module() const { return module_descriptor_; } | |
700 | |
701 void DeclareThis(AstValueFactory* ast_value_factory); | |
702 void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory); | |
703 | |
704 // This lookup corresponds to a lookup in the "intermediate" scope sitting | |
705 // between this scope and the outer scope. (ECMA-262, 3rd., requires that | |
706 // the name of named function literal is kept in an intermediate scope | |
707 // in between this scope and the next outer scope.) | |
708 Variable* LookupFunctionVar(const AstRawString* name, | |
709 AstNodeFactory* factory); | |
710 | |
711 // Declare the function variable for a function literal. This variable | |
712 // is in an intermediate scope between this function scope and the the | |
713 // outer scope. Only possible for function scopes; at most one variable. | |
714 void DeclareFunctionVar(VariableDeclaration* declaration) { | |
715 DCHECK(is_function_scope()); | |
716 // Handle implicit declaration of the function name in named function | |
717 // expressions before other declarations. | |
718 declarations()->InsertAt(0, declaration, zone()); | |
719 function_ = declaration; | |
720 } | |
721 | |
722 // Declare a parameter in this scope. When there are duplicated | |
723 // parameters the rightmost one 'wins'. However, the implementation | |
724 // expects all parameters to be declared and from left to right. | |
725 Variable* DeclareParameter(const AstRawString* name, VariableMode mode, | |
726 bool is_optional, bool is_rest, bool* is_duplicate, | |
727 AstValueFactory* ast_value_factory); | |
728 | |
729 // Declare an implicit global variable in this scope which must be a | |
730 // script scope. The variable was introduced (possibly from an inner | |
731 // scope) by a reference to an unresolved variable with no intervening | |
732 // with statements or eval calls. | |
733 Variable* DeclareDynamicGlobal(const AstRawString* name); | |
734 | |
735 // The variable corresponding to the 'this' value. | |
736 Variable* receiver() { | |
737 DCHECK(has_this_declaration()); | |
738 DCHECK_NOT_NULL(receiver_); | |
739 return receiver_; | |
740 } | |
741 | |
742 // TODO(wingo): Add a GLOBAL_SCOPE scope type which will lexically allocate | |
743 // "this" (and no other variable) on the native context. Script scopes then | |
744 // will not have a "this" declaration. | |
745 bool has_this_declaration() const { | |
746 return (is_function_scope() && !is_arrow_scope()) || is_module_scope(); | |
747 } | |
748 | |
749 // The variable corresponding to the 'new.target' value. | |
750 Variable* new_target_var() { return new_target_; } | |
751 | |
752 // The variable holding the function literal for named function | |
753 // literals, or NULL. Only valid for function scopes. | |
754 VariableDeclaration* function() const { | |
755 DCHECK(is_function_scope()); | |
756 return function_; | |
757 } | |
758 | |
759 // Parameters. The left-most parameter has index 0. | |
760 // Only valid for function scopes. | |
761 Variable* parameter(int index) const { | |
762 DCHECK(is_function_scope()); | |
763 return params_[index]; | |
764 } | |
765 | |
766 // Returns the default function arity excluding default or rest parameters. | |
767 int default_function_length() const { return arity_; } | |
768 | |
769 // Returns the number of formal parameters, up to but not including the | |
770 // rest parameter index (if the function has rest parameters), i.e. it | |
771 // says 2 for | |
772 // | |
773 // function foo(a, b) { ... } | |
774 // | |
775 // and | |
776 // | |
777 // function foo(a, b, ...c) { ... } | |
778 // | |
779 // but for | |
780 // | |
781 // function foo(a, b, c = 1) { ... } | |
782 // | |
783 // we return 3 here. | |
784 int num_parameters() const { | |
785 return has_rest_parameter() ? params_.length() - 1 : params_.length(); | |
786 } | |
787 | |
788 // A function can have at most one rest parameter. Returns Variable* or NULL. | |
789 Variable* rest_parameter(int* index) const { | |
790 *index = rest_index_; | |
791 if (rest_index_ < 0) return NULL; | |
792 return rest_parameter_; | |
793 } | |
794 | |
795 bool has_rest_parameter() const { return rest_index_ >= 0; } | |
796 | |
797 bool has_simple_parameters() const { return has_simple_parameters_; } | |
798 | |
799 // TODO(caitp): manage this state in a better way. PreParser must be able to | |
800 // communicate that the scope is non-simple, without allocating any parameters | |
801 // as the Parser does. This is necessary to ensure that TC39's proposed early | |
802 // error can be reported consistently regardless of whether lazily parsed or | |
803 // not. | |
804 void SetHasNonSimpleParameters() { | |
805 DCHECK(is_function_scope()); | |
806 has_simple_parameters_ = false; | |
807 } | |
808 | |
809 // The local variable 'arguments' if we need to allocate it; NULL otherwise. | |
810 Variable* arguments() const { | |
811 DCHECK(!is_arrow_scope() || arguments_ == nullptr); | |
812 return arguments_; | |
813 } | |
814 | |
815 Variable* this_function_var() const { | |
816 // This is only used in derived constructors atm. | |
817 DCHECK(this_function_ == nullptr || | |
818 (is_function_scope() && (IsClassConstructor(function_kind()) || | |
819 IsConciseMethod(function_kind()) || | |
820 IsAccessorFunction(function_kind())))); | |
821 return this_function_; | |
822 } | |
823 | |
824 // Remove a temporary variable. This is for adjusting the scope of | |
825 // temporaries used when desugaring parameter initializers. | |
826 // Returns the index at which it was found in this scope, or -1 if | |
827 // it was not found. | |
828 int RemoveTemporary(Variable* var); | |
829 | |
830 // Adds a temporary variable in this scope's TemporaryScope. This is for | |
831 // adjusting the scope of temporaries used when desugaring parameter | |
832 // initializers. | |
833 void AddTemporary(Variable* var) { | |
834 // Temporaries are only placed in ClosureScopes. | |
835 DCHECK_EQ(GetClosureScope(), this); | |
836 temps_.Add(var, zone()); | |
837 } | |
838 | |
839 ZoneList<Variable*>* temps() { return &temps_; } | |
840 | |
841 SloppyBlockFunctionMap* sloppy_block_function_map() { | |
842 return &sloppy_block_function_map_; | |
843 } | |
844 | |
845 // Resolve and fill in the allocation information for all variables | |
846 // in this scopes. Must be called *after* all scopes have been | |
847 // processed (parsed) to ensure that unresolved variables can be | |
848 // resolved properly. | |
849 // | |
850 // In the case of code compiled and run using 'eval', the context | |
851 // parameter is the context in which eval was called. In all other | |
852 // cases the context parameter is an empty handle. | |
853 MUST_USE_RESULT | |
854 bool AllocateVariables(ParseInfo* info, AstNodeFactory* factory); | |
855 | |
856 // To be called during parsing. Do just enough scope analysis that we can | |
857 // discard the Scope for lazily compiled functions. In particular, this | |
858 // records variables which cannot be resolved inside the Scope (we don't yet | |
859 // know what they will resolve to since the outer Scopes are incomplete) and | |
860 // migrates them into migrate_to. | |
861 void AnalyzePartially(DeclarationScope* migrate_to, | |
862 AstNodeFactory* ast_node_factory); | |
863 | |
864 #ifdef DEBUG | |
865 void PrintParameters(); | |
866 #endif | |
867 | |
868 void AllocateLocals(AstValueFactory* ast_value_factory); | |
869 void AllocateParameterLocals(); | |
870 void AllocateReceiver(); | |
871 | |
872 private: | |
873 void AllocateParameter(Variable* var, int index); | |
874 | |
875 void SetDefaults(); | |
876 | |
877 // If the scope is a function scope, this is the function kind. | |
878 const FunctionKind function_kind_; | |
879 | |
880 // Info about the parameter list of a function. | |
881 int arity_; | |
882 int rest_index_; | |
883 Variable* rest_parameter_; | |
884 // Compiler-allocated (user-invisible) temporaries. Due to the implementation | |
885 // of RemoveTemporary(), may contain nulls, which must be skipped-over during | |
886 // allocation and printing. | |
887 ZoneList<Variable*> temps_; | |
888 // Parameter list in source order. | |
889 ZoneList<Variable*> params_; | |
890 // Map of function names to lists of functions defined in sloppy blocks | |
891 SloppyBlockFunctionMap sloppy_block_function_map_; | |
892 // Convenience variable. | |
893 Variable* receiver_; | |
894 // Function variable, if any; function scopes only. | |
895 VariableDeclaration* function_; | |
896 // new.target variable, function scopes only. | |
897 Variable* new_target_; | |
898 // Convenience variable; function scopes only. | |
899 Variable* arguments_; | |
900 // Convenience variable; Subclass constructor only | |
901 Variable* this_function_; | |
902 // Module descriptor; module scopes only. | |
903 ModuleDescriptor* module_descriptor_; | |
904 PendingCompilationErrorHandler pending_error_handler_; | 881 PendingCompilationErrorHandler pending_error_handler_; |
905 }; | 882 }; |
906 | 883 |
907 } // namespace internal | 884 } // namespace internal |
908 } // namespace v8 | 885 } // namespace v8 |
909 | 886 |
910 #endif // V8_AST_SCOPES_H_ | 887 #endif // V8_AST_SCOPES_H_ |
OLD | NEW |