Chromium Code Reviews| 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 |