Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: src/scopes.cc

Issue 1097283003: Resolve references to "this" the same way as normal variables (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: Add tests for "this" scoping in arrow functions Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698