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

Side by Side Diff: src/scopes.cc

Issue 883823002: Implement proper scoping for "this" in arrow functions Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased against master, plus fixes. Only 4 tests failing (+2 in TurboFan) Created 5 years, 9 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
« no previous file with comments | « src/scopes.h ('k') | src/variables.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/scopes.h" 7 #include "src/scopes.h"
8 8
9 #include "src/accessors.h" 9 #include "src/accessors.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 13 matching lines...) Expand all
24 // use. Because a Variable holding a handle with the same location exists 24 // use. Because a Variable holding a handle with the same location exists
25 // this is ensured. 25 // this is ensured.
26 26
27 VariableMap::VariableMap(Zone* zone) 27 VariableMap::VariableMap(Zone* zone)
28 : ZoneHashMap(ZoneHashMap::PointersMatch, 8, ZoneAllocationPolicy(zone)), 28 : ZoneHashMap(ZoneHashMap::PointersMatch, 8, ZoneAllocationPolicy(zone)),
29 zone_(zone) {} 29 zone_(zone) {}
30 VariableMap::~VariableMap() {} 30 VariableMap::~VariableMap() {}
31 31
32 32
33 Variable* VariableMap::Declare(Scope* scope, const AstRawString* name, 33 Variable* VariableMap::Declare(Scope* scope, const AstRawString* name,
34 VariableMode mode, bool is_valid_lhs, 34 VariableMode mode, Variable::Kind kind,
35 Variable::Kind kind,
36 InitializationFlag initialization_flag, 35 InitializationFlag initialization_flag,
37 MaybeAssignedFlag maybe_assigned_flag) { 36 MaybeAssignedFlag maybe_assigned_flag) {
38 // AstRawStrings are unambiguous, i.e., the same string is always represented 37 // AstRawStrings are unambiguous, i.e., the same string is always represented
39 // by the same AstRawString*. 38 // by the same AstRawString*.
40 // FIXME(marja): fix the type of Lookup. 39 // FIXME(marja): fix the type of Lookup.
41 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(), 40 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(),
42 true, ZoneAllocationPolicy(zone())); 41 true, ZoneAllocationPolicy(zone()));
43 if (p->value == NULL) { 42 if (p->value == NULL) {
44 // The variable has not been declared yet -> insert it. 43 // The variable has not been declared yet -> insert it.
45 DCHECK(p->key == name); 44 DCHECK(p->key == name);
46 p->value = new (zone()) Variable(scope, name, mode, is_valid_lhs, kind, 45 p->value = new (zone()) Variable(scope, name, mode, kind,
47 initialization_flag, maybe_assigned_flag); 46 initialization_flag, maybe_assigned_flag);
48 } 47 }
49 return reinterpret_cast<Variable*>(p->value); 48 return reinterpret_cast<Variable*>(p->value);
50 } 49 }
51 50
52 51
53 Variable* VariableMap::Lookup(const AstRawString* name) { 52 Variable* VariableMap::Lookup(const AstRawString* name) {
54 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(), 53 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(),
55 false, ZoneAllocationPolicy(NULL)); 54 false, ZoneAllocationPolicy(NULL));
56 if (p != NULL) { 55 if (p != NULL) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 already_resolved_(true), 123 already_resolved_(true),
125 ast_value_factory_(value_factory), 124 ast_value_factory_(value_factory),
126 zone_(zone) { 125 zone_(zone) {
127 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); 126 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null());
128 AddInnerScope(inner_scope); 127 AddInnerScope(inner_scope);
129 ++num_var_or_const_; 128 ++num_var_or_const_;
130 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 129 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
131 Variable* variable = variables_.Declare(this, 130 Variable* variable = variables_.Declare(this,
132 catch_variable_name, 131 catch_variable_name,
133 VAR, 132 VAR,
134 true, // Valid left-hand side.
135 Variable::NORMAL, 133 Variable::NORMAL,
136 kCreatedInitialized); 134 kCreatedInitialized);
137 AllocateHeapSlot(variable); 135 AllocateHeapSlot(variable);
138 } 136 }
139 137
140 138
141 void Scope::SetDefaults(ScopeType scope_type, 139 void Scope::SetDefaults(ScopeType scope_type,
142 Scope* outer_scope, 140 Scope* outer_scope,
143 Handle<ScopeInfo> scope_info) { 141 Handle<ScopeInfo> scope_info) {
144 outer_scope_ = outer_scope; 142 outer_scope_ = outer_scope;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 // Declare convenience variables. 291 // Declare convenience variables.
294 // Declare and allocate receiver (even for the script scope, and even 292 // Declare and allocate receiver (even for the script scope, and even
295 // if naccesses_ == 0). 293 // if naccesses_ == 0).
296 // NOTE: When loading parameters in the script scope, we must take 294 // NOTE: When loading parameters in the script scope, we must take
297 // care not to access them as properties of the global object, but 295 // care not to access them as properties of the global object, but
298 // instead load them directly from the stack. Currently, the only 296 // instead load them directly from the stack. Currently, the only
299 // such parameter is 'this' which is passed on the stack when 297 // such parameter is 'this' which is passed on the stack when
300 // invoking scripts 298 // invoking scripts
301 if (is_declaration_scope()) { 299 if (is_declaration_scope()) {
302 DCHECK(!subclass_constructor || is_function_scope()); 300 DCHECK(!subclass_constructor || is_function_scope());
303 Variable* var = variables_.Declare( 301 if (has_this_declaration()) {
304 this, ast_value_factory_->this_string(), 302 Variable* var = variables_.Declare(
305 subclass_constructor ? CONST : VAR, false, Variable::THIS, 303 this, ast_value_factory_->this_string(),
306 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); 304 subclass_constructor ? CONST : VAR, Variable::THIS,
307 var->AllocateTo(Variable::PARAMETER, -1); 305 subclass_constructor ? kNeedsInitialization : kCreatedInitialized);
308 receiver_ = var; 306 receiver_ = var;
307 }
309 308
310 if (subclass_constructor) { 309 if (subclass_constructor) {
311 new_target_ = variables_.Declare( 310 new_target_ =
312 this, ast_value_factory_->new_target_string(), CONST, false, 311 variables_.Declare(this, ast_value_factory_->new_target_string(),
313 Variable::NEW_TARGET, kCreatedInitialized); 312 CONST, Variable::NEW_TARGET, kCreatedInitialized);
314 new_target_->AllocateTo(Variable::PARAMETER, -2); 313 new_target_->AllocateTo(Variable::PARAMETER, -2);
315 new_target_->set_is_used(); 314 new_target_->set_is_used();
316 } 315 }
317 } else {
318 DCHECK(outer_scope() != NULL);
319 receiver_ = outer_scope()->receiver();
320 } 316 }
321 317
322 if (is_function_scope()) { 318 if (is_function_scope()) {
323 // Declare 'arguments' variable which exists in all functions. 319 // Declare 'arguments' variable which exists in all functions.
324 // Note that it might never be accessed, in which case it won't be 320 // Note that it might never be accessed, in which case it won't be
325 // allocated during variable allocation. 321 // allocated during variable allocation.
326 variables_.Declare(this, 322 variables_.Declare(this,
327 ast_value_factory_->arguments_string(), 323 ast_value_factory_->arguments_string(),
328 VAR, 324 VAR,
329 true,
330 Variable::ARGUMENTS, 325 Variable::ARGUMENTS,
331 kCreatedInitialized); 326 kCreatedInitialized);
332 } 327 }
333 } 328 }
334 329
335 330
336 Scope* Scope::FinalizeBlockScope() { 331 Scope* Scope::FinalizeBlockScope() {
337 DCHECK(is_block_scope()); 332 DCHECK(is_block_scope());
338 DCHECK(internals_.is_empty()); 333 DCHECK(internals_.is_empty());
339 DCHECK(temps_.is_empty()); 334 DCHECK(temps_.is_empty());
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 390
396 mode = DYNAMIC; 391 mode = DYNAMIC;
397 location = Variable::LOOKUP; 392 location = Variable::LOOKUP;
398 init_flag = kCreatedInitialized; 393 init_flag = kCreatedInitialized;
399 // Be conservative and flag parameters as maybe assigned. Better information 394 // Be conservative and flag parameters as maybe assigned. Better information
400 // would require ScopeInfo to serialize the maybe_assigned bit also for 395 // would require ScopeInfo to serialize the maybe_assigned bit also for
401 // parameters. 396 // parameters.
402 maybe_assigned_flag = kMaybeAssigned; 397 maybe_assigned_flag = kMaybeAssigned;
403 } 398 }
404 399
405 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, 400 Variable* var = variables_.Declare(this, name, mode, Variable::NORMAL,
406 init_flag, maybe_assigned_flag); 401 init_flag, maybe_assigned_flag);
407 var->AllocateTo(location, index); 402 var->AllocateTo(location, index);
408 return var; 403 return var;
409 } 404 }
410 405
411 406
412 Variable* Scope::LookupFunctionVar(const AstRawString* name, 407 Variable* Scope::LookupFunctionVar(const AstRawString* name,
413 AstNodeFactory* factory) { 408 AstNodeFactory* factory) {
414 if (function_ != NULL && function_->proxy()->raw_name() == name) { 409 if (function_ != NULL && function_->proxy()->raw_name() == name) {
415 return function_->proxy()->var(); 410 return function_->proxy()->var();
416 } else if (!scope_info_.is_null()) { 411 } else if (!scope_info_.is_null()) {
417 // If we are backed by a scope info, try to lookup the variable there. 412 // If we are backed by a scope info, try to lookup the variable there.
418 VariableMode mode; 413 VariableMode mode;
419 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); 414 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode);
420 if (index < 0) return NULL; 415 if (index < 0) return NULL;
421 Variable* var = new(zone()) Variable( 416 Variable* var = new (zone())
422 this, name, mode, true /* is valid LHS */, 417 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized);
423 Variable::NORMAL, kCreatedInitialized);
424 VariableProxy* proxy = factory->NewVariableProxy(var); 418 VariableProxy* proxy = factory->NewVariableProxy(var);
425 VariableDeclaration* declaration = factory->NewVariableDeclaration( 419 VariableDeclaration* declaration = factory->NewVariableDeclaration(
426 proxy, mode, this, RelocInfo::kNoPosition); 420 proxy, mode, this, RelocInfo::kNoPosition);
427 DeclareFunctionVar(declaration); 421 DeclareFunctionVar(declaration);
428 var->AllocateTo(Variable::CONTEXT, index); 422 var->AllocateTo(Variable::CONTEXT, index);
429 return var; 423 return var;
430 } else { 424 } else {
431 return NULL; 425 return NULL;
432 } 426 }
433 } 427 }
434 428
435 429
436 Variable* Scope::Lookup(const AstRawString* name) { 430 Variable* Scope::Lookup(const AstRawString* name) {
437 for (Scope* scope = this; 431 for (Scope* scope = this;
438 scope != NULL; 432 scope != NULL;
439 scope = scope->outer_scope()) { 433 scope = scope->outer_scope()) {
440 Variable* var = scope->LookupLocal(name); 434 Variable* var = scope->LookupLocal(name);
441 if (var != NULL) return var; 435 if (var != NULL) return var;
442 } 436 }
443 return NULL; 437 return NULL;
444 } 438 }
445 439
446 440
447 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, 441 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode,
448 bool is_rest) { 442 bool is_rest) {
449 DCHECK(!already_resolved()); 443 DCHECK(!already_resolved());
450 DCHECK(is_function_scope()); 444 DCHECK(is_function_scope());
451 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, 445 Variable* var = variables_.Declare(this, name, mode, Variable::NORMAL,
452 kCreatedInitialized); 446 kCreatedInitialized);
453 if (is_rest) { 447 if (is_rest) {
454 DCHECK_NULL(rest_parameter_); 448 DCHECK_NULL(rest_parameter_);
455 rest_parameter_ = var; 449 rest_parameter_ = var;
456 rest_index_ = num_parameters(); 450 rest_index_ = num_parameters();
457 } 451 }
458 params_.Add(var, zone()); 452 params_.Add(var, zone());
459 return var; 453 return var;
460 } 454 }
461 455
462 456
463 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, 457 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
464 InitializationFlag init_flag, 458 InitializationFlag init_flag,
465 MaybeAssignedFlag maybe_assigned_flag) { 459 MaybeAssignedFlag maybe_assigned_flag) {
466 DCHECK(!already_resolved()); 460 DCHECK(!already_resolved());
467 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are 461 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are
468 // introduces during variable allocation, INTERNAL variables are allocated 462 // introduces during variable allocation, INTERNAL variables are allocated
469 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). 463 // explicitly, and TEMPORARY variables are allocated via NewTemporary().
470 DCHECK(IsDeclaredVariableMode(mode)); 464 DCHECK(IsDeclaredVariableMode(mode));
471 ++num_var_or_const_; 465 ++num_var_or_const_;
472 return variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag, 466 return variables_.Declare(this, name, mode, Variable::NORMAL, init_flag,
473 maybe_assigned_flag); 467 maybe_assigned_flag);
474 } 468 }
475 469
476 470
477 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { 471 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) {
478 DCHECK(is_script_scope()); 472 DCHECK(is_script_scope());
479 return variables_.Declare(this, 473 return variables_.Declare(this,
480 name, 474 name,
481 DYNAMIC_GLOBAL, 475 DYNAMIC_GLOBAL,
482 true,
483 Variable::NORMAL, 476 Variable::NORMAL,
484 kCreatedInitialized); 477 kCreatedInitialized);
485 } 478 }
486 479
487 480
488 void Scope::RemoveUnresolved(VariableProxy* var) { 481 void Scope::RemoveUnresolved(VariableProxy* var) {
489 // Most likely (always?) any variable we want to remove 482 // Most likely (always?) any variable we want to remove
490 // was just added before, so we search backwards. 483 // was just added before, so we search backwards.
491 for (int i = unresolved_.length(); i-- > 0;) { 484 for (int i = unresolved_.length(); i-- > 0;) {
492 if (unresolved_[i] == var) { 485 if (unresolved_[i] == var) {
493 unresolved_.Remove(i); 486 unresolved_.Remove(i);
494 return; 487 return;
495 } 488 }
496 } 489 }
497 } 490 }
498 491
499 492
500 Variable* Scope::NewInternal(const AstRawString* name) { 493 Variable* Scope::NewInternal(const AstRawString* name) {
501 DCHECK(!already_resolved()); 494 DCHECK(!already_resolved());
502 Variable* var = new(zone()) Variable(this, 495 Variable* var = new(zone()) Variable(this,
503 name, 496 name,
504 INTERNAL, 497 INTERNAL,
505 false,
506 Variable::NORMAL, 498 Variable::NORMAL,
507 kCreatedInitialized); 499 kCreatedInitialized);
508 internals_.Add(var, zone()); 500 internals_.Add(var, zone());
509 return var; 501 return var;
510 } 502 }
511 503
512 504
513 Variable* Scope::NewTemporary(const AstRawString* name) { 505 Variable* Scope::NewTemporary(const AstRawString* name) {
514 DCHECK(!already_resolved()); 506 DCHECK(!already_resolved());
515 Variable* var = new(zone()) Variable(this, 507 Variable* var = new(zone()) Variable(this,
516 name, 508 name,
517 TEMPORARY, 509 TEMPORARY,
518 true,
519 Variable::NORMAL, 510 Variable::NORMAL,
520 kCreatedInitialized); 511 kCreatedInitialized);
521 temps_.Add(var, zone()); 512 temps_.Add(var, zone());
522 return var; 513 return var;
523 } 514 }
524 515
525 516
526 void Scope::AddDeclaration(Declaration* declaration) { 517 void Scope::AddDeclaration(Declaration* declaration) {
527 decls_.Add(declaration, zone()); 518 decls_.Add(declaration, zone());
528 } 519 }
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); 946 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone());
956 VariableMap* map = dynamics_->GetMap(mode); 947 VariableMap* map = dynamics_->GetMap(mode);
957 Variable* var = map->Lookup(name); 948 Variable* var = map->Lookup(name);
958 if (var == NULL) { 949 if (var == NULL) {
959 // Declare a new non-local. 950 // Declare a new non-local.
960 InitializationFlag init_flag = (mode == VAR) 951 InitializationFlag init_flag = (mode == VAR)
961 ? kCreatedInitialized : kNeedsInitialization; 952 ? kCreatedInitialized : kNeedsInitialization;
962 var = map->Declare(NULL, 953 var = map->Declare(NULL,
963 name, 954 name,
964 mode, 955 mode,
965 true,
966 Variable::NORMAL, 956 Variable::NORMAL,
967 init_flag); 957 init_flag);
968 // Allocate it by giving it a dynamic lookup. 958 // Allocate it by giving it a dynamic lookup.
969 var->AllocateTo(Variable::LOOKUP, -1); 959 var->AllocateTo(Variable::LOOKUP, -1);
970 } 960 }
971 return var; 961 return var;
972 } 962 }
973 963
974 964
975 Variable* Scope::LookupRecursive(VariableProxy* proxy, 965 Variable* Scope::LookupRecursive(VariableProxy* proxy,
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 // via an eval() call. This is only possible if the variable has a 1145 // via an eval() call. This is only possible if the variable has a
1156 // visible name. 1146 // visible name.
1157 if ((var->is_this() || var->is_new_target() || !var->raw_name()->IsEmpty()) && 1147 if ((var->is_this() || var->is_new_target() || !var->raw_name()->IsEmpty()) &&
1158 (var->has_forced_context_allocation() || scope_calls_eval_ || 1148 (var->has_forced_context_allocation() || scope_calls_eval_ ||
1159 inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() || 1149 inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() ||
1160 is_block_scope() || is_module_scope() || is_script_scope())) { 1150 is_block_scope() || is_module_scope() || is_script_scope())) {
1161 var->set_is_used(); 1151 var->set_is_used();
1162 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); 1152 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned();
1163 } 1153 }
1164 // Global variables do not need to be allocated. 1154 // Global variables do not need to be allocated.
1165 return !var->IsGlobalObjectProperty() && var->is_used(); 1155 return var->is_this() || (var->is_used() && !var->IsGlobalObjectProperty());
1166 } 1156 }
1167 1157
1168 1158
1169 bool Scope::MustAllocateInContext(Variable* var) { 1159 bool Scope::MustAllocateInContext(Variable* var) {
1170 // If var is accessed from an inner scope, or if there is a possibility 1160 // If var is accessed from an inner scope, or if there is a possibility
1171 // that it might be accessed from the current or an inner scope (through 1161 // that it might be accessed from the current or an inner scope (through
1172 // an eval() call or a runtime with lookup), it must be allocated in the 1162 // an eval() call or a runtime with lookup), it must be allocated in the
1173 // context. 1163 // context.
1174 // 1164 //
1175 // Exceptions: If the scope as a whole has forced context allocation, all 1165 // Exceptions: If the scope as a whole has forced context allocation, all
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 // order is relevant! 1236 // order is relevant!
1247 for (int i = params_.length() - 1; i >= 0; --i) { 1237 for (int i = params_.length() - 1; i >= 0; --i) {
1248 Variable* var = params_[i]; 1238 Variable* var = params_[i];
1249 if (var == rest_parameter_) continue; 1239 if (var == rest_parameter_) continue;
1250 1240
1251 DCHECK(var->scope() == this); 1241 DCHECK(var->scope() == this);
1252 if (uses_sloppy_arguments || has_forced_context_allocation()) { 1242 if (uses_sloppy_arguments || has_forced_context_allocation()) {
1253 // Force context allocation of the parameter. 1243 // Force context allocation of the parameter.
1254 var->ForceContextAllocation(); 1244 var->ForceContextAllocation();
1255 } 1245 }
1246 AllocateParameter(var, i);
1247 }
1248 }
1256 1249
1257 if (MustAllocate(var)) { 1250
1258 if (MustAllocateInContext(var)) { 1251 void Scope::AllocateParameter(Variable* var, int index) {
1259 DCHECK(var->IsUnallocated() || var->IsContextSlot()); 1252 if (MustAllocate(var)) {
1260 if (var->IsUnallocated()) { 1253 if (MustAllocateInContext(var)) {
1261 AllocateHeapSlot(var); 1254 DCHECK(var->IsUnallocated() || var->IsContextSlot());
1262 } 1255 if (var->IsUnallocated()) {
1263 } else { 1256 AllocateHeapSlot(var);
1264 DCHECK(var->IsUnallocated() || var->IsParameter()); 1257 }
1265 if (var->IsUnallocated()) { 1258 } else {
1266 var->AllocateTo(Variable::PARAMETER, i); 1259 DCHECK(var->IsUnallocated() || var->IsParameter());
1267 } 1260 if (var->IsUnallocated()) {
1261 var->AllocateTo(Variable::PARAMETER, index);
1268 } 1262 }
1269 } 1263 }
1270 } 1264 }
1271 } 1265 }
1272 1266
1273 1267
1268 void Scope::AllocateReceiver() {
1269 DCHECK_EQ(receiver()->scope(), this);
1270
1271 if (is_script_scope()) {
1272 receiver()->AllocateTo(Variable::PARAMETER, -1);
1273 } else {
1274 if (has_forced_context_allocation()) {
1275 receiver()->ForceContextAllocation();
1276 }
1277 AllocateParameter(receiver(), -1);
1278 }
1279 }
1280
1281
1274 void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) { 1282 void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) {
1275 DCHECK(var->scope() == this); 1283 DCHECK(var->scope() == this);
1276 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) || 1284 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) ||
1277 !var->IsStackLocal()); 1285 !var->IsStackLocal());
1278 if (var->IsUnallocated() && MustAllocate(var)) { 1286 if (var->IsUnallocated() && MustAllocate(var)) {
1279 if (MustAllocateInContext(var)) { 1287 if (MustAllocateInContext(var)) {
1280 AllocateHeapSlot(var); 1288 AllocateHeapSlot(var);
1281 } else { 1289 } else {
1282 AllocateStackSlot(var); 1290 AllocateStackSlot(var);
1283 } 1291 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 // If scope is already resolved, we still need to allocate 1339 // If scope is already resolved, we still need to allocate
1332 // variables in inner scopes which might not had been resolved yet. 1340 // variables in inner scopes which might not had been resolved yet.
1333 if (already_resolved()) return; 1341 if (already_resolved()) return;
1334 // The number of slots required for variables. 1342 // The number of slots required for variables.
1335 num_stack_slots_ = 0; 1343 num_stack_slots_ = 0;
1336 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 1344 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
1337 1345
1338 // Allocate variables for this scope. 1346 // Allocate variables for this scope.
1339 // Parameters must be allocated first, if any. 1347 // Parameters must be allocated first, if any.
1340 if (is_function_scope()) AllocateParameterLocals(isolate); 1348 if (is_function_scope()) AllocateParameterLocals(isolate);
1349 if (has_this_declaration()) AllocateReceiver();
1341 AllocateNonParameterLocals(isolate); 1350 AllocateNonParameterLocals(isolate);
1342 1351
1343 // Force allocation of a context for this scope if necessary. For a 'with' 1352 // Force allocation of a context for this scope if necessary. For a 'with'
1344 // scope and for a function scope that makes an 'eval' call we need a context, 1353 // scope and for a function scope that makes an 'eval' call we need a context,
1345 // even if no local variables were statically allocated in the scope. 1354 // even if no local variables were statically allocated in the scope.
1346 // Likewise for modules. 1355 // Likewise for modules.
1347 bool must_have_context = is_with_scope() || is_module_scope() || 1356 bool must_have_context = is_with_scope() || is_module_scope() ||
1348 (is_function_scope() && calls_eval()); 1357 (is_function_scope() && calls_eval());
1349 1358
1350 // If we didn't allocate any locals in the local context, then we only 1359 // If we didn't allocate any locals in the local context, then we only
(...skipping 30 matching lines...) Expand all
1381 } 1390 }
1382 1391
1383 1392
1384 int Scope::ContextLocalCount() const { 1393 int Scope::ContextLocalCount() const {
1385 if (num_heap_slots() == 0) return 0; 1394 if (num_heap_slots() == 0) return 0;
1386 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1395 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1387 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); 1396 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
1388 } 1397 }
1389 1398
1390 } } // namespace v8::internal 1399 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | src/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698