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