| 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 "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
| 9 #include "src/messages.h" | 9 #include "src/messages.h" |
| 10 #include "src/parsing/parser.h" // for ParseInfo | 10 #include "src/parsing/parser.h" // for ParseInfo |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 p->value = new (zone_->New(sizeof(Vector))) Vector(zone_); | 74 p->value = new (zone_->New(sizeof(Vector))) Vector(zone_); |
| 75 } | 75 } |
| 76 Vector* delegates = static_cast<Vector*>(p->value); | 76 Vector* delegates = static_cast<Vector*>(p->value); |
| 77 delegates->push_back(stmt); | 77 delegates->push_back(stmt); |
| 78 } | 78 } |
| 79 | 79 |
| 80 | 80 |
| 81 // ---------------------------------------------------------------------------- | 81 // ---------------------------------------------------------------------------- |
| 82 // Implementation of Scope | 82 // Implementation of Scope |
| 83 | 83 |
| 84 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, | 84 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) |
| 85 FunctionKind function_kind) | |
| 86 : outer_scope_(outer_scope), | 85 : outer_scope_(outer_scope), |
| 87 variables_(zone), | 86 variables_(zone), |
| 88 temps_(4, zone), | |
| 89 params_(4, zone), | |
| 90 decls_(4, zone), | 87 decls_(4, zone), |
| 91 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone) | |
| 92 ModuleDescriptor(zone) | |
| 93 : NULL), | |
| 94 sloppy_block_function_map_(zone), | |
| 95 scope_type_(scope_type), | 88 scope_type_(scope_type), |
| 96 function_kind_(function_kind), | |
| 97 already_resolved_(false) { | 89 already_resolved_(false) { |
| 98 SetDefaults(); | 90 SetDefaults(); |
| 99 if (outer_scope == nullptr) { | 91 if (outer_scope == nullptr) { |
| 100 // If the outer scope is null, this cannot be a with scope. The outermost | 92 // If the outer scope is null, this cannot be a with scope. The outermost |
| 101 // scope must be a script scope. | 93 // scope must be a script scope. |
| 102 DCHECK_EQ(SCRIPT_SCOPE, scope_type); | 94 DCHECK_EQ(SCRIPT_SCOPE, scope_type); |
| 103 } else { | 95 } else { |
| 104 asm_function_ = outer_scope_->asm_module_; | 96 asm_function_ = outer_scope_->asm_module_; |
| 105 // Inherit the language mode from the parent scope unless we're a module | 97 // Inherit the language mode from the parent scope unless we're a module |
| 106 // scope. | 98 // scope. |
| 107 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_; | 99 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_; |
| 108 force_context_allocation_ = | 100 force_context_allocation_ = |
| 109 !is_function_scope() && outer_scope->has_forced_context_allocation(); | 101 !is_function_scope() && outer_scope->has_forced_context_allocation(); |
| 110 outer_scope_->AddInnerScope(this); | 102 outer_scope_->AddInnerScope(this); |
| 111 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); | 103 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); |
| 112 } | 104 } |
| 113 } | 105 } |
| 114 | 106 |
| 107 Scope::Snapshot::Snapshot(Scope* scope) |
| 108 : outer_scope_(scope), |
| 109 top_inner_scope_(scope->inner_scope_), |
| 110 top_unresolved_(scope->unresolved_), |
| 111 top_temp_(scope->GetClosureScope()->temps()->length()) {} |
| 112 |
| 113 DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope, |
| 114 ScopeType scope_type, |
| 115 FunctionKind function_kind) |
| 116 : Scope(zone, outer_scope, scope_type), |
| 117 function_kind_(function_kind), |
| 118 temps_(4, zone), |
| 119 params_(4, zone), |
| 120 sloppy_block_function_map_(zone), |
| 121 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone) |
| 122 ModuleDescriptor(zone) |
| 123 : NULL) { |
| 124 SetDefaults(); |
| 125 } |
| 126 |
| 115 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, | 127 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, |
| 116 Handle<ScopeInfo> scope_info) | 128 Handle<ScopeInfo> scope_info) |
| 117 : outer_scope_(nullptr), | 129 : outer_scope_(nullptr), |
| 118 variables_(zone), | 130 variables_(zone), |
| 119 temps_(4, zone), | |
| 120 params_(4, zone), | |
| 121 decls_(4, zone), | 131 decls_(4, zone), |
| 122 module_descriptor_(nullptr), | |
| 123 sloppy_block_function_map_(zone), | |
| 124 scope_type_(scope_type), | 132 scope_type_(scope_type), |
| 125 function_kind_(scope_info.is_null() ? kNormalFunction | |
| 126 : scope_info->function_kind()), | |
| 127 already_resolved_(true), | 133 already_resolved_(true), |
| 128 scope_info_(scope_info) { | 134 scope_info_(scope_info) { |
| 129 SetDefaults(); | 135 SetDefaults(); |
| 130 if (!scope_info.is_null()) { | 136 if (!scope_info.is_null()) { |
| 131 scope_calls_eval_ = scope_info->CallsEval(); | 137 scope_calls_eval_ = scope_info->CallsEval(); |
| 132 language_mode_ = scope_info->language_mode(); | 138 language_mode_ = scope_info->language_mode(); |
| 133 is_declaration_scope_ = scope_info->is_declaration_scope(); | |
| 134 num_heap_slots_ = scope_info_->ContextLength(); | 139 num_heap_slots_ = scope_info_->ContextLength(); |
| 135 } | 140 } |
| 136 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 141 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
| 137 num_heap_slots_ = Max(num_heap_slots_, | 142 num_heap_slots_ = Max(num_heap_slots_, |
| 138 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 143 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
| 139 AddInnerScope(inner_scope); | 144 AddInnerScope(inner_scope); |
| 140 } | 145 } |
| 141 | 146 |
| 147 DeclarationScope::DeclarationScope(Zone* zone, Scope* inner_scope, |
| 148 ScopeType scope_type, |
| 149 Handle<ScopeInfo> scope_info) |
| 150 : Scope(zone, inner_scope, scope_type, scope_info), |
| 151 function_kind_(scope_info.is_null() ? kNormalFunction |
| 152 : scope_info->function_kind()), |
| 153 temps_(4, zone), |
| 154 params_(4, zone), |
| 155 sloppy_block_function_map_(zone), |
| 156 module_descriptor_(nullptr) { |
| 157 SetDefaults(); |
| 158 } |
| 159 |
| 142 Scope::Scope(Zone* zone, Scope* inner_scope, | 160 Scope::Scope(Zone* zone, Scope* inner_scope, |
| 143 const AstRawString* catch_variable_name) | 161 const AstRawString* catch_variable_name) |
| 144 : outer_scope_(nullptr), | 162 : outer_scope_(nullptr), |
| 145 variables_(zone), | 163 variables_(zone), |
| 146 temps_(0, zone), | |
| 147 params_(0, zone), | |
| 148 decls_(0, zone), | 164 decls_(0, zone), |
| 149 module_descriptor_(nullptr), | |
| 150 sloppy_block_function_map_(zone), | |
| 151 scope_type_(CATCH_SCOPE), | 165 scope_type_(CATCH_SCOPE), |
| 152 function_kind_(kNormalFunction), | |
| 153 already_resolved_(true) { | 166 already_resolved_(true) { |
| 154 SetDefaults(); | 167 SetDefaults(); |
| 155 AddInnerScope(inner_scope); | 168 AddInnerScope(inner_scope); |
| 156 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 169 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
| 157 Variable* variable = variables_.Declare(this, | 170 Variable* variable = variables_.Declare(this, |
| 158 catch_variable_name, | 171 catch_variable_name, |
| 159 VAR, | 172 VAR, |
| 160 Variable::NORMAL, | 173 Variable::NORMAL, |
| 161 kCreatedInitialized); | 174 kCreatedInitialized); |
| 162 AllocateHeapSlot(variable); | 175 AllocateHeapSlot(variable); |
| 163 } | 176 } |
| 164 | 177 |
| 165 void Scope::SetDefaults() { | 178 void DeclarationScope::SetDefaults() { |
| 166 is_declaration_scope_ = | 179 is_declaration_scope_ = true; |
| 167 is_eval_scope() || is_function_scope() || | |
| 168 is_module_scope() || is_script_scope(); | |
| 169 inner_scope_ = nullptr; | |
| 170 sibling_ = nullptr; | |
| 171 unresolved_ = nullptr; | |
| 172 #ifdef DEBUG | |
| 173 scope_name_ = nullptr; | |
| 174 #endif | |
| 175 dynamics_ = nullptr; | |
| 176 receiver_ = nullptr; | 180 receiver_ = nullptr; |
| 177 new_target_ = nullptr; | 181 new_target_ = nullptr; |
| 178 function_ = nullptr; | 182 function_ = nullptr; |
| 179 arguments_ = nullptr; | 183 arguments_ = nullptr; |
| 180 this_function_ = nullptr; | 184 this_function_ = nullptr; |
| 185 arity_ = 0; |
| 186 has_simple_parameters_ = true; |
| 187 rest_parameter_ = NULL; |
| 188 rest_index_ = -1; |
| 189 } |
| 190 |
| 191 void Scope::SetDefaults() { |
| 192 #ifdef DEBUG |
| 193 scope_name_ = nullptr; |
| 194 #endif |
| 195 is_declaration_scope_ = false; |
| 196 inner_scope_ = nullptr; |
| 197 sibling_ = nullptr; |
| 198 unresolved_ = nullptr; |
| 199 dynamics_ = nullptr; |
| 181 scope_inside_with_ = false; | 200 scope_inside_with_ = false; |
| 182 scope_calls_eval_ = false; | 201 scope_calls_eval_ = false; |
| 183 has_arguments_parameter_ = false; | 202 has_arguments_parameter_ = false; |
| 184 scope_uses_super_property_ = false; | 203 scope_uses_super_property_ = false; |
| 185 asm_module_ = false; | 204 asm_module_ = false; |
| 186 asm_function_ = false; | 205 asm_function_ = false; |
| 187 language_mode_ = is_module_scope() ? STRICT : SLOPPY; | 206 language_mode_ = is_module_scope() ? STRICT : SLOPPY; |
| 188 outer_scope_calls_sloppy_eval_ = false; | 207 outer_scope_calls_sloppy_eval_ = false; |
| 189 inner_scope_calls_eval_ = false; | 208 inner_scope_calls_eval_ = false; |
| 190 scope_nonlinear_ = false; | 209 scope_nonlinear_ = false; |
| 191 force_eager_compilation_ = false; | 210 force_eager_compilation_ = false; |
| 192 force_context_allocation_ = false; | 211 force_context_allocation_ = false; |
| 193 num_stack_slots_ = 0; | 212 num_stack_slots_ = 0; |
| 194 num_heap_slots_ = 0; | 213 num_heap_slots_ = 0; |
| 195 num_global_slots_ = 0; | 214 num_global_slots_ = 0; |
| 196 arity_ = 0; | |
| 197 has_simple_parameters_ = true; | |
| 198 rest_parameter_ = NULL; | |
| 199 rest_index_ = -1; | |
| 200 start_position_ = kNoSourcePosition; | 215 start_position_ = kNoSourcePosition; |
| 201 end_position_ = kNoSourcePosition; | 216 end_position_ = kNoSourcePosition; |
| 202 is_hidden_ = false; | 217 is_hidden_ = false; |
| 203 } | 218 } |
| 204 | 219 |
| 220 bool Scope::HasSimpleParameters() { |
| 221 DeclarationScope* scope = GetClosureScope(); |
| 222 return !scope->is_function_scope() || scope->has_simple_parameters(); |
| 223 } |
| 224 |
| 205 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 225 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
| 206 Context* context, Scope* script_scope, | 226 Context* context, Scope* script_scope, |
| 207 AstValueFactory* ast_value_factory) { | 227 AstValueFactory* ast_value_factory) { |
| 208 // Reconstruct the outer scope chain from a closure's context chain. | 228 // Reconstruct the outer scope chain from a closure's context chain. |
| 209 Scope* current_scope = NULL; | 229 Scope* current_scope = NULL; |
| 210 Scope* innermost_scope = NULL; | 230 Scope* innermost_scope = NULL; |
| 211 while (!context->IsNativeContext()) { | 231 while (!context->IsNativeContext()) { |
| 212 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { | 232 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { |
| 213 // For scope analysis, debug-evaluate is equivalent to a with scope. | 233 // For scope analysis, debug-evaluate is equivalent to a with scope. |
| 214 Scope* with_scope = new (zone) | 234 Scope* with_scope = new (zone) |
| 215 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); | 235 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); |
| 216 current_scope = with_scope; | 236 current_scope = with_scope; |
| 217 // All the inner scopes are inside a with. | 237 // All the inner scopes are inside a with. |
| 218 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { | 238 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { |
| 219 s->scope_inside_with_ = true; | 239 s->scope_inside_with_ = true; |
| 220 } | 240 } |
| 221 } else if (context->IsScriptContext()) { | 241 } else if (context->IsScriptContext()) { |
| 222 ScopeInfo* scope_info = context->scope_info(); | 242 ScopeInfo* scope_info = context->scope_info(); |
| 223 current_scope = new (zone) Scope(zone, current_scope, SCRIPT_SCOPE, | 243 current_scope = new (zone) DeclarationScope( |
| 224 Handle<ScopeInfo>(scope_info)); | 244 zone, current_scope, SCRIPT_SCOPE, Handle<ScopeInfo>(scope_info)); |
| 225 } else if (context->IsFunctionContext()) { | 245 } else if (context->IsFunctionContext()) { |
| 226 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | 246 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
| 227 current_scope = new (zone) Scope(zone, current_scope, FUNCTION_SCOPE, | 247 current_scope = new (zone) DeclarationScope( |
| 228 Handle<ScopeInfo>(scope_info)); | 248 zone, current_scope, FUNCTION_SCOPE, Handle<ScopeInfo>(scope_info)); |
| 229 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; | 249 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; |
| 230 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; | 250 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; |
| 231 } else if (context->IsBlockContext()) { | 251 } else if (context->IsBlockContext()) { |
| 232 ScopeInfo* scope_info = context->scope_info(); | 252 ScopeInfo* scope_info = context->scope_info(); |
| 233 current_scope = new (zone) Scope(zone, current_scope, BLOCK_SCOPE, | 253 if (scope_info->is_declaration_scope()) { |
| 234 Handle<ScopeInfo>(scope_info)); | 254 current_scope = new (zone) DeclarationScope( |
| 255 zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info)); |
| 256 } else { |
| 257 current_scope = new (zone) Scope(zone, current_scope, BLOCK_SCOPE, |
| 258 Handle<ScopeInfo>(scope_info)); |
| 259 } |
| 235 } else { | 260 } else { |
| 236 DCHECK(context->IsCatchContext()); | 261 DCHECK(context->IsCatchContext()); |
| 237 String* name = context->catch_name(); | 262 String* name = context->catch_name(); |
| 238 current_scope = | 263 current_scope = |
| 239 new (zone) Scope(zone, current_scope, | 264 new (zone) Scope(zone, current_scope, |
| 240 ast_value_factory->GetString(handle(name, isolate))); | 265 ast_value_factory->GetString(handle(name, isolate))); |
| 241 } | 266 } |
| 242 if (innermost_scope == NULL) innermost_scope = current_scope; | 267 if (innermost_scope == NULL) innermost_scope = current_scope; |
| 243 context = context->previous(); | 268 context = context->previous(); |
| 244 } | 269 } |
| 245 | 270 |
| 246 script_scope->AddInnerScope(current_scope); | 271 script_scope->AddInnerScope(current_scope); |
| 247 script_scope->PropagateScopeInfo(false); | 272 script_scope->PropagateScopeInfo(false); |
| 248 return (innermost_scope == NULL) ? script_scope : innermost_scope; | 273 return (innermost_scope == NULL) ? script_scope : innermost_scope; |
| 249 } | 274 } |
| 250 | 275 |
| 276 DeclarationScope* Scope::AsDeclarationScope() { |
| 277 DCHECK(is_declaration_scope()); |
| 278 return static_cast<DeclarationScope*>(this); |
| 279 } |
| 280 |
| 281 const DeclarationScope* Scope::AsDeclarationScope() const { |
| 282 DCHECK(is_declaration_scope()); |
| 283 return static_cast<const DeclarationScope*>(this); |
| 284 } |
| 285 |
| 286 int Scope::num_parameters() const { |
| 287 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; |
| 288 } |
| 251 | 289 |
| 252 bool Scope::Analyze(ParseInfo* info) { | 290 bool Scope::Analyze(ParseInfo* info) { |
| 253 DCHECK(info->literal() != NULL); | 291 DCHECK(info->literal() != NULL); |
| 254 DCHECK(info->scope() == NULL); | 292 DCHECK(info->scope() == NULL); |
| 255 Scope* scope = info->literal()->scope(); | 293 DeclarationScope* scope = info->literal()->scope(); |
| 256 Scope* top = scope; | 294 DeclarationScope* top = scope; |
| 257 | 295 |
| 258 // Traverse the scope tree up to the first unresolved scope or the global | 296 // Traverse the scope tree up to the first unresolved scope or the global |
| 259 // scope and start scope resolution and variable allocation from that scope. | 297 // scope and start scope resolution and variable allocation from that scope. |
| 298 // Such a scope is always a closure-scope, so always skip to the next closure |
| 299 // scope. |
| 260 while (!top->is_script_scope() && | 300 while (!top->is_script_scope() && |
| 261 !top->outer_scope()->already_resolved()) { | 301 !top->outer_scope()->already_resolved()) { |
| 262 top = top->outer_scope(); | 302 top = top->outer_scope()->GetClosureScope(); |
| 263 } | 303 } |
| 264 | 304 |
| 265 // Allocate the variables. | 305 // Allocate the variables. |
| 266 { | 306 { |
| 267 AstNodeFactory ast_node_factory(info->ast_value_factory()); | 307 AstNodeFactory ast_node_factory(info->ast_value_factory()); |
| 268 if (!top->AllocateVariables(info, &ast_node_factory)) { | 308 if (!top->AllocateVariables(info, &ast_node_factory)) { |
| 269 DCHECK(top->pending_error_handler_.has_pending_error()); | 309 DCHECK(top->pending_error_handler_.has_pending_error()); |
| 270 top->pending_error_handler_.ThrowPendingError(info->isolate(), | 310 top->pending_error_handler_.ThrowPendingError(info->isolate(), |
| 271 info->script()); | 311 info->script()); |
| 272 return false; | 312 return false; |
| 273 } | 313 } |
| 274 } | 314 } |
| 275 | 315 |
| 276 #ifdef DEBUG | 316 #ifdef DEBUG |
| 277 if (info->script_is_native() ? FLAG_print_builtin_scopes | 317 if (info->script_is_native() ? FLAG_print_builtin_scopes |
| 278 : FLAG_print_scopes) { | 318 : FLAG_print_scopes) { |
| 279 scope->Print(); | 319 scope->Print(); |
| 280 } | 320 } |
| 281 scope->CheckScopePositions(); | 321 scope->CheckScopePositions(); |
| 282 scope->CheckZones(); | 322 scope->CheckZones(); |
| 283 #endif | 323 #endif |
| 284 | 324 |
| 285 info->set_scope(scope); | 325 info->set_scope(scope); |
| 286 return true; | 326 return true; |
| 287 } | 327 } |
| 288 | 328 |
| 289 void Scope::DeclareThis(AstValueFactory* ast_value_factory) { | 329 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { |
| 290 DCHECK(!already_resolved()); | 330 DCHECK(!already_resolved()); |
| 291 DCHECK(is_declaration_scope()); | 331 DCHECK(is_declaration_scope()); |
| 292 DCHECK(has_this_declaration()); | 332 DCHECK(has_this_declaration()); |
| 293 | 333 |
| 294 bool subclass_constructor = IsSubclassConstructor(function_kind_); | 334 bool subclass_constructor = IsSubclassConstructor(function_kind_); |
| 295 Variable* var = variables_.Declare( | 335 Variable* var = variables_.Declare( |
| 296 this, ast_value_factory->this_string(), | 336 this, ast_value_factory->this_string(), |
| 297 subclass_constructor ? CONST : VAR, Variable::THIS, | 337 subclass_constructor ? CONST : VAR, Variable::THIS, |
| 298 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | 338 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
| 299 receiver_ = var; | 339 receiver_ = var; |
| 300 } | 340 } |
| 301 | 341 |
| 302 void Scope::DeclareDefaultFunctionVariables( | 342 void DeclarationScope::DeclareDefaultFunctionVariables( |
| 303 AstValueFactory* ast_value_factory) { | 343 AstValueFactory* ast_value_factory) { |
| 304 DCHECK(is_function_scope()); | 344 DCHECK(is_function_scope()); |
| 305 DCHECK(!is_arrow_scope()); | 345 DCHECK(!is_arrow_scope()); |
| 306 // Declare 'arguments' variable which exists in all non arrow functions. | 346 // Declare 'arguments' variable which exists in all non arrow functions. |
| 307 // Note that it might never be accessed, in which case it won't be | 347 // Note that it might never be accessed, in which case it won't be |
| 308 // allocated during variable allocation. | 348 // allocated during variable allocation. |
| 309 arguments_ = | 349 arguments_ = |
| 310 variables_.Declare(this, ast_value_factory->arguments_string(), VAR, | 350 variables_.Declare(this, ast_value_factory->arguments_string(), VAR, |
| 311 Variable::ARGUMENTS, kCreatedInitialized); | 351 Variable::ARGUMENTS, kCreatedInitialized); |
| 312 | 352 |
| 313 new_target_ = | 353 new_target_ = |
| 314 variables_.Declare(this, ast_value_factory->new_target_string(), CONST, | 354 variables_.Declare(this, ast_value_factory->new_target_string(), CONST, |
| 315 Variable::NORMAL, kCreatedInitialized); | 355 Variable::NORMAL, kCreatedInitialized); |
| 316 | 356 |
| 317 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || | 357 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || |
| 318 IsAccessorFunction(function_kind_)) { | 358 IsAccessorFunction(function_kind_)) { |
| 319 this_function_ = | 359 this_function_ = |
| 320 variables_.Declare(this, ast_value_factory->this_function_string(), | 360 variables_.Declare(this, ast_value_factory->this_function_string(), |
| 321 CONST, Variable::NORMAL, kCreatedInitialized); | 361 CONST, Variable::NORMAL, kCreatedInitialized); |
| 322 } | 362 } |
| 323 } | 363 } |
| 324 | 364 |
| 325 | 365 |
| 326 Scope* Scope::FinalizeBlockScope() { | 366 Scope* Scope::FinalizeBlockScope() { |
| 327 DCHECK(is_block_scope()); | 367 DCHECK(is_block_scope()); |
| 328 DCHECK(temps_.is_empty()); | |
| 329 DCHECK(params_.is_empty()); | |
| 330 | 368 |
| 331 if (variables_.occupancy() > 0 || | 369 if (variables_.occupancy() > 0 || |
| 332 (is_declaration_scope() && calls_sloppy_eval())) { | 370 (is_declaration_scope() && calls_sloppy_eval())) { |
| 333 return this; | 371 return this; |
| 334 } | 372 } |
| 335 | 373 |
| 336 // Remove this scope from outer scope. | 374 // Remove this scope from outer scope. |
| 337 outer_scope()->RemoveInnerScope(this); | 375 outer_scope()->RemoveInnerScope(this); |
| 338 | 376 |
| 339 // Reparent inner scopes. | 377 // Reparent inner scopes. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 360 } | 398 } |
| 361 outer_scope()->unresolved_ = unresolved_; | 399 outer_scope()->unresolved_ = unresolved_; |
| 362 unresolved_ = nullptr; | 400 unresolved_ = nullptr; |
| 363 } | 401 } |
| 364 | 402 |
| 365 PropagateUsageFlagsToScope(outer_scope_); | 403 PropagateUsageFlagsToScope(outer_scope_); |
| 366 | 404 |
| 367 return NULL; | 405 return NULL; |
| 368 } | 406 } |
| 369 | 407 |
| 370 void Scope::Snapshot::Reparent(Scope* new_parent) const { | 408 void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const { |
| 371 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); | 409 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); |
| 372 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); | 410 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); |
| 373 DCHECK_EQ(new_parent, new_parent->ClosureScope()); | 411 DCHECK_EQ(new_parent, new_parent->GetClosureScope()); |
| 374 DCHECK_NULL(new_parent->inner_scope_); | 412 DCHECK_NULL(new_parent->inner_scope_); |
| 375 DCHECK_NULL(new_parent->unresolved_); | 413 DCHECK_NULL(new_parent->unresolved_); |
| 376 DCHECK_EQ(0, new_parent->temps_.length()); | 414 DCHECK_EQ(0, new_parent->temps()->length()); |
| 377 Scope* inner_scope = new_parent->sibling_; | 415 Scope* inner_scope = new_parent->sibling_; |
| 378 if (inner_scope != top_inner_scope_) { | 416 if (inner_scope != top_inner_scope_) { |
| 379 for (; inner_scope->sibling() != top_inner_scope_; | 417 for (; inner_scope->sibling() != top_inner_scope_; |
| 380 inner_scope = inner_scope->sibling()) { | 418 inner_scope = inner_scope->sibling()) { |
| 381 inner_scope->outer_scope_ = new_parent; | 419 inner_scope->outer_scope_ = new_parent; |
| 382 DCHECK_NE(inner_scope, new_parent); | 420 DCHECK_NE(inner_scope, new_parent); |
| 383 } | 421 } |
| 384 inner_scope->outer_scope_ = new_parent; | 422 inner_scope->outer_scope_ = new_parent; |
| 385 | 423 |
| 386 new_parent->inner_scope_ = new_parent->sibling_; | 424 new_parent->inner_scope_ = new_parent->sibling_; |
| 387 inner_scope->sibling_ = nullptr; | 425 inner_scope->sibling_ = nullptr; |
| 388 // Reset the sibling rather than the inner_scope_ since we | 426 // Reset the sibling rather than the inner_scope_ since we |
| 389 // want to keep new_parent there. | 427 // want to keep new_parent there. |
| 390 new_parent->sibling_ = top_inner_scope_; | 428 new_parent->sibling_ = top_inner_scope_; |
| 391 } | 429 } |
| 392 | 430 |
| 393 if (outer_scope_->unresolved_ != top_unresolved_) { | 431 if (outer_scope_->unresolved_ != top_unresolved_) { |
| 394 VariableProxy* last = outer_scope_->unresolved_; | 432 VariableProxy* last = outer_scope_->unresolved_; |
| 395 while (last->next_unresolved() != top_unresolved_) { | 433 while (last->next_unresolved() != top_unresolved_) { |
| 396 last = last->next_unresolved(); | 434 last = last->next_unresolved(); |
| 397 } | 435 } |
| 398 last->set_next_unresolved(nullptr); | 436 last->set_next_unresolved(nullptr); |
| 399 new_parent->unresolved_ = outer_scope_->unresolved_; | 437 new_parent->unresolved_ = outer_scope_->unresolved_; |
| 400 outer_scope_->unresolved_ = top_unresolved_; | 438 outer_scope_->unresolved_ = top_unresolved_; |
| 401 } | 439 } |
| 402 | 440 |
| 403 if (outer_scope_->ClosureScope()->temps_.length() != top_temp_) { | 441 if (outer_scope_->GetClosureScope()->temps()->length() != top_temp_) { |
| 404 ZoneList<Variable*>* temps = &outer_scope_->ClosureScope()->temps_; | 442 ZoneList<Variable*>* temps = outer_scope_->GetClosureScope()->temps(); |
| 405 for (int i = top_temp_; i < temps->length(); i++) { | 443 for (int i = top_temp_; i < temps->length(); i++) { |
| 406 Variable* temp = temps->at(i); | 444 Variable* temp = temps->at(i); |
| 407 DCHECK_EQ(temp->scope(), temp->scope()->ClosureScope()); | 445 DCHECK_EQ(temp->scope(), temp->scope()->GetClosureScope()); |
| 408 DCHECK_NE(temp->scope(), new_parent); | 446 DCHECK_NE(temp->scope(), new_parent); |
| 409 temp->set_scope(new_parent); | 447 temp->set_scope(new_parent); |
| 410 new_parent->AddTemporary(temp); | 448 new_parent->AddTemporary(temp); |
| 411 } | 449 } |
| 412 temps->Rewind(top_temp_); | 450 temps->Rewind(top_temp_); |
| 413 } | 451 } |
| 414 } | 452 } |
| 415 | 453 |
| 416 void Scope::ReplaceOuterScope(Scope* outer) { | 454 void Scope::ReplaceOuterScope(Scope* outer) { |
| 417 DCHECK_NOT_NULL(outer); | 455 DCHECK_NOT_NULL(outer); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 } | 522 } |
| 485 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and | 523 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and |
| 486 // ARGUMENTS bindings as their corresponding Variable::Kind. | 524 // ARGUMENTS bindings as their corresponding Variable::Kind. |
| 487 | 525 |
| 488 Variable* var = variables_.Declare(this, name, mode, kind, init_flag, | 526 Variable* var = variables_.Declare(this, name, mode, kind, init_flag, |
| 489 maybe_assigned_flag); | 527 maybe_assigned_flag); |
| 490 var->AllocateTo(location, index); | 528 var->AllocateTo(location, index); |
| 491 return var; | 529 return var; |
| 492 } | 530 } |
| 493 | 531 |
| 494 | 532 Variable* DeclarationScope::LookupFunctionVar(const AstRawString* name, |
| 495 Variable* Scope::LookupFunctionVar(const AstRawString* name, | 533 AstNodeFactory* factory) { |
| 496 AstNodeFactory* factory) { | |
| 497 if (function_ != NULL && function_->proxy()->raw_name() == name) { | 534 if (function_ != NULL && function_->proxy()->raw_name() == name) { |
| 498 return function_->proxy()->var(); | 535 return function_->proxy()->var(); |
| 499 } else if (!scope_info_.is_null()) { | 536 } else if (!scope_info_.is_null()) { |
| 500 // If we are backed by a scope info, try to lookup the variable there. | 537 // If we are backed by a scope info, try to lookup the variable there. |
| 501 VariableMode mode; | 538 VariableMode mode; |
| 502 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); | 539 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); |
| 503 if (index < 0) return NULL; | 540 if (index < 0) return NULL; |
| 504 Variable* var = new (zone()) | 541 Variable* var = new (zone()) |
| 505 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); | 542 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); |
| 506 DCHECK_NOT_NULL(factory); | 543 DCHECK_NOT_NULL(factory); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 520 Variable* Scope::Lookup(const AstRawString* name) { | 557 Variable* Scope::Lookup(const AstRawString* name) { |
| 521 for (Scope* scope = this; | 558 for (Scope* scope = this; |
| 522 scope != NULL; | 559 scope != NULL; |
| 523 scope = scope->outer_scope()) { | 560 scope = scope->outer_scope()) { |
| 524 Variable* var = scope->LookupLocal(name); | 561 Variable* var = scope->LookupLocal(name); |
| 525 if (var != NULL) return var; | 562 if (var != NULL) return var; |
| 526 } | 563 } |
| 527 return NULL; | 564 return NULL; |
| 528 } | 565 } |
| 529 | 566 |
| 530 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, | 567 Variable* DeclarationScope::DeclareParameter( |
| 531 bool is_optional, bool is_rest, | 568 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, |
| 532 bool* is_duplicate, | 569 bool* is_duplicate, AstValueFactory* ast_value_factory) { |
| 533 AstValueFactory* ast_value_factory) { | |
| 534 DCHECK(!already_resolved()); | 570 DCHECK(!already_resolved()); |
| 535 DCHECK(is_function_scope()); | 571 DCHECK(is_function_scope()); |
| 536 DCHECK(!is_optional || !is_rest); | 572 DCHECK(!is_optional || !is_rest); |
| 537 Variable* var; | 573 Variable* var; |
| 538 if (mode == TEMPORARY) { | 574 if (mode == TEMPORARY) { |
| 539 var = NewTemporary(name); | 575 var = NewTemporary(name); |
| 540 } else { | 576 } else { |
| 541 var = variables_.Declare(this, name, mode, Variable::NORMAL, | 577 var = variables_.Declare(this, name, mode, Variable::NORMAL, |
| 542 kCreatedInitialized); | 578 kCreatedInitialized); |
| 543 // TODO(wingo): Avoid O(n^2) check. | 579 // TODO(wingo): Avoid O(n^2) check. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 563 MaybeAssignedFlag maybe_assigned_flag) { | 599 MaybeAssignedFlag maybe_assigned_flag) { |
| 564 DCHECK(!already_resolved()); | 600 DCHECK(!already_resolved()); |
| 565 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 601 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
| 566 // introduced during variable allocation, and TEMPORARY variables are | 602 // introduced during variable allocation, and TEMPORARY variables are |
| 567 // allocated via NewTemporary(). | 603 // allocated via NewTemporary(). |
| 568 DCHECK(IsDeclaredVariableMode(mode)); | 604 DCHECK(IsDeclaredVariableMode(mode)); |
| 569 return variables_.Declare(this, name, mode, kind, init_flag, | 605 return variables_.Declare(this, name, mode, kind, init_flag, |
| 570 maybe_assigned_flag); | 606 maybe_assigned_flag); |
| 571 } | 607 } |
| 572 | 608 |
| 573 | 609 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name) { |
| 574 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { | |
| 575 DCHECK(is_script_scope()); | 610 DCHECK(is_script_scope()); |
| 576 return variables_.Declare(this, | 611 return variables_.Declare(this, |
| 577 name, | 612 name, |
| 578 DYNAMIC_GLOBAL, | 613 DYNAMIC_GLOBAL, |
| 579 Variable::NORMAL, | 614 Variable::NORMAL, |
| 580 kCreatedInitialized); | 615 kCreatedInitialized); |
| 581 } | 616 } |
| 582 | 617 |
| 583 | 618 |
| 584 bool Scope::RemoveUnresolved(VariableProxy* var) { | 619 bool Scope::RemoveUnresolved(VariableProxy* var) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 596 return true; | 631 return true; |
| 597 } | 632 } |
| 598 current = next; | 633 current = next; |
| 599 } | 634 } |
| 600 return false; | 635 return false; |
| 601 } | 636 } |
| 602 | 637 |
| 603 | 638 |
| 604 Variable* Scope::NewTemporary(const AstRawString* name) { | 639 Variable* Scope::NewTemporary(const AstRawString* name) { |
| 605 DCHECK(!already_resolved()); | 640 DCHECK(!already_resolved()); |
| 606 Scope* scope = this->ClosureScope(); | 641 DeclarationScope* scope = GetClosureScope(); |
| 607 Variable* var = new(zone()) Variable(scope, | 642 Variable* var = new(zone()) Variable(scope, |
| 608 name, | 643 name, |
| 609 TEMPORARY, | 644 TEMPORARY, |
| 610 Variable::NORMAL, | 645 Variable::NORMAL, |
| 611 kCreatedInitialized); | 646 kCreatedInitialized); |
| 612 scope->AddTemporary(var); | 647 scope->AddTemporary(var); |
| 613 return var; | 648 return var; |
| 614 } | 649 } |
| 615 | 650 |
| 616 int Scope::RemoveTemporary(Variable* var) { | 651 int DeclarationScope::RemoveTemporary(Variable* var) { |
| 617 DCHECK_NOT_NULL(var); | 652 DCHECK_NOT_NULL(var); |
| 618 // Temporaries are only placed in ClosureScopes. | 653 // Temporaries are only placed in ClosureScopes. |
| 619 DCHECK_EQ(ClosureScope(), this); | 654 DCHECK_EQ(GetClosureScope(), this); |
| 620 DCHECK_EQ(var->scope()->ClosureScope(), var->scope()); | 655 DCHECK_EQ(var->scope()->GetClosureScope(), var->scope()); |
| 621 // If the temporary is not here, return quickly. | 656 // If the temporary is not here, return quickly. |
| 622 if (var->scope() != this) return -1; | 657 if (var->scope() != this) return -1; |
| 623 // Most likely (always?) any temporary variable we want to remove | 658 // Most likely (always?) any temporary variable we want to remove |
| 624 // was just added before, so we search backwards. | 659 // was just added before, so we search backwards. |
| 625 for (int i = temps_.length(); i-- > 0;) { | 660 for (int i = temps_.length(); i-- > 0;) { |
| 626 if (temps_[i] == var) { | 661 if (temps_[i] == var) { |
| 627 // Don't shrink temps_, as callers of this method expect | 662 // Don't shrink temps_, as callers of this method expect |
| 628 // the returned indices to be unique per-scope. | 663 // the returned indices to be unique per-scope. |
| 629 temps_[i] = nullptr; | 664 temps_[i] = nullptr; |
| 630 return i; | 665 return i; |
| 631 } | 666 } |
| 632 } | 667 } |
| 633 return -1; | 668 return -1; |
| 634 } | 669 } |
| 635 | 670 |
| 636 | 671 |
| 637 void Scope::AddDeclaration(Declaration* declaration) { | 672 void Scope::AddDeclaration(Declaration* declaration) { |
| 638 decls_.Add(declaration, zone()); | 673 decls_.Add(declaration, zone()); |
| 639 } | 674 } |
| 640 | 675 |
| 641 | 676 |
| 642 Declaration* Scope::CheckConflictingVarDeclarations() { | 677 Declaration* Scope::CheckConflictingVarDeclarations() { |
| 643 int length = decls_.length(); | 678 int length = decls_.length(); |
| 644 for (int i = 0; i < length; i++) { | 679 for (int i = 0; i < length; i++) { |
| 645 Declaration* decl = decls_[i]; | 680 Declaration* decl = decls_[i]; |
| 646 // We don't create a separate scope to hold the function name of a function | 681 // We don't create a separate scope to hold the function name of a function |
| 647 // expression, so we have to make sure not to consider it when checking for | 682 // expression, so we have to make sure not to consider it when checking for |
| 648 // conflicts (since it's conceptually "outside" the declaration scope). | 683 // conflicts (since it's conceptually "outside" the declaration scope). |
| 649 if (is_function_scope() && decl == function()) continue; | 684 if (is_function_scope() && decl == AsDeclarationScope()->function()) |
| 685 continue; |
| 650 if (IsLexicalVariableMode(decl->mode()) && !is_block_scope()) continue; | 686 if (IsLexicalVariableMode(decl->mode()) && !is_block_scope()) continue; |
| 651 const AstRawString* name = decl->proxy()->raw_name(); | 687 const AstRawString* name = decl->proxy()->raw_name(); |
| 652 | 688 |
| 653 // Iterate through all scopes until and including the declaration scope. | 689 // Iterate through all scopes until and including the declaration scope. |
| 654 Scope* previous = NULL; | 690 Scope* previous = NULL; |
| 655 Scope* current = decl->scope(); | 691 Scope* current = decl->scope(); |
| 656 // Lexical vs lexical conflicts within the same scope have already been | 692 // Lexical vs lexical conflicts within the same scope have already been |
| 657 // captured in Parser::Declare. The only conflicts we still need to check | 693 // captured in Parser::Declare. The only conflicts we still need to check |
| 658 // are lexical vs VAR, or any declarations within a declaration block scope | 694 // are lexical vs VAR, or any declarations within a declaration block scope |
| 659 // vs lexical declarations in its surrounding (function) scope. | 695 // vs lexical declarations in its surrounding (function) scope. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 | 743 |
| 708 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, | 744 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, |
| 709 ZoneList<Variable*>* context_locals, | 745 ZoneList<Variable*>* context_locals, |
| 710 ZoneList<Variable*>* context_globals) { | 746 ZoneList<Variable*>* context_globals) { |
| 711 DCHECK(stack_locals != NULL); | 747 DCHECK(stack_locals != NULL); |
| 712 DCHECK(context_locals != NULL); | 748 DCHECK(context_locals != NULL); |
| 713 DCHECK(context_globals != NULL); | 749 DCHECK(context_globals != NULL); |
| 714 | 750 |
| 715 // Collect temporaries which are always allocated on the stack, unless the | 751 // Collect temporaries which are always allocated on the stack, unless the |
| 716 // context as a whole has forced context allocation. | 752 // context as a whole has forced context allocation. |
| 717 for (int i = 0; i < temps_.length(); i++) { | 753 if (is_declaration_scope()) { |
| 718 Variable* var = temps_[i]; | 754 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); |
| 719 if (var == nullptr) continue; | 755 for (int i = 0; i < temps->length(); i++) { |
| 720 if (var->is_used()) { | 756 Variable* var = (*temps)[i]; |
| 721 if (var->IsContextSlot()) { | 757 if (var == nullptr) continue; |
| 722 DCHECK(has_forced_context_allocation()); | 758 if (var->is_used()) { |
| 723 context_locals->Add(var, zone()); | 759 if (var->IsContextSlot()) { |
| 724 } else if (var->IsStackLocal()) { | 760 DCHECK(has_forced_context_allocation()); |
| 725 stack_locals->Add(var, zone()); | 761 context_locals->Add(var, zone()); |
| 726 } else { | 762 } else if (var->IsStackLocal()) { |
| 727 DCHECK(var->IsParameter()); | 763 stack_locals->Add(var, zone()); |
| 764 } else { |
| 765 DCHECK(var->IsParameter()); |
| 766 } |
| 728 } | 767 } |
| 729 } | 768 } |
| 730 } | 769 } |
| 731 | 770 |
| 732 // Collect declared local variables. | 771 // Collect declared local variables. |
| 733 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 772 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
| 734 for (VariableMap::Entry* p = variables_.Start(); | 773 for (VariableMap::Entry* p = variables_.Start(); |
| 735 p != NULL; | 774 p != NULL; |
| 736 p = variables_.Next(p)) { | 775 p = variables_.Next(p)) { |
| 737 Variable* var = reinterpret_cast<Variable*>(p->value); | 776 Variable* var = reinterpret_cast<Variable*>(p->value); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 871 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 833 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), | 872 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), |
| 834 max_context_chain_length); | 873 max_context_chain_length); |
| 835 } | 874 } |
| 836 if (NeedsContext()) { | 875 if (NeedsContext()) { |
| 837 max_context_chain_length += 1; | 876 max_context_chain_length += 1; |
| 838 } | 877 } |
| 839 return max_context_chain_length; | 878 return max_context_chain_length; |
| 840 } | 879 } |
| 841 | 880 |
| 842 | 881 DeclarationScope* Scope::GetDeclarationScope() { |
| 843 Scope* Scope::DeclarationScope() { | |
| 844 Scope* scope = this; | 882 Scope* scope = this; |
| 845 while (!scope->is_declaration_scope()) { | 883 while (!scope->is_declaration_scope()) { |
| 846 scope = scope->outer_scope(); | 884 scope = scope->outer_scope(); |
| 847 } | 885 } |
| 848 return scope; | 886 return scope->AsDeclarationScope(); |
| 849 } | 887 } |
| 850 | 888 |
| 851 | 889 DeclarationScope* Scope::GetClosureScope() { |
| 852 Scope* Scope::ClosureScope() { | |
| 853 Scope* scope = this; | 890 Scope* scope = this; |
| 854 while (!scope->is_declaration_scope() || scope->is_block_scope()) { | 891 while (!scope->is_declaration_scope() || scope->is_block_scope()) { |
| 855 scope = scope->outer_scope(); | 892 scope = scope->outer_scope(); |
| 856 } | 893 } |
| 857 return scope; | 894 return scope->AsDeclarationScope(); |
| 895 } |
| 896 |
| 897 DeclarationScope* Scope::GetReceiverScope() { |
| 898 Scope* scope = this; |
| 899 while (!scope->is_script_scope() && |
| 900 (!scope->is_function_scope() || |
| 901 scope->AsDeclarationScope()->is_arrow_scope())) { |
| 902 scope = scope->outer_scope(); |
| 903 } |
| 904 return scope->AsDeclarationScope(); |
| 858 } | 905 } |
| 859 | 906 |
| 860 | 907 |
| 861 Scope* Scope::ReceiverScope() { | |
| 862 Scope* scope = this; | |
| 863 while (!scope->is_script_scope() && | |
| 864 (!scope->is_function_scope() || scope->is_arrow_scope())) { | |
| 865 scope = scope->outer_scope(); | |
| 866 } | |
| 867 return scope; | |
| 868 } | |
| 869 | |
| 870 | |
| 871 | 908 |
| 872 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { | 909 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { |
| 873 if (scope_info_.is_null()) { | 910 if (scope_info_.is_null()) { |
| 874 scope_info_ = ScopeInfo::Create(isolate, zone(), this); | 911 scope_info_ = ScopeInfo::Create(isolate, zone(), this); |
| 875 } | 912 } |
| 876 return scope_info_; | 913 return scope_info_; |
| 877 } | 914 } |
| 878 | 915 |
| 879 Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) { | 916 Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) { |
| 880 // Collect non-local variables referenced in the scope. | 917 // Collect non-local variables referenced in the scope. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { | 1049 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { |
| 1013 Variable* var = reinterpret_cast<Variable*>(p->value); | 1050 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 1014 if (var == NULL) { | 1051 if (var == NULL) { |
| 1015 Indent(indent, "<?>\n"); | 1052 Indent(indent, "<?>\n"); |
| 1016 } else { | 1053 } else { |
| 1017 PrintVar(indent, var); | 1054 PrintVar(indent, var); |
| 1018 } | 1055 } |
| 1019 } | 1056 } |
| 1020 } | 1057 } |
| 1021 | 1058 |
| 1059 void DeclarationScope::PrintParameters() { |
| 1060 PrintF(" ("); |
| 1061 for (int i = 0; i < params_.length(); i++) { |
| 1062 if (i > 0) PrintF(", "); |
| 1063 const AstRawString* name = params_[i]->raw_name(); |
| 1064 if (name->IsEmpty()) |
| 1065 PrintF(".%p", reinterpret_cast<void*>(params_[i])); |
| 1066 else |
| 1067 PrintName(name); |
| 1068 } |
| 1069 PrintF(")"); |
| 1070 } |
| 1022 | 1071 |
| 1023 void Scope::Print(int n) { | 1072 void Scope::Print(int n) { |
| 1024 int n0 = (n > 0 ? n : 0); | 1073 int n0 = (n > 0 ? n : 0); |
| 1025 int n1 = n0 + 2; // indentation | 1074 int n1 = n0 + 2; // indentation |
| 1026 | 1075 |
| 1027 // Print header. | 1076 // Print header. |
| 1028 Indent(n0, Header(scope_type_, function_kind_, is_declaration_scope())); | 1077 FunctionKind function_kind = is_function_scope() |
| 1078 ? AsDeclarationScope()->function_kind() |
| 1079 : kNormalFunction; |
| 1080 Indent(n0, Header(scope_type_, function_kind, is_declaration_scope())); |
| 1029 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) { | 1081 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) { |
| 1030 PrintF(" "); | 1082 PrintF(" "); |
| 1031 PrintName(scope_name_); | 1083 PrintName(scope_name_); |
| 1032 } | 1084 } |
| 1033 | 1085 |
| 1034 // Print parameters, if any. | 1086 // Print parameters, if any. |
| 1087 VariableDeclaration* function = nullptr; |
| 1035 if (is_function_scope()) { | 1088 if (is_function_scope()) { |
| 1036 PrintF(" ("); | 1089 AsDeclarationScope()->PrintParameters(); |
| 1037 for (int i = 0; i < params_.length(); i++) { | 1090 function = AsDeclarationScope()->function(); |
| 1038 if (i > 0) PrintF(", "); | |
| 1039 const AstRawString* name = params_[i]->raw_name(); | |
| 1040 if (name->IsEmpty()) | |
| 1041 PrintF(".%p", reinterpret_cast<void*>(params_[i])); | |
| 1042 else | |
| 1043 PrintName(name); | |
| 1044 } | |
| 1045 PrintF(")"); | |
| 1046 } | 1091 } |
| 1047 | 1092 |
| 1048 PrintF(" { // (%d, %d)\n", start_position(), end_position()); | 1093 PrintF(" { // (%d, %d)\n", start_position(), end_position()); |
| 1049 | 1094 |
| 1050 // Function name, if any (named function literals, only). | 1095 // Function name, if any (named function literals, only). |
| 1051 if (function_ != NULL) { | 1096 if (function != nullptr) { |
| 1052 Indent(n1, "// (local) function name: "); | 1097 Indent(n1, "// (local) function name: "); |
| 1053 PrintName(function_->proxy()->raw_name()); | 1098 PrintName(function->proxy()->raw_name()); |
| 1054 PrintF("\n"); | 1099 PrintF("\n"); |
| 1055 } | 1100 } |
| 1056 | 1101 |
| 1057 // Scope info. | 1102 // Scope info. |
| 1058 if (HasTrivialOuterContext()) { | 1103 if (HasTrivialOuterContext()) { |
| 1059 Indent(n1, "// scope has trivial outer context\n"); | 1104 Indent(n1, "// scope has trivial outer context\n"); |
| 1060 } | 1105 } |
| 1061 if (is_strict(language_mode())) { | 1106 if (is_strict(language_mode())) { |
| 1062 Indent(n1, "// strict mode scope\n"); | 1107 Indent(n1, "// strict mode scope\n"); |
| 1063 } | 1108 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1075 Indent(n1, "// "); | 1120 Indent(n1, "// "); |
| 1076 PrintF("%d stack slots\n", num_stack_slots_); | 1121 PrintF("%d stack slots\n", num_stack_slots_); |
| 1077 } | 1122 } |
| 1078 if (num_heap_slots_ > 0) { | 1123 if (num_heap_slots_ > 0) { |
| 1079 Indent(n1, "// "); | 1124 Indent(n1, "// "); |
| 1080 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, | 1125 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, |
| 1081 num_global_slots_); | 1126 num_global_slots_); |
| 1082 } | 1127 } |
| 1083 | 1128 |
| 1084 // Print locals. | 1129 // Print locals. |
| 1085 if (function_ != NULL) { | 1130 if (function != nullptr) { |
| 1086 Indent(n1, "// function var:\n"); | 1131 Indent(n1, "// function var:\n"); |
| 1087 PrintVar(n1, function_->proxy()->var()); | 1132 PrintVar(n1, function->proxy()->var()); |
| 1088 } | 1133 } |
| 1089 | 1134 |
| 1090 if (temps_.length() > 0) { | 1135 if (is_declaration_scope()) { |
| 1091 bool printed_header = false; | 1136 bool printed_header = false; |
| 1092 for (int i = 0; i < temps_.length(); i++) { | 1137 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); |
| 1093 if (temps_[i] != nullptr) { | 1138 for (int i = 0; i < temps->length(); i++) { |
| 1139 if ((*temps)[i] != nullptr) { |
| 1094 if (!printed_header) { | 1140 if (!printed_header) { |
| 1095 printed_header = true; | 1141 printed_header = true; |
| 1096 Indent(n1, "// temporary vars:\n"); | 1142 Indent(n1, "// temporary vars:\n"); |
| 1097 } | 1143 } |
| 1098 PrintVar(n1, temps_[i]); | 1144 PrintVar(n1, (*temps)[i]); |
| 1099 } | 1145 } |
| 1100 } | 1146 } |
| 1101 } | 1147 } |
| 1102 | 1148 |
| 1103 if (variables_.Start() != NULL) { | 1149 if (variables_.Start() != NULL) { |
| 1104 Indent(n1, "// local vars:\n"); | 1150 Indent(n1, "// local vars:\n"); |
| 1105 PrintMap(n1, &variables_); | 1151 PrintMap(n1, &variables_); |
| 1106 } | 1152 } |
| 1107 | 1153 |
| 1108 if (dynamics_ != NULL) { | 1154 if (dynamics_ != NULL) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1179 Variable* var = LookupLocal(proxy->raw_name()); | 1225 Variable* var = LookupLocal(proxy->raw_name()); |
| 1180 | 1226 |
| 1181 // We found a variable and we are done. (Even if there is an 'eval' in | 1227 // We found a variable and we are done. (Even if there is an 'eval' in |
| 1182 // this scope which introduces the same variable again, the resulting | 1228 // this scope which introduces the same variable again, the resulting |
| 1183 // variable remains the same.) | 1229 // variable remains the same.) |
| 1184 if (var != NULL) { | 1230 if (var != NULL) { |
| 1185 *binding_kind = BOUND; | 1231 *binding_kind = BOUND; |
| 1186 return var; | 1232 return var; |
| 1187 } | 1233 } |
| 1188 | 1234 |
| 1189 // We did not find a variable locally. Check against the function variable, | 1235 // We did not find a variable locally. Check against the function variable, if |
| 1190 // if any. We can do this for all scopes, since the function variable is | 1236 // any. |
| 1191 // only present - if at all - for function scopes. | |
| 1192 *binding_kind = UNBOUND; | 1237 *binding_kind = UNBOUND; |
| 1193 var = LookupFunctionVar(proxy->raw_name(), factory); | 1238 var = |
| 1239 is_function_scope() |
| 1240 ? AsDeclarationScope()->LookupFunctionVar(proxy->raw_name(), factory) |
| 1241 : nullptr; |
| 1194 if (var != NULL) { | 1242 if (var != NULL) { |
| 1195 *binding_kind = BOUND; | 1243 *binding_kind = BOUND; |
| 1196 } else if (outer_scope_ != nullptr && this != max_outer_scope) { | 1244 } else if (outer_scope_ != nullptr && this != max_outer_scope) { |
| 1197 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, | 1245 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, |
| 1198 max_outer_scope); | 1246 max_outer_scope); |
| 1199 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { | 1247 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { |
| 1200 var->ForceContextAllocation(); | 1248 var->ForceContextAllocation(); |
| 1201 } | 1249 } |
| 1202 } else { | 1250 } else { |
| 1203 DCHECK(is_script_scope() || this == max_outer_scope); | 1251 DCHECK(is_script_scope() || this == max_outer_scope); |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1406 if (var->mode() == TEMPORARY) return false; | 1454 if (var->mode() == TEMPORARY) return false; |
| 1407 if (is_catch_scope() || is_module_scope()) return true; | 1455 if (is_catch_scope() || is_module_scope()) return true; |
| 1408 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; | 1456 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; |
| 1409 return var->has_forced_context_allocation() || scope_calls_eval_ || | 1457 return var->has_forced_context_allocation() || scope_calls_eval_ || |
| 1410 inner_scope_calls_eval_; | 1458 inner_scope_calls_eval_; |
| 1411 } | 1459 } |
| 1412 | 1460 |
| 1413 | 1461 |
| 1414 void Scope::AllocateStackSlot(Variable* var) { | 1462 void Scope::AllocateStackSlot(Variable* var) { |
| 1415 if (is_block_scope()) { | 1463 if (is_block_scope()) { |
| 1416 outer_scope()->DeclarationScope()->AllocateStackSlot(var); | 1464 outer_scope()->GetDeclarationScope()->AllocateStackSlot(var); |
| 1417 } else { | 1465 } else { |
| 1418 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); | 1466 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); |
| 1419 } | 1467 } |
| 1420 } | 1468 } |
| 1421 | 1469 |
| 1422 | 1470 |
| 1423 void Scope::AllocateHeapSlot(Variable* var) { | 1471 void Scope::AllocateHeapSlot(Variable* var) { |
| 1424 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); | 1472 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); |
| 1425 } | 1473 } |
| 1426 | 1474 |
| 1427 void Scope::AllocateParameterLocals() { | 1475 void DeclarationScope::AllocateParameterLocals() { |
| 1428 DCHECK(is_function_scope()); | 1476 DCHECK(is_function_scope()); |
| 1429 | 1477 |
| 1430 bool uses_sloppy_arguments = false; | 1478 bool uses_sloppy_arguments = false; |
| 1431 | 1479 |
| 1432 // Functions have 'arguments' declared implicitly in all non arrow functions. | 1480 // Functions have 'arguments' declared implicitly in all non arrow functions. |
| 1433 if (arguments_ != nullptr) { | 1481 if (arguments_ != nullptr) { |
| 1434 // 'arguments' is used. Unless there is also a parameter called | 1482 // 'arguments' is used. Unless there is also a parameter called |
| 1435 // 'arguments', we must be conservative and allocate all parameters to | 1483 // 'arguments', we must be conservative and allocate all parameters to |
| 1436 // the context assuming they will be captured by the arguments object. | 1484 // the context assuming they will be captured by the arguments object. |
| 1437 // If we have a parameter named 'arguments', a (new) value is always | 1485 // 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... |
| 1470 | 1518 |
| 1471 DCHECK(var->scope() == this); | 1519 DCHECK(var->scope() == this); |
| 1472 if (uses_sloppy_arguments || has_forced_context_allocation()) { | 1520 if (uses_sloppy_arguments || has_forced_context_allocation()) { |
| 1473 // Force context allocation of the parameter. | 1521 // Force context allocation of the parameter. |
| 1474 var->ForceContextAllocation(); | 1522 var->ForceContextAllocation(); |
| 1475 } | 1523 } |
| 1476 AllocateParameter(var, i); | 1524 AllocateParameter(var, i); |
| 1477 } | 1525 } |
| 1478 } | 1526 } |
| 1479 | 1527 |
| 1480 | 1528 void DeclarationScope::AllocateParameter(Variable* var, int index) { |
| 1481 void Scope::AllocateParameter(Variable* var, int index) { | |
| 1482 if (MustAllocate(var)) { | 1529 if (MustAllocate(var)) { |
| 1483 if (MustAllocateInContext(var)) { | 1530 if (MustAllocateInContext(var)) { |
| 1484 DCHECK(var->IsUnallocated() || var->IsContextSlot()); | 1531 DCHECK(var->IsUnallocated() || var->IsContextSlot()); |
| 1485 if (var->IsUnallocated()) { | 1532 if (var->IsUnallocated()) { |
| 1486 AllocateHeapSlot(var); | 1533 AllocateHeapSlot(var); |
| 1487 } | 1534 } |
| 1488 } else { | 1535 } else { |
| 1489 DCHECK(var->IsUnallocated() || var->IsParameter()); | 1536 DCHECK(var->IsUnallocated() || var->IsParameter()); |
| 1490 if (var->IsUnallocated()) { | 1537 if (var->IsUnallocated()) { |
| 1491 var->AllocateTo(VariableLocation::PARAMETER, index); | 1538 var->AllocateTo(VariableLocation::PARAMETER, index); |
| 1492 } | 1539 } |
| 1493 } | 1540 } |
| 1494 } else { | 1541 } else { |
| 1495 DCHECK(!var->IsGlobalSlot()); | 1542 DCHECK(!var->IsGlobalSlot()); |
| 1496 } | 1543 } |
| 1497 } | 1544 } |
| 1498 | 1545 |
| 1499 | 1546 void DeclarationScope::AllocateReceiver() { |
| 1500 void Scope::AllocateReceiver() { | 1547 if (!has_this_declaration()) return; |
| 1501 DCHECK_NOT_NULL(receiver()); | 1548 DCHECK_NOT_NULL(receiver()); |
| 1502 DCHECK_EQ(receiver()->scope(), this); | 1549 DCHECK_EQ(receiver()->scope(), this); |
| 1503 | 1550 |
| 1504 if (has_forced_context_allocation()) { | 1551 if (has_forced_context_allocation()) { |
| 1505 // Force context allocation of the receiver. | 1552 // Force context allocation of the receiver. |
| 1506 receiver()->ForceContextAllocation(); | 1553 receiver()->ForceContextAllocation(); |
| 1507 } | 1554 } |
| 1508 AllocateParameter(receiver(), -1); | 1555 AllocateParameter(receiver(), -1); |
| 1509 } | 1556 } |
| 1510 | 1557 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1536 } else { | 1583 } else { |
| 1537 // There must be only DYNAMIC_GLOBAL in the script scope. | 1584 // There must be only DYNAMIC_GLOBAL in the script scope. |
| 1538 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); | 1585 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); |
| 1539 } | 1586 } |
| 1540 } | 1587 } |
| 1541 } | 1588 } |
| 1542 | 1589 |
| 1543 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals( | 1590 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals( |
| 1544 AstValueFactory* ast_value_factory) { | 1591 AstValueFactory* ast_value_factory) { |
| 1545 // All variables that have no rewrite yet are non-parameter locals. | 1592 // All variables that have no rewrite yet are non-parameter locals. |
| 1546 for (int i = 0; i < temps_.length(); i++) { | 1593 if (is_declaration_scope()) { |
| 1547 if (temps_[i] == nullptr) continue; | 1594 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); |
| 1548 AllocateNonParameterLocal(temps_[i], ast_value_factory); | 1595 for (int i = 0; i < temps->length(); i++) { |
| 1596 if ((*temps)[i] == nullptr) continue; |
| 1597 AllocateNonParameterLocal((*temps)[i], ast_value_factory); |
| 1598 } |
| 1549 } | 1599 } |
| 1550 | 1600 |
| 1551 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 1601 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
| 1552 for (VariableMap::Entry* p = variables_.Start(); | 1602 for (VariableMap::Entry* p = variables_.Start(); |
| 1553 p != NULL; | 1603 p != NULL; |
| 1554 p = variables_.Next(p)) { | 1604 p = variables_.Next(p)) { |
| 1555 Variable* var = reinterpret_cast<Variable*>(p->value); | 1605 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 1556 vars.Add(VarAndOrder(var, p->order), zone()); | 1606 vars.Add(VarAndOrder(var, p->order), zone()); |
| 1557 } | 1607 } |
| 1558 vars.Sort(VarAndOrder::Compare); | 1608 vars.Sort(VarAndOrder::Compare); |
| 1559 int var_count = vars.length(); | 1609 int var_count = vars.length(); |
| 1560 for (int i = 0; i < var_count; i++) { | 1610 for (int i = 0; i < var_count; i++) { |
| 1561 AllocateNonParameterLocal(vars[i].var(), ast_value_factory); | 1611 AllocateNonParameterLocal(vars[i].var(), ast_value_factory); |
| 1562 } | 1612 } |
| 1563 | 1613 |
| 1564 if (FLAG_global_var_shortcuts) { | 1614 if (FLAG_global_var_shortcuts) { |
| 1565 for (int i = 0; i < var_count; i++) { | 1615 for (int i = 0; i < var_count; i++) { |
| 1566 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory); | 1616 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory); |
| 1567 } | 1617 } |
| 1568 } | 1618 } |
| 1569 | 1619 |
| 1620 if (is_declaration_scope()) { |
| 1621 AsDeclarationScope()->AllocateLocals(ast_value_factory); |
| 1622 } |
| 1623 } |
| 1624 |
| 1625 void DeclarationScope::AllocateLocals(AstValueFactory* ast_value_factory) { |
| 1570 // For now, function_ must be allocated at the very end. If it gets | 1626 // For now, function_ must be allocated at the very end. If it gets |
| 1571 // allocated in the context, it must be the last slot in the context, | 1627 // allocated in the context, it must be the last slot in the context, |
| 1572 // because of the current ScopeInfo implementation (see | 1628 // because of the current ScopeInfo implementation (see |
| 1573 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1629 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
| 1574 if (function_ != nullptr) { | 1630 if (function_ != nullptr) { |
| 1575 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory); | 1631 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory); |
| 1576 } | 1632 } |
| 1577 | 1633 |
| 1578 if (rest_parameter_ != nullptr) { | 1634 if (rest_parameter_ != nullptr) { |
| 1579 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); | 1635 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1598 } | 1654 } |
| 1599 | 1655 |
| 1600 // If scope is already resolved, we still need to allocate | 1656 // If scope is already resolved, we still need to allocate |
| 1601 // variables in inner scopes which might not have been resolved yet. | 1657 // variables in inner scopes which might not have been resolved yet. |
| 1602 if (already_resolved()) return; | 1658 if (already_resolved()) return; |
| 1603 // The number of slots required for variables. | 1659 // The number of slots required for variables. |
| 1604 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 1660 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
| 1605 | 1661 |
| 1606 // Allocate variables for this scope. | 1662 // Allocate variables for this scope. |
| 1607 // Parameters must be allocated first, if any. | 1663 // Parameters must be allocated first, if any. |
| 1608 if (is_function_scope()) AllocateParameterLocals(); | 1664 if (is_declaration_scope()) { |
| 1609 if (has_this_declaration()) AllocateReceiver(); | 1665 if (is_function_scope()) AsDeclarationScope()->AllocateParameterLocals(); |
| 1666 AsDeclarationScope()->AllocateReceiver(); |
| 1667 } |
| 1610 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory); | 1668 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory); |
| 1611 | 1669 |
| 1612 // Force allocation of a context for this scope if necessary. For a 'with' | 1670 // Force allocation of a context for this scope if necessary. For a 'with' |
| 1613 // scope and for a function scope that makes an 'eval' call we need a context, | 1671 // scope and for a function scope that makes an 'eval' call we need a context, |
| 1614 // even if no local variables were statically allocated in the scope. | 1672 // even if no local variables were statically allocated in the scope. |
| 1615 // Likewise for modules. | 1673 // Likewise for modules. |
| 1616 bool must_have_context = | 1674 bool must_have_context = |
| 1617 is_with_scope() || is_module_scope() || | 1675 is_with_scope() || is_module_scope() || |
| 1618 (is_function_scope() && calls_sloppy_eval()) || | 1676 (is_function_scope() && calls_sloppy_eval()) || |
| 1619 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); | 1677 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); |
| 1620 | 1678 |
| 1621 // If we didn't allocate any locals in the local context, then we only | 1679 // If we didn't allocate any locals in the local context, then we only |
| 1622 // need the minimal number of slots if we must have a context. | 1680 // need the minimal number of slots if we must have a context. |
| 1623 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1681 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
| 1624 num_heap_slots_ = 0; | 1682 num_heap_slots_ = 0; |
| 1625 } | 1683 } |
| 1626 | 1684 |
| 1627 // Allocation done. | 1685 // Allocation done. |
| 1628 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1686 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
| 1629 } | 1687 } |
| 1630 | 1688 |
| 1631 | 1689 |
| 1632 int Scope::StackLocalCount() const { | 1690 int Scope::StackLocalCount() const { |
| 1691 VariableDeclaration* function = |
| 1692 is_function_scope() ? AsDeclarationScope()->function() : nullptr; |
| 1633 return num_stack_slots() - | 1693 return num_stack_slots() - |
| 1634 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1694 (function != NULL && function->proxy()->var()->IsStackLocal() ? 1 : 0); |
| 1635 } | 1695 } |
| 1636 | 1696 |
| 1637 | 1697 |
| 1638 int Scope::ContextLocalCount() const { | 1698 int Scope::ContextLocalCount() const { |
| 1639 if (num_heap_slots() == 0) return 0; | 1699 if (num_heap_slots() == 0) return 0; |
| 1700 VariableDeclaration* function = |
| 1701 is_function_scope() ? AsDeclarationScope()->function() : nullptr; |
| 1640 bool is_function_var_in_context = | 1702 bool is_function_var_in_context = |
| 1641 function_ != NULL && function_->proxy()->var()->IsContextSlot(); | 1703 function != NULL && function->proxy()->var()->IsContextSlot(); |
| 1642 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1704 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
| 1643 (is_function_var_in_context ? 1 : 0); | 1705 (is_function_var_in_context ? 1 : 0); |
| 1644 } | 1706 } |
| 1645 | 1707 |
| 1646 | 1708 |
| 1647 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1709 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
| 1648 | 1710 |
| 1649 } // namespace internal | 1711 } // namespace internal |
| 1650 } // namespace v8 | 1712 } // namespace v8 |
| OLD | NEW |