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. | |
87 class Scope: public ZoneObject { | 94 class Scope: public ZoneObject { |
88 public: | 95 public: |
89 // --------------------------------------------------------------------------- | 96 // --------------------------------------------------------------------------- |
90 // Construction | 97 // Construction |
91 | 98 |
92 Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, | 99 Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type); |
93 FunctionKind function_kind = kNormalFunction); | 100 |
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; | |
94 | 113 |
95 class Snapshot final BASE_EMBEDDED { | 114 class Snapshot final BASE_EMBEDDED { |
96 public: | 115 public: |
97 explicit Snapshot(Scope* scope) | 116 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()) {} | |
102 | 117 |
103 void Reparent(Scope* new_parent) const; | 118 void Reparent(DeclarationScope* new_parent) const; |
104 | 119 |
105 private: | 120 private: |
106 Scope* outer_scope_; | 121 Scope* outer_scope_; |
107 Scope* top_inner_scope_; | 122 Scope* top_inner_scope_; |
108 VariableProxy* top_unresolved_; | 123 VariableProxy* top_unresolved_; |
109 int top_temp_; | 124 int top_temp_; |
110 }; | 125 }; |
111 | 126 |
112 // Compute top scope and allocate variables. For lazy compilation the top | 127 // Compute top scope and allocate variables. For lazy compilation the top |
113 // scope only contains the single lazily compiled function, so this | 128 // scope only contains the single lazily compiled function, so this |
114 // doesn't re-allocate variables repeatedly. | 129 // doesn't re-allocate variables repeatedly. |
115 static bool Analyze(ParseInfo* info); | 130 static bool Analyze(ParseInfo* info); |
116 | 131 |
117 enum class DeserializationMode { kDeserializeOffHeap, kKeepScopeInfo }; | 132 enum class DeserializationMode { kDeserializeOffHeap, kKeepScopeInfo }; |
118 | 133 |
119 static Scope* DeserializeScopeChain(Isolate* isolate, Zone* zone, | 134 static Scope* DeserializeScopeChain(Isolate* isolate, Zone* zone, |
120 Context* context, Scope* script_scope, | 135 Context* context, |
136 DeclarationScope* script_scope, | |
121 AstValueFactory* ast_value_factory, | 137 AstValueFactory* ast_value_factory, |
122 DeserializationMode deserialization_mode); | 138 DeserializationMode deserialization_mode); |
123 | 139 |
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 | |
134 // Checks if the block scope is redundant, i.e. it does not contain any | 140 // Checks if the block scope is redundant, i.e. it does not contain any |
135 // block scoped declarations. In that case it is removed from the scope | 141 // block scoped declarations. In that case it is removed from the scope |
136 // tree and its children are reparented. | 142 // tree and its children are reparented. |
137 Scope* FinalizeBlockScope(); | 143 Scope* FinalizeBlockScope(); |
138 | 144 |
139 // Inserts outer_scope into this scope's scope chain (and removes this | 145 // Inserts outer_scope into this scope's scope chain (and removes this |
140 // from the current outer_scope_'s inner scope list). | 146 // from the current outer_scope_'s inner scope list). |
141 // Assumes outer_scope_ is non-null. | 147 // Assumes outer_scope_ is non-null. |
142 void ReplaceOuterScope(Scope* outer_scope); | 148 void ReplaceOuterScope(Scope* outer_scope); |
143 | 149 |
144 // Propagates any eagerly-gathered scope usage flags (such as calls_eval()) | 150 // Propagates any eagerly-gathered scope usage flags (such as calls_eval()) |
145 // to the passed-in scope. | 151 // to the passed-in scope. |
146 void PropagateUsageFlagsToScope(Scope* other); | 152 void PropagateUsageFlagsToScope(Scope* other); |
147 | 153 |
148 Zone* zone() const { return variables_.zone(); } | 154 Zone* zone() const { return variables_.zone(); } |
149 | 155 |
150 // --------------------------------------------------------------------------- | 156 // --------------------------------------------------------------------------- |
151 // Declarations | 157 // Declarations |
152 | 158 |
153 // Lookup a variable in this scope. Returns the variable or NULL if not found. | 159 // Lookup a variable in this scope. Returns the variable or NULL if not found. |
154 Variable* LookupLocal(const AstRawString* name); | 160 Variable* LookupLocal(const AstRawString* name); |
155 | 161 |
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 | |
163 // Lookup a variable in this scope or outer scopes. | 162 // Lookup a variable in this scope or outer scopes. |
164 // Returns the variable or NULL if not found. | 163 // Returns the variable or NULL if not found. |
165 Variable* Lookup(const AstRawString* name); | 164 Variable* Lookup(const AstRawString* name); |
166 | 165 |
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 | |
185 // Declare a local variable in this scope. If the variable has been | 166 // Declare a local variable in this scope. If the variable has been |
186 // declared before, the previously declared variable is returned. | 167 // declared before, the previously declared variable is returned. |
187 Variable* DeclareLocal(const AstRawString* name, VariableMode mode, | 168 Variable* DeclareLocal(const AstRawString* name, VariableMode mode, |
188 InitializationFlag init_flag, Variable::Kind kind, | 169 InitializationFlag init_flag, Variable::Kind kind, |
189 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned); | 170 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned); |
190 | 171 |
191 // Declare an implicit global variable in this scope which must be a | 172 // Declarations list. |
192 // script scope. The variable was introduced (possibly from an inner | 173 ZoneList<Declaration*>* declarations() { return &decls_; } |
193 // scope) by a reference to an unresolved variable with no intervening | |
194 // with statements or eval calls. | |
195 Variable* DeclareDynamicGlobal(const AstRawString* name); | |
196 | 174 |
197 // Create a new unresolved variable. | 175 // Create a new unresolved variable. |
198 VariableProxy* NewUnresolved(AstNodeFactory* factory, | 176 VariableProxy* NewUnresolved(AstNodeFactory* factory, |
199 const AstRawString* name, | 177 const AstRawString* name, |
200 Variable::Kind kind = Variable::NORMAL, | 178 Variable::Kind kind = Variable::NORMAL, |
201 int start_position = kNoSourcePosition, | 179 int start_position = kNoSourcePosition, |
202 int end_position = kNoSourcePosition) { | 180 int end_position = kNoSourcePosition) { |
203 // Note that we must not share the unresolved variables with | 181 // Note that we must not share the unresolved variables with |
204 // the same name because they may be removed selectively via | 182 // the same name because they may be removed selectively via |
205 // RemoveUnresolved(). | 183 // RemoveUnresolved(). |
(...skipping 19 matching lines...) Expand all Loading... | |
225 // addition introduced a new unresolved variable which may end up being | 203 // addition introduced a new unresolved variable which may end up being |
226 // allocated globally as a "ghost" variable. RemoveUnresolved removes | 204 // allocated globally as a "ghost" variable. RemoveUnresolved removes |
227 // such a variable again if it was added; otherwise this is a no-op. | 205 // such a variable again if it was added; otherwise this is a no-op. |
228 bool RemoveUnresolved(VariableProxy* var); | 206 bool RemoveUnresolved(VariableProxy* var); |
229 | 207 |
230 // Creates a new temporary variable in this scope's TemporaryScope. The | 208 // Creates a new temporary variable in this scope's TemporaryScope. The |
231 // name is only used for printing and cannot be used to find the variable. | 209 // name is only used for printing and cannot be used to find the variable. |
232 // In particular, the only way to get hold of the temporary is by keeping the | 210 // In particular, the only way to get hold of the temporary is by keeping the |
233 // Variable* around. The name should not clash with a legitimate variable | 211 // Variable* around. The name should not clash with a legitimate variable |
234 // names. | 212 // names. |
213 // TODO(verwaest): Move to DeclarationScope? | |
235 Variable* NewTemporary(const AstRawString* name); | 214 Variable* NewTemporary(const AstRawString* name); |
236 | 215 |
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 | |
252 // Adds the specific declaration node to the list of declarations in | 216 // Adds the specific declaration node to the list of declarations in |
253 // this scope. The declarations are processed as part of entering | 217 // this scope. The declarations are processed as part of entering |
254 // the scope; see codegen.cc:ProcessDeclarations. | 218 // the scope; see codegen.cc:ProcessDeclarations. |
255 void AddDeclaration(Declaration* declaration); | 219 void AddDeclaration(Declaration* declaration); |
256 | 220 |
257 // --------------------------------------------------------------------------- | 221 // --------------------------------------------------------------------------- |
258 // Illegal redeclaration support. | 222 // Illegal redeclaration support. |
259 | 223 |
260 // Check if the scope has conflicting var | 224 // Check if the scope has conflicting var |
261 // declarations, i.e. a var declaration that has been hoisted from a nested | 225 // 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... | |
351 // Predicates. | 315 // Predicates. |
352 | 316 |
353 // Specific scope types. | 317 // Specific scope types. |
354 bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; } | 318 bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; } |
355 bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; } | 319 bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; } |
356 bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; } | 320 bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; } |
357 bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; } | 321 bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; } |
358 bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; } | 322 bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; } |
359 bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; } | 323 bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; } |
360 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; } | 324 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 } | |
364 bool is_declaration_scope() const { return is_declaration_scope_; } | 325 bool is_declaration_scope() const { return is_declaration_scope_; } |
365 | 326 |
366 void set_is_declaration_scope() { is_declaration_scope_ = true; } | |
367 | |
368 // Information about which scopes calls eval. | 327 // Information about which scopes calls eval. |
369 bool calls_eval() const { return scope_calls_eval_; } | 328 bool calls_eval() const { return scope_calls_eval_; } |
370 bool calls_sloppy_eval() const { | 329 bool calls_sloppy_eval() const { |
371 return scope_calls_eval_ && is_sloppy(language_mode_); | 330 return scope_calls_eval_ && is_sloppy(language_mode_); |
372 } | 331 } |
373 bool outer_scope_calls_sloppy_eval() const { | 332 bool outer_scope_calls_sloppy_eval() const { |
374 return outer_scope_calls_sloppy_eval_; | 333 return outer_scope_calls_sloppy_eval_; |
375 } | 334 } |
376 bool asm_module() const { return asm_module_; } | 335 bool asm_module() const { return asm_module_; } |
377 bool asm_function() const { return asm_function_; } | 336 bool asm_function() const { return asm_function_; } |
378 | 337 |
379 // Is this scope inside a with statement. | 338 // Is this scope inside a with statement. |
380 bool inside_with() const { return scope_inside_with_; } | 339 bool inside_with() const { return scope_inside_with_; } |
381 | 340 |
382 // Does this scope access "super" property (super.foo). | 341 // Does this scope access "super" property (super.foo). |
383 bool uses_super_property() const { return scope_uses_super_property_; } | 342 bool uses_super_property() const { return scope_uses_super_property_; } |
384 // Does this scope have the potential to execute declarations non-linearly? | 343 // Does this scope have the potential to execute declarations non-linearly? |
385 bool is_nonlinear() const { return scope_nonlinear_; } | 344 bool is_nonlinear() const { return scope_nonlinear_; } |
386 | 345 |
387 // Whether this needs to be represented by a runtime context. | 346 // Whether this needs to be represented by a runtime context. |
388 bool NeedsContext() const { | 347 bool NeedsContext() const { |
389 // Catch and module scopes always have heap slots. | 348 // Catch and module scopes always have heap slots. |
390 DCHECK(!is_catch_scope() || num_heap_slots() > 0); | 349 DCHECK(!is_catch_scope() || num_heap_slots() > 0); |
391 DCHECK(!is_module_scope() || num_heap_slots() > 0); | 350 DCHECK(!is_module_scope() || num_heap_slots() > 0); |
392 return is_with_scope() || num_heap_slots() > 0; | 351 return is_with_scope() || num_heap_slots() > 0; |
393 } | 352 } |
394 | 353 |
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 | |
403 // --------------------------------------------------------------------------- | 354 // --------------------------------------------------------------------------- |
404 // Accessors. | 355 // Accessors. |
405 | 356 |
406 // The type of this scope. | 357 // The type of this scope. |
407 ScopeType scope_type() const { return scope_type_; } | 358 ScopeType scope_type() const { return scope_type_; } |
408 | 359 |
409 FunctionKind function_kind() const { return function_kind_; } | |
410 | |
411 // The language mode of this scope. | 360 // The language mode of this scope. |
412 LanguageMode language_mode() const { return language_mode_; } | 361 LanguageMode language_mode() const { return language_mode_; } |
413 | 362 |
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 | |
514 // inner_scope() and sibling() together implement the inner scope list of a | 363 // inner_scope() and sibling() together implement the inner scope list of a |
515 // scope. Inner scope points to the an inner scope of the function, and | 364 // scope. Inner scope points to the an inner scope of the function, and |
516 // "sibling" points to a next inner scope of the outer scope of this scope. | 365 // "sibling" points to a next inner scope of the outer scope of this scope. |
517 Scope* inner_scope() const { return inner_scope_; } | 366 Scope* inner_scope() const { return inner_scope_; } |
518 Scope* sibling() const { return sibling_; } | 367 Scope* sibling() const { return sibling_; } |
519 | 368 |
520 // The scope immediately surrounding this scope, or NULL. | 369 // The scope immediately surrounding this scope, or NULL. |
521 Scope* outer_scope() const { return outer_scope_; } | 370 Scope* outer_scope() const { return outer_scope_; } |
522 | 371 |
523 // The ModuleDescriptor for this scope; only for module scopes. | |
524 ModuleDescriptor* module() const { return module_descriptor_; } | |
525 | |
526 const AstRawString* catch_variable_name() const { | 372 const AstRawString* catch_variable_name() const { |
527 DCHECK(is_catch_scope()); | 373 DCHECK(is_catch_scope()); |
528 DCHECK_EQ(1, num_var()); | 374 DCHECK_EQ(1, num_var()); |
529 return static_cast<AstRawString*>(variables_.Start()->key); | 375 return static_cast<AstRawString*>(variables_.Start()->key); |
530 } | 376 } |
531 | 377 |
532 // --------------------------------------------------------------------------- | 378 // --------------------------------------------------------------------------- |
533 // Variable allocation. | 379 // Variable allocation. |
534 | 380 |
535 // Collect stack and context allocated local variables in this scope. Note | 381 // Collect stack and context allocated local variables in this scope. Note |
(...skipping 29 matching lines...) Expand all Loading... | |
565 | 411 |
566 // The number of contexts between this and scope; zero if this == scope. | 412 // The number of contexts between this and scope; zero if this == scope. |
567 int ContextChainLength(Scope* scope); | 413 int ContextChainLength(Scope* scope); |
568 | 414 |
569 // The maximum number of nested contexts required for this scope and any inner | 415 // The maximum number of nested contexts required for this scope and any inner |
570 // scopes. | 416 // scopes. |
571 int MaxNestedContextChainLength(); | 417 int MaxNestedContextChainLength(); |
572 | 418 |
573 // Find the first function, script, eval or (declaration) block scope. This is | 419 // Find the first function, script, eval or (declaration) block scope. This is |
574 // the scope where var declarations will be hoisted to in the implementation. | 420 // the scope where var declarations will be hoisted to in the implementation. |
575 Scope* DeclarationScope(); | 421 DeclarationScope* GetDeclarationScope(); |
576 | 422 |
577 // Find the first non-block declaration scope. This should be either a script, | 423 // Find the first non-block declaration scope. This should be either a script, |
578 // function, or eval scope. Same as DeclarationScope(), but skips | 424 // function, or eval scope. Same as DeclarationScope(), but skips declaration |
579 // declaration "block" scopes. Used for differentiating associated | 425 // "block" scopes. Used for differentiating associated function objects (i.e., |
580 // function objects (i.e., the scope for which a function prologue allocates | 426 // the scope for which a function prologue allocates a context) or declaring |
581 // a context) or declaring temporaries. | 427 // temporaries. |
582 Scope* ClosureScope(); | 428 DeclarationScope* GetClosureScope(); |
583 | 429 |
584 // Find the first (non-arrow) function or script scope. This is where | 430 // Find the first (non-arrow) function or script scope. This is where |
585 // 'this' is bound, and what determines the function kind. | 431 // 'this' is bound, and what determines the function kind. |
586 Scope* ReceiverScope(); | 432 DeclarationScope* GetReceiverScope(); |
587 | 433 |
588 Handle<ScopeInfo> GetScopeInfo(Isolate* isolate); | 434 Handle<ScopeInfo> GetScopeInfo(Isolate* isolate); |
589 | 435 |
590 Handle<StringSet> CollectNonLocals(Handle<StringSet> non_locals); | 436 Handle<StringSet> CollectNonLocals(Handle<StringSet> non_locals); |
591 | 437 |
592 // --------------------------------------------------------------------------- | 438 // --------------------------------------------------------------------------- |
593 // Strict mode support. | 439 // Strict mode support. |
594 bool IsDeclared(const AstRawString* name) { | 440 bool IsDeclared(const AstRawString* name) { |
595 // During formal parameter list parsing the scope only contains | 441 // During formal parameter list parsing the scope only contains |
596 // two variables inserted at initialization: "this" and "arguments". | 442 // two variables inserted at initialization: "this" and "arguments". |
597 // "this" is an invalid parameter name and "arguments" is invalid parameter | 443 // "this" is an invalid parameter name and "arguments" is invalid parameter |
598 // name in strict mode. Therefore looking up with the map which includes | 444 // name in strict mode. Therefore looking up with the map which includes |
599 // "this" and "arguments" in addition to all formal parameters is safe. | 445 // "this" and "arguments" in addition to all formal parameters is safe. |
600 return variables_.Lookup(name) != NULL; | 446 return variables_.Lookup(name) != NULL; |
601 } | 447 } |
602 | 448 |
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 | |
610 int num_var() const { return variables_.occupancy(); } | 449 int num_var() const { return variables_.occupancy(); } |
611 | 450 |
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 | |
623 // --------------------------------------------------------------------------- | 451 // --------------------------------------------------------------------------- |
624 // Debugging. | 452 // Debugging. |
625 | 453 |
626 #ifdef DEBUG | 454 #ifdef DEBUG |
627 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively | 455 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively |
628 | 456 |
629 // Check that the scope has positions assigned. | 457 // Check that the scope has positions assigned. |
630 void CheckScopePositions(); | 458 void CheckScopePositions(); |
631 | 459 |
632 // Check that all Scopes in the scope tree use the same Zone. | 460 // Check that all Scopes in the scope tree use the same Zone. |
633 void CheckZones(); | 461 void CheckZones(); |
634 #endif | 462 #endif |
635 | 463 |
636 // --------------------------------------------------------------------------- | 464 // Retrieve `IsSimpleParameterList` of current or outer function. |
637 // Implementation. | 465 bool HasSimpleParameters(); |
466 | |
638 private: | 467 private: |
639 // Scope tree. | 468 // Scope tree. |
640 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL | 469 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL |
641 Scope* inner_scope_; // an inner scope of this scope | 470 Scope* inner_scope_; // an inner scope of this scope |
642 Scope* sibling_; // a sibling inner scope of the outer scope of this scope. | 471 Scope* sibling_; // a sibling inner scope of the outer scope of this scope. |
643 | 472 |
644 // Debugging support. | |
645 #ifdef DEBUG | |
646 const AstRawString* scope_name_; | |
647 #endif | |
648 | |
649 // The variables declared in this scope: | 473 // The variables declared in this scope: |
650 // | 474 // |
651 // All user-declared variables (incl. parameters). For script scopes | 475 // All user-declared variables (incl. parameters). For script scopes |
652 // variables may be implicitly 'declared' by being used (possibly in | 476 // variables may be implicitly 'declared' by being used (possibly in |
653 // an inner scope) with no intervening with statements or eval calls. | 477 // an inner scope) with no intervening with statements or eval calls. |
654 VariableMap variables_; | 478 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_; | |
661 // Variables that must be looked up dynamically. | 479 // Variables that must be looked up dynamically. |
662 DynamicScopePart* dynamics_; | 480 DynamicScopePart* dynamics_; |
663 // Unresolved variables referred to from this scope. The proxies themselves | 481 // Unresolved variables referred to from this scope. The proxies themselves |
664 // form a linked list of all unresolved proxies. | 482 // form a linked list of all unresolved proxies. |
665 VariableProxy* unresolved_; | 483 VariableProxy* unresolved_; |
666 // Declarations. | 484 // Declarations. |
667 ZoneList<Declaration*> decls_; | 485 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_; | |
680 | 486 |
681 // Map of function names to lists of functions defined in sloppy blocks | 487 // Serialized scope info support. |
682 SloppyBlockFunctionMap sloppy_block_function_map_; | 488 Handle<ScopeInfo> scope_info_; |
489 // Debugging support. | |
490 #ifdef DEBUG | |
491 const AstRawString* scope_name_; | |
492 #endif | |
493 | |
494 // Source positions. | |
495 int start_position_; | |
496 int end_position_; | |
497 | |
498 // Computed via AllocateVariables; function, block and catch scopes only. | |
499 int num_stack_slots_; | |
500 int num_heap_slots_; | |
501 int num_global_slots_; | |
683 | 502 |
684 // The scope type. | 503 // The scope type. |
685 const ScopeType scope_type_; | 504 const ScopeType scope_type_; |
686 // If the scope is a function scope, this is the function kind. | |
687 const FunctionKind function_kind_; | |
688 | 505 |
689 // Scope-specific information computed during parsing. | 506 // Scope-specific information computed during parsing. |
690 // | 507 // |
691 // The language mode of this scope. | 508 // The language mode of this scope. |
692 STATIC_ASSERT(LANGUAGE_END == 3); | 509 STATIC_ASSERT(LANGUAGE_END == 3); |
693 LanguageMode language_mode_ : 2; | 510 LanguageMode language_mode_ : 2; |
694 // This scope is inside a 'with' of some outer scope. | 511 // This scope is inside a 'with' of some outer scope. |
695 bool scope_inside_with_ : 1; | 512 bool scope_inside_with_ : 1; |
696 // This scope or a nested catch scope or with scope contain an 'eval' call. At | 513 // This scope or a nested catch scope or with scope contain an 'eval' call. At |
697 // the 'eval' call site this scope is the declaration scope. | 514 // the 'eval' call site this scope is the declaration scope. |
698 bool scope_calls_eval_ : 1; | 515 bool scope_calls_eval_ : 1; |
699 // This scope uses "super" property ('super.foo'). | 516 // This scope uses "super" property ('super.foo'). |
700 bool scope_uses_super_property_ : 1; | 517 bool scope_uses_super_property_ : 1; |
701 // This scope has a parameter called "arguments". | 518 // This scope has a parameter called "arguments". |
702 bool has_arguments_parameter_ : 1; | 519 bool has_arguments_parameter_ : 1; |
703 // This scope contains an "use asm" annotation. | 520 // This scope contains an "use asm" annotation. |
704 bool asm_module_ : 1; | 521 bool asm_module_ : 1; |
705 // This scope's outer context is an asm module. | 522 // This scope's outer context is an asm module. |
706 bool asm_function_ : 1; | 523 bool asm_function_ : 1; |
707 // This scope's declarations might not be executed in order (e.g., switch). | 524 // This scope's declarations might not be executed in order (e.g., switch). |
708 bool scope_nonlinear_ : 1; | 525 bool scope_nonlinear_ : 1; |
709 bool is_hidden_ : 1; | 526 bool is_hidden_ : 1; |
710 bool has_simple_parameters_ : 1; | |
711 | 527 |
712 // Computed via PropagateScopeInfo. | 528 // Computed via PropagateScopeInfo. |
713 bool outer_scope_calls_sloppy_eval_ : 1; | 529 bool outer_scope_calls_sloppy_eval_ : 1; |
714 bool inner_scope_calls_eval_ : 1; | 530 bool inner_scope_calls_eval_ : 1; |
715 bool force_eager_compilation_ : 1; | 531 bool force_eager_compilation_ : 1; |
716 bool force_context_allocation_ : 1; | 532 bool force_context_allocation_ : 1; |
717 | 533 |
718 // True if it doesn't need scope resolution (e.g., if the scope was | 534 // True if it doesn't need scope resolution (e.g., if the scope was |
719 // constructed based on a serialized scope info or a catch context). | 535 // constructed based on a serialized scope info or a catch context). |
720 bool already_resolved_ : 1; | 536 bool already_resolved_ : 1; |
721 bool already_resolved() { return already_resolved_; } | 537 bool already_resolved() { return already_resolved_; } |
722 | 538 |
723 // True if it holds 'var' declarations. | 539 // True if it holds 'var' declarations. |
724 bool is_declaration_scope_ : 1; | 540 bool is_declaration_scope_ : 1; |
725 | 541 |
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 | |
743 // Create a non-local variable with a given name. | 542 // Create a non-local variable with a given name. |
744 // These variables are looked up dynamically at runtime. | 543 // These variables are looked up dynamically at runtime. |
745 Variable* NonLocal(const AstRawString* name, VariableMode mode); | 544 Variable* NonLocal(const AstRawString* name, VariableMode mode); |
746 | 545 |
747 // Variable resolution. | 546 // Variable resolution. |
748 // Possible results of a recursive variable lookup telling if and how a | 547 // Possible results of a recursive variable lookup telling if and how a |
749 // variable is bound. These are returned in the output parameter *binding_kind | 548 // variable is bound. These are returned in the output parameter *binding_kind |
750 // of the LookupRecursive function. | 549 // of the LookupRecursive function. |
751 enum BindingKind { | 550 enum BindingKind { |
752 // The variable reference could be statically resolved to a variable binding | 551 // The variable reference could be statically resolved to a variable binding |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
798 AstNodeFactory* factory, | 597 AstNodeFactory* factory, |
799 Scope* max_outer_scope = nullptr); | 598 Scope* max_outer_scope = nullptr); |
800 MUST_USE_RESULT | 599 MUST_USE_RESULT |
801 bool ResolveVariable(ParseInfo* info, VariableProxy* proxy, | 600 bool ResolveVariable(ParseInfo* info, VariableProxy* proxy, |
802 AstNodeFactory* factory); | 601 AstNodeFactory* factory); |
803 MUST_USE_RESULT | 602 MUST_USE_RESULT |
804 bool ResolveVariablesRecursively(ParseInfo* info, AstNodeFactory* factory); | 603 bool ResolveVariablesRecursively(ParseInfo* info, AstNodeFactory* factory); |
805 | 604 |
806 // Tries to resolve local variables inside max_outer_scope; migrates those | 605 // Tries to resolve local variables inside max_outer_scope; migrates those |
807 // which cannot be resolved into migrate_to. | 606 // which cannot be resolved into migrate_to. |
808 void MigrateUnresolvableLocals(Scope* migrate_to, | 607 void MigrateUnresolvableLocals(DeclarationScope* migrate_to, |
809 AstNodeFactory* ast_node_factory, | 608 AstNodeFactory* ast_node_factory, |
810 Scope* max_outer_scope); | 609 DeclarationScope* max_outer_scope); |
811 | 610 |
812 // Scope analysis. | 611 // Scope analysis. |
813 void PropagateScopeInfo(bool outer_scope_calls_sloppy_eval); | 612 void PropagateScopeInfo(bool outer_scope_calls_sloppy_eval); |
814 bool HasTrivialContext() const; | 613 bool HasTrivialContext() const; |
815 | 614 |
816 // Predicates. | 615 // Predicates. |
817 bool MustAllocate(Variable* var); | 616 bool MustAllocate(Variable* var); |
818 bool MustAllocateInContext(Variable* var); | 617 bool MustAllocateInContext(Variable* var); |
819 | 618 |
820 // Variable allocation. | 619 // Variable allocation. |
821 void AllocateStackSlot(Variable* var); | 620 void AllocateStackSlot(Variable* var); |
822 void AllocateHeapSlot(Variable* var); | 621 void AllocateHeapSlot(Variable* var); |
823 void AllocateParameterLocals(); | |
824 void AllocateNonParameterLocal(Variable* var, | 622 void AllocateNonParameterLocal(Variable* var, |
825 AstValueFactory* ast_value_factory); | 623 AstValueFactory* ast_value_factory); |
826 void AllocateDeclaredGlobal(Variable* var, | 624 void AllocateDeclaredGlobal(Variable* var, |
827 AstValueFactory* ast_value_factory); | 625 AstValueFactory* ast_value_factory); |
828 void AllocateNonParameterLocalsAndDeclaredGlobals( | 626 void AllocateNonParameterLocalsAndDeclaredGlobals( |
829 AstValueFactory* ast_value_factory); | 627 AstValueFactory* ast_value_factory); |
830 void AllocateVariablesRecursively(AstValueFactory* ast_value_factory); | 628 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); | |
844 | 629 |
845 // Construct a scope based on the scope info. | 630 // Construct a scope based on the scope info. |
846 Scope(Zone* zone, Scope* inner_scope, ScopeType type, | 631 Scope(Zone* zone, Scope* inner_scope, ScopeType type, |
847 Handle<ScopeInfo> scope_info); | 632 Handle<ScopeInfo> scope_info); |
848 | 633 |
849 // Construct a catch scope with a binding for the name. | 634 // Construct a catch scope with a binding for the name. |
850 Scope(Zone* zone, Scope* inner_scope, | 635 Scope(Zone* zone, Scope* inner_scope, |
851 const AstRawString* catch_variable_name); | 636 const AstRawString* catch_variable_name); |
852 | 637 |
853 void AddInnerScope(Scope* inner_scope) { | 638 void AddInnerScope(Scope* inner_scope) { |
(...skipping 17 matching lines...) Expand all Loading... | |
871 return; | 656 return; |
872 } | 657 } |
873 } | 658 } |
874 } | 659 } |
875 | 660 |
876 void SetDefaults(); | 661 void SetDefaults(); |
877 | 662 |
878 void DeserializeScopeInfo(Isolate* isolate, | 663 void DeserializeScopeInfo(Isolate* isolate, |
879 AstValueFactory* ast_value_factory); | 664 AstValueFactory* ast_value_factory); |
880 | 665 |
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 bool has_simple_parameters_ : 1; | |
Toon Verwaest
2016/08/05 13:42:13
This is the actual change that valgrind was fallin
| |
881 | |
882 // Info about the parameter list of a function. | |
883 int arity_; | |
884 int rest_index_; | |
885 Variable* rest_parameter_; | |
886 // Compiler-allocated (user-invisible) temporaries. Due to the implementation | |
887 // of RemoveTemporary(), may contain nulls, which must be skipped-over during | |
888 // allocation and printing. | |
889 ZoneList<Variable*> temps_; | |
890 // Parameter list in source order. | |
891 ZoneList<Variable*> params_; | |
892 // Map of function names to lists of functions defined in sloppy blocks | |
893 SloppyBlockFunctionMap sloppy_block_function_map_; | |
894 // Convenience variable. | |
895 Variable* receiver_; | |
896 // Function variable, if any; function scopes only. | |
897 VariableDeclaration* function_; | |
898 // new.target variable, function scopes only. | |
899 Variable* new_target_; | |
900 // Convenience variable; function scopes only. | |
901 Variable* arguments_; | |
902 // Convenience variable; Subclass constructor only | |
903 Variable* this_function_; | |
904 // Module descriptor; module scopes only. | |
905 ModuleDescriptor* module_descriptor_; | |
881 PendingCompilationErrorHandler pending_error_handler_; | 906 PendingCompilationErrorHandler pending_error_handler_; |
882 }; | 907 }; |
883 | 908 |
884 } // namespace internal | 909 } // namespace internal |
885 } // namespace v8 | 910 } // namespace v8 |
886 | 911 |
887 #endif // V8_AST_SCOPES_H_ | 912 #endif // V8_AST_SCOPES_H_ |
OLD | NEW |