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 #include "src/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 76 p->value = new (zone_->New(sizeof(Vector))) Vector(zone_); | 76 p->value = new (zone_->New(sizeof(Vector))) Vector(zone_); |
| 77 } | 77 } |
| 78 Vector* delegates = static_cast<Vector*>(p->value); | 78 Vector* delegates = static_cast<Vector*>(p->value); |
| 79 delegates->push_back(stmt); | 79 delegates->push_back(stmt); |
| 80 } | 80 } |
| 81 | 81 |
| 82 | 82 |
| 83 // ---------------------------------------------------------------------------- | 83 // ---------------------------------------------------------------------------- |
| 84 // Implementation of Scope | 84 // Implementation of Scope |
| 85 | 85 |
| 86 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, | 86 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) |
| 87 FunctionKind function_kind) | |
| 88 : outer_scope_(outer_scope), | 87 : outer_scope_(outer_scope), |
| 89 variables_(zone), | 88 variables_(zone), |
| 90 temps_(4, zone), | |
| 91 params_(4, zone), | |
| 92 decls_(4, zone), | 89 decls_(4, zone), |
| 93 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone) | |
| 94 ModuleDescriptor(zone) | |
| 95 : NULL), | |
| 96 sloppy_block_function_map_(zone), | |
| 97 scope_type_(scope_type), | 90 scope_type_(scope_type), |
| 98 function_kind_(function_kind), | |
| 99 already_resolved_(false) { | 91 already_resolved_(false) { |
| 100 SetDefaults(); | 92 SetDefaults(); |
| 101 if (outer_scope == nullptr) { | 93 if (outer_scope == nullptr) { |
| 102 // If the outer scope is null, this cannot be a with scope. The outermost | 94 // If the outer scope is null, this cannot be a with scope. The outermost |
| 103 // scope must be a script scope. | 95 // scope must be a script scope. |
| 104 DCHECK_EQ(SCRIPT_SCOPE, scope_type); | 96 DCHECK_EQ(SCRIPT_SCOPE, scope_type); |
| 105 } else { | 97 } else { |
| 106 asm_function_ = outer_scope_->asm_module_; | 98 asm_function_ = outer_scope_->asm_module_; |
| 107 // Inherit the language mode from the parent scope unless we're a module | 99 // Inherit the language mode from the parent scope unless we're a module |
| 108 // scope. | 100 // scope. |
| 109 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_; | 101 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_; |
| 110 force_context_allocation_ = | 102 force_context_allocation_ = |
| 111 !is_function_scope() && outer_scope->has_forced_context_allocation(); | 103 !is_function_scope() && outer_scope->has_forced_context_allocation(); |
| 112 outer_scope_->AddInnerScope(this); | 104 outer_scope_->AddInnerScope(this); |
| 113 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); | 105 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); |
| 114 } | 106 } |
| 115 } | 107 } |
| 116 | 108 |
| 109 Scope::Snapshot::Snapshot(Scope* scope) | |
| 110 : outer_scope_(scope), | |
| 111 top_inner_scope_(scope->inner_scope_), | |
| 112 top_unresolved_(scope->unresolved_), | |
| 113 top_temp_(scope->GetClosureScope()->temps()->length()) {} | |
| 114 | |
| 115 DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope, | |
| 116 ScopeType scope_type, | |
| 117 FunctionKind function_kind) | |
| 118 : Scope(zone, outer_scope, scope_type), | |
| 119 function_kind_(function_kind), | |
| 120 temps_(4, zone), | |
| 121 params_(4, zone), | |
| 122 sloppy_block_function_map_(zone), | |
| 123 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone) | |
| 124 ModuleDescriptor(zone) | |
| 125 : NULL) { | |
| 126 SetDefaults(); | |
| 127 } | |
| 128 | |
| 117 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, | 129 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, |
| 118 Handle<ScopeInfo> scope_info) | 130 Handle<ScopeInfo> scope_info) |
| 119 : outer_scope_(nullptr), | 131 : outer_scope_(nullptr), |
| 120 variables_(zone), | 132 variables_(zone), |
| 121 temps_(4, zone), | |
| 122 params_(4, zone), | |
| 123 decls_(4, zone), | 133 decls_(4, zone), |
| 124 module_descriptor_(nullptr), | 134 scope_info_(scope_info), |
| 125 sloppy_block_function_map_(zone), | |
| 126 scope_type_(scope_type), | 135 scope_type_(scope_type), |
| 127 function_kind_(scope_info.is_null() ? kNormalFunction | 136 already_resolved_(true) { |
| 128 : scope_info->function_kind()), | |
| 129 already_resolved_(true), | |
| 130 scope_info_(scope_info) { | |
| 131 SetDefaults(); | 137 SetDefaults(); |
| 132 if (!scope_info.is_null()) { | 138 if (!scope_info.is_null()) { |
| 133 scope_calls_eval_ = scope_info->CallsEval(); | 139 scope_calls_eval_ = scope_info->CallsEval(); |
| 134 language_mode_ = scope_info->language_mode(); | 140 language_mode_ = scope_info->language_mode(); |
| 135 is_declaration_scope_ = scope_info->is_declaration_scope(); | |
| 136 num_heap_slots_ = scope_info_->ContextLength(); | 141 num_heap_slots_ = scope_info_->ContextLength(); |
| 137 } | 142 } |
| 138 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 143 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
| 139 num_heap_slots_ = Max(num_heap_slots_, | 144 num_heap_slots_ = Max(num_heap_slots_, |
| 140 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 145 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
| 141 AddInnerScope(inner_scope); | 146 AddInnerScope(inner_scope); |
| 142 } | 147 } |
| 143 | 148 |
| 149 DeclarationScope::DeclarationScope(Zone* zone, Scope* inner_scope, | |
| 150 ScopeType scope_type, | |
| 151 Handle<ScopeInfo> scope_info) | |
| 152 : Scope(zone, inner_scope, scope_type, scope_info), | |
| 153 function_kind_(scope_info.is_null() ? kNormalFunction | |
| 154 : scope_info->function_kind()), | |
| 155 temps_(4, zone), | |
| 156 params_(4, zone), | |
| 157 sloppy_block_function_map_(zone), | |
| 158 module_descriptor_(nullptr) { | |
| 159 SetDefaults(); | |
| 160 } | |
| 161 | |
| 144 Scope::Scope(Zone* zone, Scope* inner_scope, | 162 Scope::Scope(Zone* zone, Scope* inner_scope, |
| 145 const AstRawString* catch_variable_name) | 163 const AstRawString* catch_variable_name) |
| 146 : outer_scope_(nullptr), | 164 : outer_scope_(nullptr), |
| 147 variables_(zone), | 165 variables_(zone), |
| 148 temps_(0, zone), | |
| 149 params_(0, zone), | |
| 150 decls_(0, zone), | 166 decls_(0, zone), |
| 151 module_descriptor_(nullptr), | |
| 152 sloppy_block_function_map_(zone), | |
| 153 scope_type_(CATCH_SCOPE), | 167 scope_type_(CATCH_SCOPE), |
| 154 function_kind_(kNormalFunction), | |
| 155 already_resolved_(true) { | 168 already_resolved_(true) { |
| 156 SetDefaults(); | 169 SetDefaults(); |
| 157 AddInnerScope(inner_scope); | 170 AddInnerScope(inner_scope); |
| 158 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 171 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
| 159 Variable* variable = variables_.Declare(this, | 172 Variable* variable = variables_.Declare(this, |
| 160 catch_variable_name, | 173 catch_variable_name, |
| 161 VAR, | 174 VAR, |
| 162 Variable::NORMAL, | 175 Variable::NORMAL, |
| 163 kCreatedInitialized); | 176 kCreatedInitialized); |
| 164 AllocateHeapSlot(variable); | 177 AllocateHeapSlot(variable); |
| 165 } | 178 } |
| 166 | 179 |
| 167 void Scope::SetDefaults() { | 180 void DeclarationScope::SetDefaults() { |
| 168 is_declaration_scope_ = | 181 is_declaration_scope_ = true; |
| 169 is_eval_scope() || is_function_scope() || | 182 has_simple_parameters_ = true; |
| 170 is_module_scope() || is_script_scope(); | |
| 171 inner_scope_ = nullptr; | |
| 172 sibling_ = nullptr; | |
| 173 unresolved_ = nullptr; | |
| 174 #ifdef DEBUG | |
| 175 scope_name_ = nullptr; | |
| 176 #endif | |
| 177 dynamics_ = nullptr; | |
| 178 receiver_ = nullptr; | 183 receiver_ = nullptr; |
| 179 new_target_ = nullptr; | 184 new_target_ = nullptr; |
| 180 function_ = nullptr; | 185 function_ = nullptr; |
| 181 arguments_ = nullptr; | 186 arguments_ = nullptr; |
| 182 this_function_ = nullptr; | 187 this_function_ = nullptr; |
| 183 scope_inside_with_ = false; | 188 arity_ = 0; |
| 184 scope_calls_eval_ = false; | 189 rest_parameter_ = NULL; |
| 185 has_arguments_parameter_ = false; | 190 rest_index_ = -1; |
| 186 scope_uses_super_property_ = false; | 191 } |
| 187 asm_module_ = false; | 192 |
| 188 asm_function_ = false; | 193 void Scope::SetDefaults() { |
| 189 language_mode_ = is_module_scope() ? STRICT : SLOPPY; | 194 #ifdef DEBUG |
| 190 outer_scope_calls_sloppy_eval_ = false; | 195 scope_name_ = nullptr; |
| 191 inner_scope_calls_eval_ = false; | 196 #endif |
| 192 scope_nonlinear_ = false; | 197 inner_scope_ = nullptr; |
| 193 force_eager_compilation_ = false; | 198 sibling_ = nullptr; |
| 194 force_context_allocation_ = false; | 199 unresolved_ = nullptr; |
| 200 dynamics_ = nullptr; | |
| 201 | |
|
Toon Verwaest
2016/08/05 13:42:13
Here just shuffling around to put in the same orde
| |
| 202 start_position_ = kNoSourcePosition; | |
| 203 end_position_ = kNoSourcePosition; | |
| 204 | |
| 195 num_stack_slots_ = 0; | 205 num_stack_slots_ = 0; |
| 196 num_heap_slots_ = 0; | 206 num_heap_slots_ = 0; |
| 197 num_global_slots_ = 0; | 207 num_global_slots_ = 0; |
| 198 arity_ = 0; | 208 |
| 199 has_simple_parameters_ = true; | 209 language_mode_ = is_module_scope() ? STRICT : SLOPPY; |
| 200 rest_parameter_ = NULL; | 210 |
| 201 rest_index_ = -1; | 211 scope_inside_with_ = false; |
| 202 start_position_ = kNoSourcePosition; | 212 scope_calls_eval_ = false; |
| 203 end_position_ = kNoSourcePosition; | 213 scope_uses_super_property_ = false; |
| 214 has_arguments_parameter_ = false; | |
| 215 asm_module_ = false; | |
| 216 asm_function_ = false; | |
| 217 scope_nonlinear_ = false; | |
| 204 is_hidden_ = false; | 218 is_hidden_ = false; |
| 219 | |
| 220 outer_scope_calls_sloppy_eval_ = false; | |
| 221 inner_scope_calls_eval_ = false; | |
| 222 force_eager_compilation_ = false; | |
| 223 force_context_allocation_ = false; | |
| 224 | |
| 225 is_declaration_scope_ = false; | |
| 226 } | |
| 227 | |
| 228 bool Scope::HasSimpleParameters() { | |
| 229 DeclarationScope* scope = GetClosureScope(); | |
| 230 return !scope->is_function_scope() || scope->has_simple_parameters(); | |
| 205 } | 231 } |
| 206 | 232 |
| 207 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 233 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
| 208 Context* context, Scope* script_scope, | 234 Context* context, |
| 235 DeclarationScope* script_scope, | |
| 209 AstValueFactory* ast_value_factory, | 236 AstValueFactory* ast_value_factory, |
| 210 DeserializationMode deserialization_mode) { | 237 DeserializationMode deserialization_mode) { |
| 211 // Reconstruct the outer scope chain from a closure's context chain. | 238 // Reconstruct the outer scope chain from a closure's context chain. |
| 212 Scope* current_scope = NULL; | 239 Scope* current_scope = NULL; |
| 213 Scope* innermost_scope = NULL; | 240 Scope* innermost_scope = NULL; |
| 214 while (!context->IsNativeContext()) { | 241 while (!context->IsNativeContext()) { |
| 215 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { | 242 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { |
| 216 // For scope analysis, debug-evaluate is equivalent to a with scope. | 243 // For scope analysis, debug-evaluate is equivalent to a with scope. |
| 217 Scope* with_scope = new (zone) | 244 Scope* with_scope = new (zone) |
| 218 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); | 245 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); |
| 219 current_scope = with_scope; | 246 current_scope = with_scope; |
| 220 // All the inner scopes are inside a with. | 247 // All the inner scopes are inside a with. |
| 221 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { | 248 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { |
| 222 s->scope_inside_with_ = true; | 249 s->scope_inside_with_ = true; |
| 223 } | 250 } |
| 224 } else if (context->IsScriptContext()) { | 251 } else if (context->IsScriptContext()) { |
| 225 ScopeInfo* scope_info = context->scope_info(); | 252 ScopeInfo* scope_info = context->scope_info(); |
| 226 current_scope = new (zone) Scope(zone, current_scope, SCRIPT_SCOPE, | 253 current_scope = new (zone) DeclarationScope( |
| 227 Handle<ScopeInfo>(scope_info)); | 254 zone, current_scope, SCRIPT_SCOPE, Handle<ScopeInfo>(scope_info)); |
| 228 } else if (context->IsFunctionContext()) { | 255 } else if (context->IsFunctionContext()) { |
| 229 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | 256 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
| 230 current_scope = new (zone) Scope(zone, current_scope, FUNCTION_SCOPE, | 257 current_scope = new (zone) DeclarationScope( |
| 231 Handle<ScopeInfo>(scope_info)); | 258 zone, current_scope, FUNCTION_SCOPE, Handle<ScopeInfo>(scope_info)); |
| 232 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; | 259 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; |
| 233 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; | 260 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; |
| 234 } else if (context->IsBlockContext()) { | 261 } else if (context->IsBlockContext()) { |
| 235 ScopeInfo* scope_info = context->scope_info(); | 262 ScopeInfo* scope_info = context->scope_info(); |
| 236 current_scope = new (zone) Scope(zone, current_scope, BLOCK_SCOPE, | 263 if (scope_info->is_declaration_scope()) { |
| 237 Handle<ScopeInfo>(scope_info)); | 264 current_scope = new (zone) DeclarationScope( |
| 265 zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info)); | |
| 266 } else { | |
| 267 current_scope = new (zone) Scope(zone, current_scope, BLOCK_SCOPE, | |
| 268 Handle<ScopeInfo>(scope_info)); | |
| 269 } | |
| 238 } else { | 270 } else { |
| 239 DCHECK(context->IsCatchContext()); | 271 DCHECK(context->IsCatchContext()); |
| 240 String* name = context->catch_name(); | 272 String* name = context->catch_name(); |
| 241 current_scope = | 273 current_scope = |
| 242 new (zone) Scope(zone, current_scope, | 274 new (zone) Scope(zone, current_scope, |
| 243 ast_value_factory->GetString(handle(name, isolate))); | 275 ast_value_factory->GetString(handle(name, isolate))); |
| 244 } | 276 } |
| 245 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { | 277 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { |
| 246 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); | 278 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); |
| 247 } | 279 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 312 Handle<String> name_handle(scope_info_->FunctionName(), isolate); | 344 Handle<String> name_handle(scope_info_->FunctionName(), isolate); |
| 313 const AstRawString* name = ast_value_factory->GetString(name_handle); | 345 const AstRawString* name = ast_value_factory->GetString(name_handle); |
| 314 VariableMode mode; | 346 VariableMode mode; |
| 315 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode); | 347 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode); |
| 316 if (index >= 0) { | 348 if (index >= 0) { |
| 317 Variable* result = new (zone()) | 349 Variable* result = new (zone()) |
| 318 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); | 350 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); |
| 319 VariableProxy* proxy = factory.NewVariableProxy(result); | 351 VariableProxy* proxy = factory.NewVariableProxy(result); |
| 320 VariableDeclaration* declaration = | 352 VariableDeclaration* declaration = |
| 321 factory.NewVariableDeclaration(proxy, mode, this, kNoSourcePosition); | 353 factory.NewVariableDeclaration(proxy, mode, this, kNoSourcePosition); |
| 322 DeclareFunctionVar(declaration); | 354 AsDeclarationScope()->DeclareFunctionVar(declaration); |
| 323 result->AllocateTo(VariableLocation::CONTEXT, index); | 355 result->AllocateTo(VariableLocation::CONTEXT, index); |
| 324 } | 356 } |
| 325 } | 357 } |
| 326 | 358 |
| 327 scope_info_ = Handle<ScopeInfo>::null(); | 359 scope_info_ = Handle<ScopeInfo>::null(); |
| 328 } | 360 } |
| 329 | 361 |
| 362 DeclarationScope* Scope::AsDeclarationScope() { | |
| 363 DCHECK(is_declaration_scope()); | |
| 364 return static_cast<DeclarationScope*>(this); | |
| 365 } | |
| 366 | |
| 367 const DeclarationScope* Scope::AsDeclarationScope() const { | |
| 368 DCHECK(is_declaration_scope()); | |
| 369 return static_cast<const DeclarationScope*>(this); | |
| 370 } | |
| 371 | |
| 372 int Scope::num_parameters() const { | |
| 373 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; | |
| 374 } | |
| 375 | |
| 330 bool Scope::Analyze(ParseInfo* info) { | 376 bool Scope::Analyze(ParseInfo* info) { |
| 331 DCHECK(info->literal() != NULL); | 377 DCHECK(info->literal() != NULL); |
| 332 DCHECK(info->scope() == NULL); | 378 DCHECK(info->scope() == NULL); |
| 333 Scope* scope = info->literal()->scope(); | 379 DeclarationScope* scope = info->literal()->scope(); |
| 334 Scope* top = scope; | 380 DeclarationScope* top = scope; |
| 335 | 381 |
| 336 // Traverse the scope tree up to the first unresolved scope or the global | 382 // Traverse the scope tree up to the first unresolved scope or the global |
| 337 // scope and start scope resolution and variable allocation from that scope. | 383 // scope and start scope resolution and variable allocation from that scope. |
| 384 // Such a scope is always a closure-scope, so always skip to the next closure | |
| 385 // scope. | |
| 338 while (!top->is_script_scope() && | 386 while (!top->is_script_scope() && |
| 339 !top->outer_scope()->already_resolved()) { | 387 !top->outer_scope()->already_resolved()) { |
| 340 top = top->outer_scope(); | 388 top = top->outer_scope()->GetClosureScope(); |
| 341 } | 389 } |
| 342 | 390 |
| 343 // Allocate the variables. | 391 // Allocate the variables. |
| 344 { | 392 { |
| 345 AstNodeFactory ast_node_factory(info->ast_value_factory()); | 393 AstNodeFactory ast_node_factory(info->ast_value_factory()); |
| 346 if (!top->AllocateVariables(info, &ast_node_factory)) { | 394 if (!top->AllocateVariables(info, &ast_node_factory)) return false; |
| 347 DCHECK(top->pending_error_handler_.has_pending_error()); | |
| 348 top->pending_error_handler_.ThrowPendingError(info->isolate(), | |
| 349 info->script()); | |
| 350 return false; | |
| 351 } | |
| 352 } | 395 } |
| 353 | 396 |
| 354 #ifdef DEBUG | 397 #ifdef DEBUG |
| 355 if (info->script_is_native() ? FLAG_print_builtin_scopes | 398 if (info->script_is_native() ? FLAG_print_builtin_scopes |
| 356 : FLAG_print_scopes) { | 399 : FLAG_print_scopes) { |
| 357 scope->Print(); | 400 scope->Print(); |
| 358 } | 401 } |
| 359 scope->CheckScopePositions(); | 402 scope->CheckScopePositions(); |
| 360 scope->CheckZones(); | 403 scope->CheckZones(); |
| 361 #endif | 404 #endif |
| 362 | 405 |
| 363 info->set_scope(scope); | 406 info->set_scope(scope); |
| 364 return true; | 407 return true; |
| 365 } | 408 } |
| 366 | 409 |
| 367 void Scope::DeclareThis(AstValueFactory* ast_value_factory) { | 410 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { |
| 368 DCHECK(!already_resolved()); | 411 DCHECK(!already_resolved()); |
| 369 DCHECK(is_declaration_scope()); | 412 DCHECK(is_declaration_scope()); |
| 370 DCHECK(has_this_declaration()); | 413 DCHECK(has_this_declaration()); |
| 371 | 414 |
| 372 bool subclass_constructor = IsSubclassConstructor(function_kind_); | 415 bool subclass_constructor = IsSubclassConstructor(function_kind_); |
| 373 Variable* var = variables_.Declare( | 416 Variable* var = variables_.Declare( |
| 374 this, ast_value_factory->this_string(), | 417 this, ast_value_factory->this_string(), |
| 375 subclass_constructor ? CONST : VAR, Variable::THIS, | 418 subclass_constructor ? CONST : VAR, Variable::THIS, |
| 376 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | 419 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
| 377 receiver_ = var; | 420 receiver_ = var; |
| 378 } | 421 } |
| 379 | 422 |
| 380 void Scope::DeclareDefaultFunctionVariables( | 423 void DeclarationScope::DeclareDefaultFunctionVariables( |
| 381 AstValueFactory* ast_value_factory) { | 424 AstValueFactory* ast_value_factory) { |
| 382 DCHECK(is_function_scope()); | 425 DCHECK(is_function_scope()); |
| 383 DCHECK(!is_arrow_scope()); | 426 DCHECK(!is_arrow_scope()); |
| 384 // Declare 'arguments' variable which exists in all non arrow functions. | 427 // Declare 'arguments' variable which exists in all non arrow functions. |
| 385 // Note that it might never be accessed, in which case it won't be | 428 // Note that it might never be accessed, in which case it won't be |
| 386 // allocated during variable allocation. | 429 // allocated during variable allocation. |
| 387 arguments_ = | 430 arguments_ = |
| 388 variables_.Declare(this, ast_value_factory->arguments_string(), VAR, | 431 variables_.Declare(this, ast_value_factory->arguments_string(), VAR, |
| 389 Variable::ARGUMENTS, kCreatedInitialized); | 432 Variable::ARGUMENTS, kCreatedInitialized); |
| 390 | 433 |
| 391 new_target_ = | 434 new_target_ = |
| 392 variables_.Declare(this, ast_value_factory->new_target_string(), CONST, | 435 variables_.Declare(this, ast_value_factory->new_target_string(), CONST, |
| 393 Variable::NORMAL, kCreatedInitialized); | 436 Variable::NORMAL, kCreatedInitialized); |
| 394 | 437 |
| 395 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || | 438 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || |
| 396 IsAccessorFunction(function_kind_)) { | 439 IsAccessorFunction(function_kind_)) { |
| 397 this_function_ = | 440 this_function_ = |
| 398 variables_.Declare(this, ast_value_factory->this_function_string(), | 441 variables_.Declare(this, ast_value_factory->this_function_string(), |
| 399 CONST, Variable::NORMAL, kCreatedInitialized); | 442 CONST, Variable::NORMAL, kCreatedInitialized); |
| 400 } | 443 } |
| 401 } | 444 } |
| 402 | 445 |
| 403 | 446 |
| 404 Scope* Scope::FinalizeBlockScope() { | 447 Scope* Scope::FinalizeBlockScope() { |
| 405 DCHECK(is_block_scope()); | 448 DCHECK(is_block_scope()); |
| 406 DCHECK(temps_.is_empty()); | |
| 407 DCHECK(params_.is_empty()); | |
| 408 | 449 |
| 409 if (variables_.occupancy() > 0 || | 450 if (variables_.occupancy() > 0 || |
| 410 (is_declaration_scope() && calls_sloppy_eval())) { | 451 (is_declaration_scope() && calls_sloppy_eval())) { |
| 411 return this; | 452 return this; |
| 412 } | 453 } |
| 413 | 454 |
| 414 // Remove this scope from outer scope. | 455 // Remove this scope from outer scope. |
| 415 outer_scope()->RemoveInnerScope(this); | 456 outer_scope()->RemoveInnerScope(this); |
| 416 | 457 |
| 417 // Reparent inner scopes. | 458 // Reparent inner scopes. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 438 } | 479 } |
| 439 outer_scope()->unresolved_ = unresolved_; | 480 outer_scope()->unresolved_ = unresolved_; |
| 440 unresolved_ = nullptr; | 481 unresolved_ = nullptr; |
| 441 } | 482 } |
| 442 | 483 |
| 443 PropagateUsageFlagsToScope(outer_scope_); | 484 PropagateUsageFlagsToScope(outer_scope_); |
| 444 | 485 |
| 445 return NULL; | 486 return NULL; |
| 446 } | 487 } |
| 447 | 488 |
| 448 void Scope::Snapshot::Reparent(Scope* new_parent) const { | 489 void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const { |
| 449 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); | 490 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); |
| 450 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); | 491 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); |
| 451 DCHECK_EQ(new_parent, new_parent->ClosureScope()); | 492 DCHECK_EQ(new_parent, new_parent->GetClosureScope()); |
| 452 DCHECK_NULL(new_parent->inner_scope_); | 493 DCHECK_NULL(new_parent->inner_scope_); |
| 453 DCHECK_NULL(new_parent->unresolved_); | 494 DCHECK_NULL(new_parent->unresolved_); |
| 454 DCHECK_EQ(0, new_parent->temps_.length()); | 495 DCHECK_EQ(0, new_parent->temps()->length()); |
| 455 Scope* inner_scope = new_parent->sibling_; | 496 Scope* inner_scope = new_parent->sibling_; |
| 456 if (inner_scope != top_inner_scope_) { | 497 if (inner_scope != top_inner_scope_) { |
| 457 for (; inner_scope->sibling() != top_inner_scope_; | 498 for (; inner_scope->sibling() != top_inner_scope_; |
| 458 inner_scope = inner_scope->sibling()) { | 499 inner_scope = inner_scope->sibling()) { |
| 459 inner_scope->outer_scope_ = new_parent; | 500 inner_scope->outer_scope_ = new_parent; |
| 460 DCHECK_NE(inner_scope, new_parent); | 501 DCHECK_NE(inner_scope, new_parent); |
| 461 } | 502 } |
| 462 inner_scope->outer_scope_ = new_parent; | 503 inner_scope->outer_scope_ = new_parent; |
| 463 | 504 |
| 464 new_parent->inner_scope_ = new_parent->sibling_; | 505 new_parent->inner_scope_ = new_parent->sibling_; |
| 465 inner_scope->sibling_ = nullptr; | 506 inner_scope->sibling_ = nullptr; |
| 466 // Reset the sibling rather than the inner_scope_ since we | 507 // Reset the sibling rather than the inner_scope_ since we |
| 467 // want to keep new_parent there. | 508 // want to keep new_parent there. |
| 468 new_parent->sibling_ = top_inner_scope_; | 509 new_parent->sibling_ = top_inner_scope_; |
| 469 } | 510 } |
| 470 | 511 |
| 471 if (outer_scope_->unresolved_ != top_unresolved_) { | 512 if (outer_scope_->unresolved_ != top_unresolved_) { |
| 472 VariableProxy* last = outer_scope_->unresolved_; | 513 VariableProxy* last = outer_scope_->unresolved_; |
| 473 while (last->next_unresolved() != top_unresolved_) { | 514 while (last->next_unresolved() != top_unresolved_) { |
| 474 last = last->next_unresolved(); | 515 last = last->next_unresolved(); |
| 475 } | 516 } |
| 476 last->set_next_unresolved(nullptr); | 517 last->set_next_unresolved(nullptr); |
| 477 new_parent->unresolved_ = outer_scope_->unresolved_; | 518 new_parent->unresolved_ = outer_scope_->unresolved_; |
| 478 outer_scope_->unresolved_ = top_unresolved_; | 519 outer_scope_->unresolved_ = top_unresolved_; |
| 479 } | 520 } |
| 480 | 521 |
| 481 if (outer_scope_->ClosureScope()->temps_.length() != top_temp_) { | 522 if (outer_scope_->GetClosureScope()->temps()->length() != top_temp_) { |
| 482 ZoneList<Variable*>* temps = &outer_scope_->ClosureScope()->temps_; | 523 ZoneList<Variable*>* temps = outer_scope_->GetClosureScope()->temps(); |
| 483 for (int i = top_temp_; i < temps->length(); i++) { | 524 for (int i = top_temp_; i < temps->length(); i++) { |
| 484 Variable* temp = temps->at(i); | 525 Variable* temp = temps->at(i); |
| 485 DCHECK_EQ(temp->scope(), temp->scope()->ClosureScope()); | 526 DCHECK_EQ(temp->scope(), temp->scope()->GetClosureScope()); |
| 486 DCHECK_NE(temp->scope(), new_parent); | 527 DCHECK_NE(temp->scope(), new_parent); |
| 487 temp->set_scope(new_parent); | 528 temp->set_scope(new_parent); |
| 488 new_parent->AddTemporary(temp); | 529 new_parent->AddTemporary(temp); |
| 489 } | 530 } |
| 490 temps->Rewind(top_temp_); | 531 temps->Rewind(top_temp_); |
| 491 } | 532 } |
| 492 } | 533 } |
| 493 | 534 |
| 494 void Scope::ReplaceOuterScope(Scope* outer) { | 535 void Scope::ReplaceOuterScope(Scope* outer) { |
| 495 DCHECK_NOT_NULL(outer); | 536 DCHECK_NOT_NULL(outer); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 562 } | 603 } |
| 563 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and | 604 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and |
| 564 // ARGUMENTS bindings as their corresponding Variable::Kind. | 605 // ARGUMENTS bindings as their corresponding Variable::Kind. |
| 565 | 606 |
| 566 Variable* var = variables_.Declare(this, name, mode, kind, init_flag, | 607 Variable* var = variables_.Declare(this, name, mode, kind, init_flag, |
| 567 maybe_assigned_flag); | 608 maybe_assigned_flag); |
| 568 var->AllocateTo(location, index); | 609 var->AllocateTo(location, index); |
| 569 return var; | 610 return var; |
| 570 } | 611 } |
| 571 | 612 |
| 572 | 613 Variable* DeclarationScope::LookupFunctionVar(const AstRawString* name, |
| 573 Variable* Scope::LookupFunctionVar(const AstRawString* name, | 614 AstNodeFactory* factory) { |
| 574 AstNodeFactory* factory) { | |
| 575 if (function_ != NULL && function_->proxy()->raw_name() == name) { | 615 if (function_ != NULL && function_->proxy()->raw_name() == name) { |
| 576 return function_->proxy()->var(); | 616 return function_->proxy()->var(); |
| 577 } else if (!scope_info_.is_null()) { | 617 } else if (!scope_info_.is_null()) { |
| 578 // If we are backed by a scope info, try to lookup the variable there. | 618 // If we are backed by a scope info, try to lookup the variable there. |
| 579 VariableMode mode; | 619 VariableMode mode; |
| 580 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); | 620 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); |
| 581 if (index < 0) return NULL; | 621 if (index < 0) return NULL; |
| 582 Variable* var = new (zone()) | 622 Variable* var = new (zone()) |
| 583 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); | 623 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); |
| 584 DCHECK_NOT_NULL(factory); | 624 DCHECK_NOT_NULL(factory); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 598 Variable* Scope::Lookup(const AstRawString* name) { | 638 Variable* Scope::Lookup(const AstRawString* name) { |
| 599 for (Scope* scope = this; | 639 for (Scope* scope = this; |
| 600 scope != NULL; | 640 scope != NULL; |
| 601 scope = scope->outer_scope()) { | 641 scope = scope->outer_scope()) { |
| 602 Variable* var = scope->LookupLocal(name); | 642 Variable* var = scope->LookupLocal(name); |
| 603 if (var != NULL) return var; | 643 if (var != NULL) return var; |
| 604 } | 644 } |
| 605 return NULL; | 645 return NULL; |
| 606 } | 646 } |
| 607 | 647 |
| 608 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, | 648 Variable* DeclarationScope::DeclareParameter( |
| 609 bool is_optional, bool is_rest, | 649 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, |
| 610 bool* is_duplicate, | 650 bool* is_duplicate, AstValueFactory* ast_value_factory) { |
| 611 AstValueFactory* ast_value_factory) { | |
| 612 DCHECK(!already_resolved()); | 651 DCHECK(!already_resolved()); |
| 613 DCHECK(is_function_scope()); | 652 DCHECK(is_function_scope()); |
| 614 DCHECK(!is_optional || !is_rest); | 653 DCHECK(!is_optional || !is_rest); |
| 615 Variable* var; | 654 Variable* var; |
| 616 if (mode == TEMPORARY) { | 655 if (mode == TEMPORARY) { |
| 617 var = NewTemporary(name); | 656 var = NewTemporary(name); |
| 618 } else { | 657 } else { |
| 619 var = variables_.Declare(this, name, mode, Variable::NORMAL, | 658 var = variables_.Declare(this, name, mode, Variable::NORMAL, |
| 620 kCreatedInitialized); | 659 kCreatedInitialized); |
| 621 // TODO(wingo): Avoid O(n^2) check. | 660 // TODO(wingo): Avoid O(n^2) check. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 641 MaybeAssignedFlag maybe_assigned_flag) { | 680 MaybeAssignedFlag maybe_assigned_flag) { |
| 642 DCHECK(!already_resolved()); | 681 DCHECK(!already_resolved()); |
| 643 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 682 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
| 644 // introduced during variable allocation, and TEMPORARY variables are | 683 // introduced during variable allocation, and TEMPORARY variables are |
| 645 // allocated via NewTemporary(). | 684 // allocated via NewTemporary(). |
| 646 DCHECK(IsDeclaredVariableMode(mode)); | 685 DCHECK(IsDeclaredVariableMode(mode)); |
| 647 return variables_.Declare(this, name, mode, kind, init_flag, | 686 return variables_.Declare(this, name, mode, kind, init_flag, |
| 648 maybe_assigned_flag); | 687 maybe_assigned_flag); |
| 649 } | 688 } |
| 650 | 689 |
| 651 | 690 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name) { |
| 652 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { | |
| 653 DCHECK(is_script_scope()); | 691 DCHECK(is_script_scope()); |
| 654 return variables_.Declare(this, | 692 return variables_.Declare(this, |
| 655 name, | 693 name, |
| 656 DYNAMIC_GLOBAL, | 694 DYNAMIC_GLOBAL, |
| 657 Variable::NORMAL, | 695 Variable::NORMAL, |
| 658 kCreatedInitialized); | 696 kCreatedInitialized); |
| 659 } | 697 } |
| 660 | 698 |
| 661 | 699 |
| 662 bool Scope::RemoveUnresolved(VariableProxy* var) { | 700 bool Scope::RemoveUnresolved(VariableProxy* var) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 674 return true; | 712 return true; |
| 675 } | 713 } |
| 676 current = next; | 714 current = next; |
| 677 } | 715 } |
| 678 return false; | 716 return false; |
| 679 } | 717 } |
| 680 | 718 |
| 681 | 719 |
| 682 Variable* Scope::NewTemporary(const AstRawString* name) { | 720 Variable* Scope::NewTemporary(const AstRawString* name) { |
| 683 DCHECK(!already_resolved()); | 721 DCHECK(!already_resolved()); |
| 684 Scope* scope = this->ClosureScope(); | 722 DeclarationScope* scope = GetClosureScope(); |
| 685 Variable* var = new(zone()) Variable(scope, | 723 Variable* var = new(zone()) Variable(scope, |
| 686 name, | 724 name, |
| 687 TEMPORARY, | 725 TEMPORARY, |
| 688 Variable::NORMAL, | 726 Variable::NORMAL, |
| 689 kCreatedInitialized); | 727 kCreatedInitialized); |
| 690 scope->AddTemporary(var); | 728 scope->AddTemporary(var); |
| 691 return var; | 729 return var; |
| 692 } | 730 } |
| 693 | 731 |
| 694 int Scope::RemoveTemporary(Variable* var) { | 732 int DeclarationScope::RemoveTemporary(Variable* var) { |
| 695 DCHECK_NOT_NULL(var); | 733 DCHECK_NOT_NULL(var); |
| 696 // Temporaries are only placed in ClosureScopes. | 734 // Temporaries are only placed in ClosureScopes. |
| 697 DCHECK_EQ(ClosureScope(), this); | 735 DCHECK_EQ(GetClosureScope(), this); |
| 698 DCHECK_EQ(var->scope()->ClosureScope(), var->scope()); | 736 DCHECK_EQ(var->scope()->GetClosureScope(), var->scope()); |
| 699 // If the temporary is not here, return quickly. | 737 // If the temporary is not here, return quickly. |
| 700 if (var->scope() != this) return -1; | 738 if (var->scope() != this) return -1; |
| 701 // Most likely (always?) any temporary variable we want to remove | 739 // Most likely (always?) any temporary variable we want to remove |
| 702 // was just added before, so we search backwards. | 740 // was just added before, so we search backwards. |
| 703 for (int i = temps_.length(); i-- > 0;) { | 741 for (int i = temps_.length(); i-- > 0;) { |
| 704 if (temps_[i] == var) { | 742 if (temps_[i] == var) { |
| 705 // Don't shrink temps_, as callers of this method expect | 743 // Don't shrink temps_, as callers of this method expect |
| 706 // the returned indices to be unique per-scope. | 744 // the returned indices to be unique per-scope. |
| 707 temps_[i] = nullptr; | 745 temps_[i] = nullptr; |
| 708 return i; | 746 return i; |
| 709 } | 747 } |
| 710 } | 748 } |
| 711 return -1; | 749 return -1; |
| 712 } | 750 } |
| 713 | 751 |
| 714 | 752 |
| 715 void Scope::AddDeclaration(Declaration* declaration) { | 753 void Scope::AddDeclaration(Declaration* declaration) { |
| 716 decls_.Add(declaration, zone()); | 754 decls_.Add(declaration, zone()); |
| 717 } | 755 } |
| 718 | 756 |
| 719 | 757 |
| 720 Declaration* Scope::CheckConflictingVarDeclarations() { | 758 Declaration* Scope::CheckConflictingVarDeclarations() { |
| 721 int length = decls_.length(); | 759 int length = decls_.length(); |
| 722 for (int i = 0; i < length; i++) { | 760 for (int i = 0; i < length; i++) { |
| 723 Declaration* decl = decls_[i]; | 761 Declaration* decl = decls_[i]; |
| 724 // We don't create a separate scope to hold the function name of a function | 762 // We don't create a separate scope to hold the function name of a function |
| 725 // expression, so we have to make sure not to consider it when checking for | 763 // expression, so we have to make sure not to consider it when checking for |
| 726 // conflicts (since it's conceptually "outside" the declaration scope). | 764 // conflicts (since it's conceptually "outside" the declaration scope). |
| 727 if (is_function_scope() && decl == function()) continue; | 765 if (is_function_scope() && decl == AsDeclarationScope()->function()) |
| 766 continue; | |
| 728 if (IsLexicalVariableMode(decl->mode()) && !is_block_scope()) continue; | 767 if (IsLexicalVariableMode(decl->mode()) && !is_block_scope()) continue; |
| 729 const AstRawString* name = decl->proxy()->raw_name(); | 768 const AstRawString* name = decl->proxy()->raw_name(); |
| 730 | 769 |
| 731 // Iterate through all scopes until and including the declaration scope. | 770 // Iterate through all scopes until and including the declaration scope. |
| 732 Scope* previous = NULL; | 771 Scope* previous = NULL; |
| 733 Scope* current = decl->scope(); | 772 Scope* current = decl->scope(); |
| 734 // Lexical vs lexical conflicts within the same scope have already been | 773 // Lexical vs lexical conflicts within the same scope have already been |
| 735 // captured in Parser::Declare. The only conflicts we still need to check | 774 // captured in Parser::Declare. The only conflicts we still need to check |
| 736 // are lexical vs VAR, or any declarations within a declaration block scope | 775 // are lexical vs VAR, or any declarations within a declaration block scope |
| 737 // vs lexical declarations in its surrounding (function) scope. | 776 // vs lexical declarations in its surrounding (function) scope. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 785 | 824 |
| 786 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, | 825 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, |
| 787 ZoneList<Variable*>* context_locals, | 826 ZoneList<Variable*>* context_locals, |
| 788 ZoneList<Variable*>* context_globals) { | 827 ZoneList<Variable*>* context_globals) { |
| 789 DCHECK(stack_locals != NULL); | 828 DCHECK(stack_locals != NULL); |
| 790 DCHECK(context_locals != NULL); | 829 DCHECK(context_locals != NULL); |
| 791 DCHECK(context_globals != NULL); | 830 DCHECK(context_globals != NULL); |
| 792 | 831 |
| 793 // Collect temporaries which are always allocated on the stack, unless the | 832 // Collect temporaries which are always allocated on the stack, unless the |
| 794 // context as a whole has forced context allocation. | 833 // context as a whole has forced context allocation. |
| 795 for (int i = 0; i < temps_.length(); i++) { | 834 if (is_declaration_scope()) { |
| 796 Variable* var = temps_[i]; | 835 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); |
| 797 if (var == nullptr) continue; | 836 for (int i = 0; i < temps->length(); i++) { |
| 798 if (var->is_used()) { | 837 Variable* var = (*temps)[i]; |
| 799 if (var->IsContextSlot()) { | 838 if (var == nullptr) continue; |
| 800 DCHECK(has_forced_context_allocation()); | 839 if (var->is_used()) { |
| 801 context_locals->Add(var, zone()); | 840 if (var->IsContextSlot()) { |
| 802 } else if (var->IsStackLocal()) { | 841 DCHECK(has_forced_context_allocation()); |
| 803 stack_locals->Add(var, zone()); | 842 context_locals->Add(var, zone()); |
| 804 } else { | 843 } else if (var->IsStackLocal()) { |
| 805 DCHECK(var->IsParameter()); | 844 stack_locals->Add(var, zone()); |
| 845 } else { | |
| 846 DCHECK(var->IsParameter()); | |
| 847 } | |
| 806 } | 848 } |
| 807 } | 849 } |
| 808 } | 850 } |
| 809 | 851 |
| 810 // Collect declared local variables. | 852 // Collect declared local variables. |
| 811 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 853 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
| 812 for (VariableMap::Entry* p = variables_.Start(); | 854 for (VariableMap::Entry* p = variables_.Start(); |
| 813 p != NULL; | 855 p != NULL; |
| 814 p = variables_.Next(p)) { | 856 p = variables_.Next(p)) { |
| 815 Variable* var = reinterpret_cast<Variable*>(p->value); | 857 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 816 if (var->is_used()) { | 858 if (var->is_used()) { |
| 817 vars.Add(VarAndOrder(var, p->order), zone()); | 859 vars.Add(VarAndOrder(var, p->order), zone()); |
| 818 } | 860 } |
| 819 } | 861 } |
| 820 vars.Sort(VarAndOrder::Compare); | 862 vars.Sort(VarAndOrder::Compare); |
| 821 int var_count = vars.length(); | 863 int var_count = vars.length(); |
| 822 for (int i = 0; i < var_count; i++) { | 864 for (int i = 0; i < var_count; i++) { |
| 823 Variable* var = vars[i].var(); | 865 Variable* var = vars[i].var(); |
| 824 if (var->IsStackLocal()) { | 866 if (var->IsStackLocal()) { |
| 825 stack_locals->Add(var, zone()); | 867 stack_locals->Add(var, zone()); |
| 826 } else if (var->IsContextSlot()) { | 868 } else if (var->IsContextSlot()) { |
| 827 context_locals->Add(var, zone()); | 869 context_locals->Add(var, zone()); |
| 828 } else if (var->IsGlobalSlot()) { | 870 } else if (var->IsGlobalSlot()) { |
| 829 context_globals->Add(var, zone()); | 871 context_globals->Add(var, zone()); |
| 830 } | 872 } |
| 831 } | 873 } |
| 832 } | 874 } |
| 833 | 875 |
| 834 bool Scope::AllocateVariables(ParseInfo* info, AstNodeFactory* factory) { | 876 bool DeclarationScope::AllocateVariables(ParseInfo* info, |
| 877 AstNodeFactory* factory) { | |
| 835 // 1) Propagate scope information. | 878 // 1) Propagate scope information. |
| 836 bool outer_scope_calls_sloppy_eval = false; | 879 bool outer_scope_calls_sloppy_eval = false; |
| 837 if (outer_scope_ != NULL) { | 880 if (outer_scope_ != NULL) { |
| 838 outer_scope_calls_sloppy_eval = | 881 outer_scope_calls_sloppy_eval = |
| 839 outer_scope_->outer_scope_calls_sloppy_eval() | | 882 outer_scope_->outer_scope_calls_sloppy_eval() | |
| 840 outer_scope_->calls_sloppy_eval(); | 883 outer_scope_->calls_sloppy_eval(); |
| 841 } | 884 } |
| 842 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | 885 PropagateScopeInfo(outer_scope_calls_sloppy_eval); |
| 843 | 886 |
| 844 // 2) Resolve variables. | 887 // 2) Resolve variables. |
| 845 if (!ResolveVariablesRecursively(info, factory)) return false; | 888 if (!ResolveVariablesRecursively(info, factory)) { |
| 889 DCHECK(pending_error_handler_.has_pending_error()); | |
| 890 pending_error_handler_.ThrowPendingError(info->isolate(), info->script()); | |
| 891 return false; | |
| 892 } | |
| 846 | 893 |
| 847 // 3) Allocate variables. | 894 // 3) Allocate variables. |
| 848 AllocateVariablesRecursively(info->ast_value_factory()); | 895 AllocateVariablesRecursively(info->ast_value_factory()); |
| 849 | 896 |
| 850 return true; | 897 return true; |
| 851 } | 898 } |
| 852 | 899 |
| 853 | 900 |
| 854 bool Scope::HasTrivialContext() const { | 901 bool Scope::HasTrivialContext() const { |
| 855 // A function scope has a trivial context if it always is the global | 902 // A function scope has a trivial context if it always is the global |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 910 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 957 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 911 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), | 958 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), |
| 912 max_context_chain_length); | 959 max_context_chain_length); |
| 913 } | 960 } |
| 914 if (NeedsContext()) { | 961 if (NeedsContext()) { |
| 915 max_context_chain_length += 1; | 962 max_context_chain_length += 1; |
| 916 } | 963 } |
| 917 return max_context_chain_length; | 964 return max_context_chain_length; |
| 918 } | 965 } |
| 919 | 966 |
| 920 | 967 DeclarationScope* Scope::GetDeclarationScope() { |
| 921 Scope* Scope::DeclarationScope() { | |
| 922 Scope* scope = this; | 968 Scope* scope = this; |
| 923 while (!scope->is_declaration_scope()) { | 969 while (!scope->is_declaration_scope()) { |
| 924 scope = scope->outer_scope(); | 970 scope = scope->outer_scope(); |
| 925 } | 971 } |
| 926 return scope; | 972 return scope->AsDeclarationScope(); |
| 927 } | 973 } |
| 928 | 974 |
| 929 | 975 DeclarationScope* Scope::GetClosureScope() { |
| 930 Scope* Scope::ClosureScope() { | |
| 931 Scope* scope = this; | 976 Scope* scope = this; |
| 932 while (!scope->is_declaration_scope() || scope->is_block_scope()) { | 977 while (!scope->is_declaration_scope() || scope->is_block_scope()) { |
| 933 scope = scope->outer_scope(); | 978 scope = scope->outer_scope(); |
| 934 } | 979 } |
| 935 return scope; | 980 return scope->AsDeclarationScope(); |
| 981 } | |
| 982 | |
| 983 DeclarationScope* Scope::GetReceiverScope() { | |
| 984 Scope* scope = this; | |
| 985 while (!scope->is_script_scope() && | |
| 986 (!scope->is_function_scope() || | |
| 987 scope->AsDeclarationScope()->is_arrow_scope())) { | |
| 988 scope = scope->outer_scope(); | |
| 989 } | |
| 990 return scope->AsDeclarationScope(); | |
| 936 } | 991 } |
| 937 | 992 |
| 938 | 993 |
| 939 Scope* Scope::ReceiverScope() { | |
| 940 Scope* scope = this; | |
| 941 while (!scope->is_script_scope() && | |
| 942 (!scope->is_function_scope() || scope->is_arrow_scope())) { | |
| 943 scope = scope->outer_scope(); | |
| 944 } | |
| 945 return scope; | |
| 946 } | |
| 947 | |
| 948 | |
| 949 | 994 |
| 950 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { | 995 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { |
| 951 if (scope_info_.is_null()) { | 996 if (scope_info_.is_null()) { |
| 952 scope_info_ = ScopeInfo::Create(isolate, zone(), this); | 997 scope_info_ = ScopeInfo::Create(isolate, zone(), this); |
| 953 } | 998 } |
| 954 return scope_info_; | 999 return scope_info_; |
| 955 } | 1000 } |
| 956 | 1001 |
| 957 Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) { | 1002 Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) { |
| 958 // Collect non-local variables referenced in the scope. | 1003 // Collect non-local variables referenced in the scope. |
| 959 // TODO(yangguo): store non-local variables explicitly if we can no longer | 1004 // TODO(yangguo): store non-local variables explicitly if we can no longer |
| 960 // rely on unresolved_ to find them. | 1005 // rely on unresolved_ to find them. |
| 961 for (VariableProxy* proxy = unresolved_; proxy != nullptr; | 1006 for (VariableProxy* proxy = unresolved_; proxy != nullptr; |
| 962 proxy = proxy->next_unresolved()) { | 1007 proxy = proxy->next_unresolved()) { |
| 963 if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue; | 1008 if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue; |
| 964 Handle<String> name = proxy->name(); | 1009 Handle<String> name = proxy->name(); |
| 965 non_locals = StringSet::Add(non_locals, name); | 1010 non_locals = StringSet::Add(non_locals, name); |
| 966 } | 1011 } |
| 967 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1012 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 968 non_locals = scope->CollectNonLocals(non_locals); | 1013 non_locals = scope->CollectNonLocals(non_locals); |
| 969 } | 1014 } |
| 970 return non_locals; | 1015 return non_locals; |
| 971 } | 1016 } |
| 972 | 1017 |
| 973 void Scope::AnalyzePartially(Scope* migrate_to, | 1018 void DeclarationScope::AnalyzePartially(DeclarationScope* migrate_to, |
| 974 AstNodeFactory* ast_node_factory) { | 1019 AstNodeFactory* ast_node_factory) { |
| 975 // Gather info from inner scopes. | 1020 // Gather info from inner scopes. |
| 976 PropagateScopeInfo(false); | 1021 PropagateScopeInfo(false); |
| 977 | 1022 |
| 978 // Try to resolve unresolved variables for this Scope and migrate those which | 1023 // Try to resolve unresolved variables for this Scope and migrate those which |
| 979 // cannot be resolved inside. It doesn't make sense to try to resolve them in | 1024 // cannot be resolved inside. It doesn't make sense to try to resolve them in |
| 980 // the outer Scopes here, because they are incomplete. | 1025 // the outer Scopes here, because they are incomplete. |
| 981 MigrateUnresolvableLocals(migrate_to, ast_node_factory, this); | 1026 MigrateUnresolvableLocals(migrate_to, ast_node_factory, this); |
| 982 | 1027 |
| 983 // Push scope data up to migrate_to. Note that migrate_to and this Scope | 1028 // Push scope data up to migrate_to. Note that migrate_to and this Scope |
| 984 // describe the same Scope, just in different Zones. | 1029 // describe the same Scope, just in different Zones. |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1084 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { | 1129 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { |
| 1085 Variable* var = reinterpret_cast<Variable*>(p->value); | 1130 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 1086 if (var == NULL) { | 1131 if (var == NULL) { |
| 1087 Indent(indent, "<?>\n"); | 1132 Indent(indent, "<?>\n"); |
| 1088 } else { | 1133 } else { |
| 1089 PrintVar(indent, var); | 1134 PrintVar(indent, var); |
| 1090 } | 1135 } |
| 1091 } | 1136 } |
| 1092 } | 1137 } |
| 1093 | 1138 |
| 1139 void DeclarationScope::PrintParameters() { | |
| 1140 PrintF(" ("); | |
| 1141 for (int i = 0; i < params_.length(); i++) { | |
| 1142 if (i > 0) PrintF(", "); | |
| 1143 const AstRawString* name = params_[i]->raw_name(); | |
| 1144 if (name->IsEmpty()) | |
| 1145 PrintF(".%p", reinterpret_cast<void*>(params_[i])); | |
| 1146 else | |
| 1147 PrintName(name); | |
| 1148 } | |
| 1149 PrintF(")"); | |
| 1150 } | |
| 1094 | 1151 |
| 1095 void Scope::Print(int n) { | 1152 void Scope::Print(int n) { |
| 1096 int n0 = (n > 0 ? n : 0); | 1153 int n0 = (n > 0 ? n : 0); |
| 1097 int n1 = n0 + 2; // indentation | 1154 int n1 = n0 + 2; // indentation |
| 1098 | 1155 |
| 1099 // Print header. | 1156 // Print header. |
| 1100 Indent(n0, Header(scope_type_, function_kind_, is_declaration_scope())); | 1157 FunctionKind function_kind = is_function_scope() |
| 1158 ? AsDeclarationScope()->function_kind() | |
| 1159 : kNormalFunction; | |
| 1160 Indent(n0, Header(scope_type_, function_kind, is_declaration_scope())); | |
| 1101 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) { | 1161 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) { |
| 1102 PrintF(" "); | 1162 PrintF(" "); |
| 1103 PrintName(scope_name_); | 1163 PrintName(scope_name_); |
| 1104 } | 1164 } |
| 1105 | 1165 |
| 1106 // Print parameters, if any. | 1166 // Print parameters, if any. |
| 1167 VariableDeclaration* function = nullptr; | |
| 1107 if (is_function_scope()) { | 1168 if (is_function_scope()) { |
| 1108 PrintF(" ("); | 1169 AsDeclarationScope()->PrintParameters(); |
| 1109 for (int i = 0; i < params_.length(); i++) { | 1170 function = AsDeclarationScope()->function(); |
| 1110 if (i > 0) PrintF(", "); | |
| 1111 const AstRawString* name = params_[i]->raw_name(); | |
| 1112 if (name->IsEmpty()) | |
| 1113 PrintF(".%p", reinterpret_cast<void*>(params_[i])); | |
| 1114 else | |
| 1115 PrintName(name); | |
| 1116 } | |
| 1117 PrintF(")"); | |
| 1118 } | 1171 } |
| 1119 | 1172 |
| 1120 PrintF(" { // (%d, %d)\n", start_position(), end_position()); | 1173 PrintF(" { // (%d, %d)\n", start_position(), end_position()); |
| 1121 | 1174 |
| 1122 // Function name, if any (named function literals, only). | 1175 // Function name, if any (named function literals, only). |
| 1123 if (function_ != NULL) { | 1176 if (function != nullptr) { |
| 1124 Indent(n1, "// (local) function name: "); | 1177 Indent(n1, "// (local) function name: "); |
| 1125 PrintName(function_->proxy()->raw_name()); | 1178 PrintName(function->proxy()->raw_name()); |
| 1126 PrintF("\n"); | 1179 PrintF("\n"); |
| 1127 } | 1180 } |
| 1128 | 1181 |
| 1129 // Scope info. | 1182 // Scope info. |
| 1130 if (HasTrivialOuterContext()) { | 1183 if (HasTrivialOuterContext()) { |
| 1131 Indent(n1, "// scope has trivial outer context\n"); | 1184 Indent(n1, "// scope has trivial outer context\n"); |
| 1132 } | 1185 } |
| 1133 if (is_strict(language_mode())) { | 1186 if (is_strict(language_mode())) { |
| 1134 Indent(n1, "// strict mode scope\n"); | 1187 Indent(n1, "// strict mode scope\n"); |
| 1135 } | 1188 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1147 Indent(n1, "// "); | 1200 Indent(n1, "// "); |
| 1148 PrintF("%d stack slots\n", num_stack_slots_); | 1201 PrintF("%d stack slots\n", num_stack_slots_); |
| 1149 } | 1202 } |
| 1150 if (num_heap_slots_ > 0) { | 1203 if (num_heap_slots_ > 0) { |
| 1151 Indent(n1, "// "); | 1204 Indent(n1, "// "); |
| 1152 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, | 1205 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, |
| 1153 num_global_slots_); | 1206 num_global_slots_); |
| 1154 } | 1207 } |
| 1155 | 1208 |
| 1156 // Print locals. | 1209 // Print locals. |
| 1157 if (function_ != NULL) { | 1210 if (function != nullptr) { |
| 1158 Indent(n1, "// function var:\n"); | 1211 Indent(n1, "// function var:\n"); |
| 1159 PrintVar(n1, function_->proxy()->var()); | 1212 PrintVar(n1, function->proxy()->var()); |
| 1160 } | 1213 } |
| 1161 | 1214 |
| 1162 if (temps_.length() > 0) { | 1215 if (is_declaration_scope()) { |
| 1163 bool printed_header = false; | 1216 bool printed_header = false; |
| 1164 for (int i = 0; i < temps_.length(); i++) { | 1217 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); |
| 1165 if (temps_[i] != nullptr) { | 1218 for (int i = 0; i < temps->length(); i++) { |
| 1219 if ((*temps)[i] != nullptr) { | |
| 1166 if (!printed_header) { | 1220 if (!printed_header) { |
| 1167 printed_header = true; | 1221 printed_header = true; |
| 1168 Indent(n1, "// temporary vars:\n"); | 1222 Indent(n1, "// temporary vars:\n"); |
| 1169 } | 1223 } |
| 1170 PrintVar(n1, temps_[i]); | 1224 PrintVar(n1, (*temps)[i]); |
| 1171 } | 1225 } |
| 1172 } | 1226 } |
| 1173 } | 1227 } |
| 1174 | 1228 |
| 1175 if (variables_.Start() != NULL) { | 1229 if (variables_.Start() != NULL) { |
| 1176 Indent(n1, "// local vars:\n"); | 1230 Indent(n1, "// local vars:\n"); |
| 1177 PrintMap(n1, &variables_); | 1231 PrintMap(n1, &variables_); |
| 1178 } | 1232 } |
| 1179 | 1233 |
| 1180 if (dynamics_ != NULL) { | 1234 if (dynamics_ != NULL) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1251 Variable* var = LookupLocal(proxy->raw_name()); | 1305 Variable* var = LookupLocal(proxy->raw_name()); |
| 1252 | 1306 |
| 1253 // We found a variable and we are done. (Even if there is an 'eval' in | 1307 // We found a variable and we are done. (Even if there is an 'eval' in |
| 1254 // this scope which introduces the same variable again, the resulting | 1308 // this scope which introduces the same variable again, the resulting |
| 1255 // variable remains the same.) | 1309 // variable remains the same.) |
| 1256 if (var != NULL) { | 1310 if (var != NULL) { |
| 1257 *binding_kind = BOUND; | 1311 *binding_kind = BOUND; |
| 1258 return var; | 1312 return var; |
| 1259 } | 1313 } |
| 1260 | 1314 |
| 1261 // We did not find a variable locally. Check against the function variable, | 1315 // We did not find a variable locally. Check against the function variable, if |
| 1262 // if any. We can do this for all scopes, since the function variable is | 1316 // any. |
| 1263 // only present - if at all - for function scopes. | |
| 1264 *binding_kind = UNBOUND; | 1317 *binding_kind = UNBOUND; |
| 1265 var = LookupFunctionVar(proxy->raw_name(), factory); | 1318 var = |
| 1319 is_function_scope() | |
| 1320 ? AsDeclarationScope()->LookupFunctionVar(proxy->raw_name(), factory) | |
| 1321 : nullptr; | |
| 1266 if (var != NULL) { | 1322 if (var != NULL) { |
| 1267 *binding_kind = BOUND; | 1323 *binding_kind = BOUND; |
| 1268 } else if (outer_scope_ != nullptr && this != max_outer_scope) { | 1324 } else if (outer_scope_ != nullptr && this != max_outer_scope) { |
| 1269 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, | 1325 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, |
| 1270 max_outer_scope); | 1326 max_outer_scope); |
| 1271 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { | 1327 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { |
| 1272 var->ForceContextAllocation(); | 1328 var->ForceContextAllocation(); |
| 1273 } | 1329 } |
| 1274 } else { | 1330 } else { |
| 1275 DCHECK(is_script_scope() || this == max_outer_scope); | 1331 DCHECK(is_script_scope() || this == max_outer_scope); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1398 } | 1454 } |
| 1399 | 1455 |
| 1400 // Resolve unresolved variables for inner scopes. | 1456 // Resolve unresolved variables for inner scopes. |
| 1401 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1457 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 1402 if (!scope->ResolveVariablesRecursively(info, factory)) return false; | 1458 if (!scope->ResolveVariablesRecursively(info, factory)) return false; |
| 1403 } | 1459 } |
| 1404 | 1460 |
| 1405 return true; | 1461 return true; |
| 1406 } | 1462 } |
| 1407 | 1463 |
| 1408 void Scope::MigrateUnresolvableLocals(Scope* migrate_to, | 1464 void Scope::MigrateUnresolvableLocals(DeclarationScope* migrate_to, |
| 1409 AstNodeFactory* ast_node_factory, | 1465 AstNodeFactory* ast_node_factory, |
| 1410 Scope* max_outer_scope) { | 1466 DeclarationScope* max_outer_scope) { |
| 1411 BindingKind binding_kind; | 1467 BindingKind binding_kind; |
| 1412 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; | 1468 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; |
| 1413 proxy = next) { | 1469 proxy = next) { |
| 1414 next = proxy->next_unresolved(); | 1470 next = proxy->next_unresolved(); |
| 1415 // Note that we pass nullptr as AstNodeFactory: this phase should not create | 1471 // Note that we pass nullptr as AstNodeFactory: this phase should not create |
| 1416 // any new AstNodes, since none of the Scopes involved are backed up by | 1472 // any new AstNodes, since none of the Scopes involved are backed up by |
| 1417 // ScopeInfo. | 1473 // ScopeInfo. |
| 1418 if (LookupRecursive(proxy, &binding_kind, nullptr, max_outer_scope) == | 1474 if (LookupRecursive(proxy, &binding_kind, nullptr, max_outer_scope) == |
| 1419 nullptr) { | 1475 nullptr) { |
| 1420 // Re-create the VariableProxies in the right Zone and insert them into | 1476 // Re-create the VariableProxies in the right Zone and insert them into |
| 1421 // migrate_to. | 1477 // migrate_to. |
| 1422 DCHECK(!proxy->is_resolved()); | 1478 DCHECK(!proxy->is_resolved()); |
| 1423 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); | 1479 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); |
| 1424 migrate_to->AddUnresolved(copy); | 1480 migrate_to->AddUnresolved(copy); |
| 1425 } | 1481 } |
| 1426 } | 1482 } |
| 1427 | 1483 |
| 1428 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1484 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 1429 scope->MigrateUnresolvableLocals(migrate_to, ast_node_factory, | 1485 scope->MigrateUnresolvableLocals(migrate_to, ast_node_factory, |
| 1430 max_outer_scope); | 1486 max_outer_scope); |
| 1431 } | 1487 } |
| 1432 } | 1488 } |
| 1433 | 1489 |
| 1434 void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) { | 1490 void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval) { |
| 1435 if (outer_scope_calls_sloppy_eval) { | 1491 if (outer_scope_calls_sloppy_eval) { |
| 1436 outer_scope_calls_sloppy_eval_ = true; | 1492 outer_scope_calls_sloppy_eval_ = true; |
| 1437 } | 1493 } |
| 1438 | 1494 |
| 1439 bool calls_sloppy_eval = | 1495 bool calls_sloppy_eval = |
| 1440 this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_; | 1496 this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_; |
| 1441 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { | 1497 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { |
| 1442 inner->PropagateScopeInfo(calls_sloppy_eval); | 1498 inner->PropagateScopeInfo(calls_sloppy_eval); |
| 1443 if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) { | 1499 if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) { |
| 1444 inner_scope_calls_eval_ = true; | 1500 inner_scope_calls_eval_ = true; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1483 if (var->mode() == TEMPORARY) return false; | 1539 if (var->mode() == TEMPORARY) return false; |
| 1484 if (is_catch_scope() || is_module_scope()) return true; | 1540 if (is_catch_scope() || is_module_scope()) return true; |
| 1485 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; | 1541 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; |
| 1486 return var->has_forced_context_allocation() || scope_calls_eval_ || | 1542 return var->has_forced_context_allocation() || scope_calls_eval_ || |
| 1487 inner_scope_calls_eval_; | 1543 inner_scope_calls_eval_; |
| 1488 } | 1544 } |
| 1489 | 1545 |
| 1490 | 1546 |
| 1491 void Scope::AllocateStackSlot(Variable* var) { | 1547 void Scope::AllocateStackSlot(Variable* var) { |
| 1492 if (is_block_scope()) { | 1548 if (is_block_scope()) { |
| 1493 outer_scope()->DeclarationScope()->AllocateStackSlot(var); | 1549 outer_scope()->GetDeclarationScope()->AllocateStackSlot(var); |
| 1494 } else { | 1550 } else { |
| 1495 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); | 1551 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); |
| 1496 } | 1552 } |
| 1497 } | 1553 } |
| 1498 | 1554 |
| 1499 | 1555 |
| 1500 void Scope::AllocateHeapSlot(Variable* var) { | 1556 void Scope::AllocateHeapSlot(Variable* var) { |
| 1501 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); | 1557 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); |
| 1502 } | 1558 } |
| 1503 | 1559 |
| 1504 void Scope::AllocateParameterLocals() { | 1560 void DeclarationScope::AllocateParameterLocals() { |
| 1505 DCHECK(is_function_scope()); | 1561 DCHECK(is_function_scope()); |
| 1506 | 1562 |
| 1507 bool uses_sloppy_arguments = false; | 1563 bool uses_sloppy_arguments = false; |
| 1508 | 1564 |
| 1509 // Functions have 'arguments' declared implicitly in all non arrow functions. | 1565 // Functions have 'arguments' declared implicitly in all non arrow functions. |
| 1510 if (arguments_ != nullptr) { | 1566 if (arguments_ != nullptr) { |
| 1511 // 'arguments' is used. Unless there is also a parameter called | 1567 // 'arguments' is used. Unless there is also a parameter called |
| 1512 // 'arguments', we must be conservative and allocate all parameters to | 1568 // 'arguments', we must be conservative and allocate all parameters to |
| 1513 // the context assuming they will be captured by the arguments object. | 1569 // the context assuming they will be captured by the arguments object. |
| 1514 // If we have a parameter named 'arguments', a (new) value is always | 1570 // If we have a parameter named 'arguments', a (new) value is always |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1547 | 1603 |
| 1548 DCHECK(var->scope() == this); | 1604 DCHECK(var->scope() == this); |
| 1549 if (uses_sloppy_arguments || has_forced_context_allocation()) { | 1605 if (uses_sloppy_arguments || has_forced_context_allocation()) { |
| 1550 // Force context allocation of the parameter. | 1606 // Force context allocation of the parameter. |
| 1551 var->ForceContextAllocation(); | 1607 var->ForceContextAllocation(); |
| 1552 } | 1608 } |
| 1553 AllocateParameter(var, i); | 1609 AllocateParameter(var, i); |
| 1554 } | 1610 } |
| 1555 } | 1611 } |
| 1556 | 1612 |
| 1557 | 1613 void DeclarationScope::AllocateParameter(Variable* var, int index) { |
| 1558 void Scope::AllocateParameter(Variable* var, int index) { | |
| 1559 if (MustAllocate(var)) { | 1614 if (MustAllocate(var)) { |
| 1560 if (MustAllocateInContext(var)) { | 1615 if (MustAllocateInContext(var)) { |
| 1561 DCHECK(var->IsUnallocated() || var->IsContextSlot()); | 1616 DCHECK(var->IsUnallocated() || var->IsContextSlot()); |
| 1562 if (var->IsUnallocated()) { | 1617 if (var->IsUnallocated()) { |
| 1563 AllocateHeapSlot(var); | 1618 AllocateHeapSlot(var); |
| 1564 } | 1619 } |
| 1565 } else { | 1620 } else { |
| 1566 DCHECK(var->IsUnallocated() || var->IsParameter()); | 1621 DCHECK(var->IsUnallocated() || var->IsParameter()); |
| 1567 if (var->IsUnallocated()) { | 1622 if (var->IsUnallocated()) { |
| 1568 var->AllocateTo(VariableLocation::PARAMETER, index); | 1623 var->AllocateTo(VariableLocation::PARAMETER, index); |
| 1569 } | 1624 } |
| 1570 } | 1625 } |
| 1571 } else { | 1626 } else { |
| 1572 DCHECK(!var->IsGlobalSlot()); | 1627 DCHECK(!var->IsGlobalSlot()); |
| 1573 } | 1628 } |
| 1574 } | 1629 } |
| 1575 | 1630 |
| 1576 | 1631 void DeclarationScope::AllocateReceiver() { |
| 1577 void Scope::AllocateReceiver() { | 1632 if (!has_this_declaration()) return; |
| 1578 DCHECK_NOT_NULL(receiver()); | 1633 DCHECK_NOT_NULL(receiver()); |
| 1579 DCHECK_EQ(receiver()->scope(), this); | 1634 DCHECK_EQ(receiver()->scope(), this); |
| 1580 | 1635 |
| 1581 if (has_forced_context_allocation()) { | 1636 if (has_forced_context_allocation()) { |
| 1582 // Force context allocation of the receiver. | 1637 // Force context allocation of the receiver. |
| 1583 receiver()->ForceContextAllocation(); | 1638 receiver()->ForceContextAllocation(); |
| 1584 } | 1639 } |
| 1585 AllocateParameter(receiver(), -1); | 1640 AllocateParameter(receiver(), -1); |
| 1586 } | 1641 } |
| 1587 | 1642 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1613 } else { | 1668 } else { |
| 1614 // There must be only DYNAMIC_GLOBAL in the script scope. | 1669 // There must be only DYNAMIC_GLOBAL in the script scope. |
| 1615 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); | 1670 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); |
| 1616 } | 1671 } |
| 1617 } | 1672 } |
| 1618 } | 1673 } |
| 1619 | 1674 |
| 1620 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals( | 1675 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals( |
| 1621 AstValueFactory* ast_value_factory) { | 1676 AstValueFactory* ast_value_factory) { |
| 1622 // All variables that have no rewrite yet are non-parameter locals. | 1677 // All variables that have no rewrite yet are non-parameter locals. |
| 1623 for (int i = 0; i < temps_.length(); i++) { | 1678 if (is_declaration_scope()) { |
| 1624 if (temps_[i] == nullptr) continue; | 1679 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); |
| 1625 AllocateNonParameterLocal(temps_[i], ast_value_factory); | 1680 for (int i = 0; i < temps->length(); i++) { |
| 1681 if ((*temps)[i] == nullptr) continue; | |
| 1682 AllocateNonParameterLocal((*temps)[i], ast_value_factory); | |
| 1683 } | |
| 1626 } | 1684 } |
| 1627 | 1685 |
| 1628 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 1686 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
| 1629 for (VariableMap::Entry* p = variables_.Start(); | 1687 for (VariableMap::Entry* p = variables_.Start(); |
| 1630 p != NULL; | 1688 p != NULL; |
| 1631 p = variables_.Next(p)) { | 1689 p = variables_.Next(p)) { |
| 1632 Variable* var = reinterpret_cast<Variable*>(p->value); | 1690 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 1633 vars.Add(VarAndOrder(var, p->order), zone()); | 1691 vars.Add(VarAndOrder(var, p->order), zone()); |
| 1634 } | 1692 } |
| 1635 vars.Sort(VarAndOrder::Compare); | 1693 vars.Sort(VarAndOrder::Compare); |
| 1636 int var_count = vars.length(); | 1694 int var_count = vars.length(); |
| 1637 for (int i = 0; i < var_count; i++) { | 1695 for (int i = 0; i < var_count; i++) { |
| 1638 AllocateNonParameterLocal(vars[i].var(), ast_value_factory); | 1696 AllocateNonParameterLocal(vars[i].var(), ast_value_factory); |
| 1639 } | 1697 } |
| 1640 | 1698 |
| 1641 if (FLAG_global_var_shortcuts) { | 1699 if (FLAG_global_var_shortcuts) { |
| 1642 for (int i = 0; i < var_count; i++) { | 1700 for (int i = 0; i < var_count; i++) { |
| 1643 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory); | 1701 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory); |
| 1644 } | 1702 } |
| 1645 } | 1703 } |
| 1646 | 1704 |
| 1705 if (is_declaration_scope()) { | |
| 1706 AsDeclarationScope()->AllocateLocals(ast_value_factory); | |
| 1707 } | |
| 1708 } | |
| 1709 | |
| 1710 void DeclarationScope::AllocateLocals(AstValueFactory* ast_value_factory) { | |
| 1647 // For now, function_ must be allocated at the very end. If it gets | 1711 // For now, function_ must be allocated at the very end. If it gets |
| 1648 // allocated in the context, it must be the last slot in the context, | 1712 // allocated in the context, it must be the last slot in the context, |
| 1649 // because of the current ScopeInfo implementation (see | 1713 // because of the current ScopeInfo implementation (see |
| 1650 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1714 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
| 1651 if (function_ != nullptr) { | 1715 if (function_ != nullptr) { |
| 1652 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory); | 1716 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory); |
| 1653 } | 1717 } |
| 1654 | 1718 |
| 1655 if (rest_parameter_ != nullptr) { | 1719 if (rest_parameter_ != nullptr) { |
| 1656 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); | 1720 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1675 } | 1739 } |
| 1676 | 1740 |
| 1677 // If scope is already resolved, we still need to allocate | 1741 // If scope is already resolved, we still need to allocate |
| 1678 // variables in inner scopes which might not have been resolved yet. | 1742 // variables in inner scopes which might not have been resolved yet. |
| 1679 if (already_resolved()) return; | 1743 if (already_resolved()) return; |
| 1680 // The number of slots required for variables. | 1744 // The number of slots required for variables. |
| 1681 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 1745 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
| 1682 | 1746 |
| 1683 // Allocate variables for this scope. | 1747 // Allocate variables for this scope. |
| 1684 // Parameters must be allocated first, if any. | 1748 // Parameters must be allocated first, if any. |
| 1685 if (is_function_scope()) AllocateParameterLocals(); | 1749 if (is_declaration_scope()) { |
| 1686 if (has_this_declaration()) AllocateReceiver(); | 1750 if (is_function_scope()) AsDeclarationScope()->AllocateParameterLocals(); |
| 1751 AsDeclarationScope()->AllocateReceiver(); | |
| 1752 } | |
| 1687 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory); | 1753 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory); |
| 1688 | 1754 |
| 1689 // Force allocation of a context for this scope if necessary. For a 'with' | 1755 // Force allocation of a context for this scope if necessary. For a 'with' |
| 1690 // scope and for a function scope that makes an 'eval' call we need a context, | 1756 // scope and for a function scope that makes an 'eval' call we need a context, |
| 1691 // even if no local variables were statically allocated in the scope. | 1757 // even if no local variables were statically allocated in the scope. |
| 1692 // Likewise for modules. | 1758 // Likewise for modules. |
| 1693 bool must_have_context = | 1759 bool must_have_context = |
| 1694 is_with_scope() || is_module_scope() || | 1760 is_with_scope() || is_module_scope() || |
| 1695 (is_function_scope() && calls_sloppy_eval()) || | 1761 (is_function_scope() && calls_sloppy_eval()) || |
| 1696 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); | 1762 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); |
| 1697 | 1763 |
| 1698 // If we didn't allocate any locals in the local context, then we only | 1764 // If we didn't allocate any locals in the local context, then we only |
| 1699 // need the minimal number of slots if we must have a context. | 1765 // need the minimal number of slots if we must have a context. |
| 1700 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1766 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
| 1701 num_heap_slots_ = 0; | 1767 num_heap_slots_ = 0; |
| 1702 } | 1768 } |
| 1703 | 1769 |
| 1704 // Allocation done. | 1770 // Allocation done. |
| 1705 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1771 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
| 1706 } | 1772 } |
| 1707 | 1773 |
| 1708 | 1774 |
| 1709 int Scope::StackLocalCount() const { | 1775 int Scope::StackLocalCount() const { |
| 1776 VariableDeclaration* function = | |
| 1777 is_function_scope() ? AsDeclarationScope()->function() : nullptr; | |
| 1710 return num_stack_slots() - | 1778 return num_stack_slots() - |
| 1711 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1779 (function != NULL && function->proxy()->var()->IsStackLocal() ? 1 : 0); |
| 1712 } | 1780 } |
| 1713 | 1781 |
| 1714 | 1782 |
| 1715 int Scope::ContextLocalCount() const { | 1783 int Scope::ContextLocalCount() const { |
| 1716 if (num_heap_slots() == 0) return 0; | 1784 if (num_heap_slots() == 0) return 0; |
| 1785 VariableDeclaration* function = | |
| 1786 is_function_scope() ? AsDeclarationScope()->function() : nullptr; | |
| 1717 bool is_function_var_in_context = | 1787 bool is_function_var_in_context = |
| 1718 function_ != NULL && function_->proxy()->var()->IsContextSlot(); | 1788 function != NULL && function->proxy()->var()->IsContextSlot(); |
| 1719 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1789 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
| 1720 (is_function_var_in_context ? 1 : 0); | 1790 (is_function_var_in_context ? 1 : 0); |
| 1721 } | 1791 } |
| 1722 | 1792 |
| 1723 | 1793 |
| 1724 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1794 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
| 1725 | 1795 |
| 1726 } // namespace internal | 1796 } // namespace internal |
| 1727 } // namespace v8 | 1797 } // namespace v8 |
| OLD | NEW |