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/v8.h" | 5 #include "src/v8.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/parser.h" | 10 #include "src/parser.h" |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 // Declare convenience variables. | 302 // Declare convenience variables. |
303 // Declare and allocate receiver (even for the script scope, and even | 303 // Declare and allocate receiver (even for the script scope, and even |
304 // if naccesses_ == 0). | 304 // if naccesses_ == 0). |
305 // NOTE: When loading parameters in the script scope, we must take | 305 // NOTE: When loading parameters in the script scope, we must take |
306 // care not to access them as properties of the global object, but | 306 // care not to access them as properties of the global object, but |
307 // instead load them directly from the stack. Currently, the only | 307 // instead load them directly from the stack. Currently, the only |
308 // such parameter is 'this' which is passed on the stack when | 308 // such parameter is 'this' which is passed on the stack when |
309 // invoking scripts | 309 // invoking scripts |
310 if (is_declaration_scope()) { | 310 if (is_declaration_scope()) { |
311 DCHECK(!subclass_constructor || is_function_scope()); | 311 DCHECK(!subclass_constructor || is_function_scope()); |
312 Variable* var = variables_.Declare( | 312 if (has_this_declaration()) { |
313 this, ast_value_factory_->this_string(), | 313 Variable* var = variables_.Declare( |
314 subclass_constructor ? CONST : VAR, Variable::THIS, | 314 this, ast_value_factory_->this_string(), |
315 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | 315 subclass_constructor ? CONST : VAR, Variable::THIS, |
316 var->AllocateTo(Variable::PARAMETER, -1); | 316 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
317 receiver_ = var; | 317 receiver_ = var; |
| 318 } |
318 | 319 |
319 if (subclass_constructor) { | 320 if (subclass_constructor) { |
320 new_target_ = | 321 new_target_ = |
321 variables_.Declare(this, ast_value_factory_->new_target_string(), | 322 variables_.Declare(this, ast_value_factory_->new_target_string(), |
322 CONST, Variable::NEW_TARGET, kCreatedInitialized); | 323 CONST, Variable::NEW_TARGET, kCreatedInitialized); |
323 new_target_->AllocateTo(Variable::PARAMETER, -2); | 324 new_target_->AllocateTo(Variable::PARAMETER, -2); |
324 new_target_->set_is_used(); | 325 new_target_->set_is_used(); |
325 } | 326 } |
326 } else { | |
327 DCHECK(outer_scope() != NULL); | |
328 receiver_ = outer_scope()->receiver(); | |
329 } | 327 } |
330 | 328 |
331 if (is_function_scope() && !is_arrow_scope()) { | 329 if (is_function_scope() && !is_arrow_scope()) { |
332 // Declare 'arguments' variable which exists in all non arrow functions. | 330 // Declare 'arguments' variable which exists in all non arrow functions. |
333 // Note that it might never be accessed, in which case it won't be | 331 // Note that it might never be accessed, in which case it won't be |
334 // allocated during variable allocation. | 332 // allocated during variable allocation. |
335 variables_.Declare(this, | 333 variables_.Declare(this, |
336 ast_value_factory_->arguments_string(), | 334 ast_value_factory_->arguments_string(), |
337 VAR, | 335 VAR, |
338 Variable::ARGUMENTS, | 336 Variable::ARGUMENTS, |
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 // order is relevant! | 1329 // order is relevant! |
1332 for (int i = params_.length() - 1; i >= 0; --i) { | 1330 for (int i = params_.length() - 1; i >= 0; --i) { |
1333 Variable* var = params_[i]; | 1331 Variable* var = params_[i]; |
1334 if (var == rest_parameter_) continue; | 1332 if (var == rest_parameter_) continue; |
1335 | 1333 |
1336 DCHECK(var->scope() == this); | 1334 DCHECK(var->scope() == this); |
1337 if (uses_sloppy_arguments || has_forced_context_allocation()) { | 1335 if (uses_sloppy_arguments || has_forced_context_allocation()) { |
1338 // Force context allocation of the parameter. | 1336 // Force context allocation of the parameter. |
1339 var->ForceContextAllocation(); | 1337 var->ForceContextAllocation(); |
1340 } | 1338 } |
| 1339 AllocateParameter(var, i); |
| 1340 } |
| 1341 } |
1341 | 1342 |
1342 if (MustAllocate(var)) { | 1343 |
1343 if (MustAllocateInContext(var)) { | 1344 void Scope::AllocateParameter(Variable* var, int index) { |
1344 DCHECK(var->IsUnallocated() || var->IsContextSlot()); | 1345 if (MustAllocate(var)) { |
1345 if (var->IsUnallocated()) { | 1346 if (MustAllocateInContext(var)) { |
1346 AllocateHeapSlot(var); | 1347 DCHECK(var->IsUnallocated() || var->IsContextSlot()); |
1347 } | 1348 if (var->IsUnallocated()) { |
1348 } else { | 1349 AllocateHeapSlot(var); |
1349 DCHECK(var->IsUnallocated() || var->IsParameter()); | 1350 } |
1350 if (var->IsUnallocated()) { | 1351 } else { |
1351 var->AllocateTo(Variable::PARAMETER, i); | 1352 DCHECK(var->IsUnallocated() || var->IsParameter()); |
1352 } | 1353 if (var->IsUnallocated()) { |
| 1354 var->AllocateTo(Variable::PARAMETER, index); |
1353 } | 1355 } |
1354 } | 1356 } |
1355 } | 1357 } |
1356 } | 1358 } |
1357 | 1359 |
1358 | 1360 |
| 1361 void Scope::AllocateReceiver() { |
| 1362 DCHECK_NOT_NULL(receiver()); |
| 1363 DCHECK_EQ(receiver()->scope(), this); |
| 1364 |
| 1365 if (has_forced_context_allocation()) { |
| 1366 // Force context allocation of the receiver. |
| 1367 receiver()->ForceContextAllocation(); |
| 1368 } |
| 1369 AllocateParameter(receiver(), -1); |
| 1370 } |
| 1371 |
| 1372 |
1359 void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) { | 1373 void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) { |
1360 DCHECK(var->scope() == this); | 1374 DCHECK(var->scope() == this); |
1361 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) || | 1375 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) || |
1362 !var->IsStackLocal()); | 1376 !var->IsStackLocal()); |
1363 if (var->IsUnallocated() && MustAllocate(var)) { | 1377 if (var->IsUnallocated() && MustAllocate(var)) { |
1364 if (MustAllocateInContext(var)) { | 1378 if (MustAllocateInContext(var)) { |
1365 AllocateHeapSlot(var); | 1379 AllocateHeapSlot(var); |
1366 } else { | 1380 } else { |
1367 AllocateStackSlot(var); | 1381 AllocateStackSlot(var); |
1368 } | 1382 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 // If scope is already resolved, we still need to allocate | 1430 // If scope is already resolved, we still need to allocate |
1417 // variables in inner scopes which might not had been resolved yet. | 1431 // variables in inner scopes which might not had been resolved yet. |
1418 if (already_resolved()) return; | 1432 if (already_resolved()) return; |
1419 // The number of slots required for variables. | 1433 // The number of slots required for variables. |
1420 num_stack_slots_ = 0; | 1434 num_stack_slots_ = 0; |
1421 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 1435 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
1422 | 1436 |
1423 // Allocate variables for this scope. | 1437 // Allocate variables for this scope. |
1424 // Parameters must be allocated first, if any. | 1438 // Parameters must be allocated first, if any. |
1425 if (is_function_scope()) AllocateParameterLocals(isolate); | 1439 if (is_function_scope()) AllocateParameterLocals(isolate); |
| 1440 if (has_this_declaration()) AllocateReceiver(); |
1426 AllocateNonParameterLocals(isolate); | 1441 AllocateNonParameterLocals(isolate); |
1427 | 1442 |
1428 // Force allocation of a context for this scope if necessary. For a 'with' | 1443 // Force allocation of a context for this scope if necessary. For a 'with' |
1429 // scope and for a function scope that makes an 'eval' call we need a context, | 1444 // scope and for a function scope that makes an 'eval' call we need a context, |
1430 // even if no local variables were statically allocated in the scope. | 1445 // even if no local variables were statically allocated in the scope. |
1431 // Likewise for modules. | 1446 // Likewise for modules. |
1432 bool must_have_context = is_with_scope() || is_module_scope() || | 1447 bool must_have_context = is_with_scope() || is_module_scope() || |
1433 (is_function_scope() && calls_eval()); | 1448 (is_function_scope() && calls_eval()); |
1434 | 1449 |
1435 // If we didn't allocate any locals in the local context, then we only | 1450 // If we didn't allocate any locals in the local context, then we only |
(...skipping 28 matching lines...) Expand all Loading... |
1464 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1479 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
1465 } | 1480 } |
1466 | 1481 |
1467 | 1482 |
1468 int Scope::ContextLocalCount() const { | 1483 int Scope::ContextLocalCount() const { |
1469 if (num_heap_slots() == 0) return 0; | 1484 if (num_heap_slots() == 0) return 0; |
1470 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1485 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1471 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1486 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1472 } | 1487 } |
1473 } } // namespace v8::internal | 1488 } } // namespace v8::internal |
OLD | NEW |