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

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: mjsunit/debug-scopes: Skip "this" the same as "arguments" Created 5 years, 10 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
« src/scopes.h ('K') | « 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,
35 Variable::Kind kind, 35 Variable::Kind kind,
36 InitializationFlag initialization_flag, 36 InitializationFlag initialization_flag,
37 MaybeAssignedFlag maybe_assigned_flag, 37 MaybeAssignedFlag maybe_assigned_flag,
38 Interface* interface) { 38 Interface* interface) {
39 // AstRawStrings are unambiguous, i.e., the same string is always represented 39 // AstRawStrings are unambiguous, i.e., the same string is always represented
40 // by the same AstRawString*. 40 // by the same AstRawString*.
41 // FIXME(marja): fix the type of Lookup. 41 // FIXME(marja): fix the type of Lookup.
42 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(), 42 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(),
43 true, ZoneAllocationPolicy(zone())); 43 true, ZoneAllocationPolicy(zone()));
44 if (p->value == NULL) { 44 if (p->value == NULL) {
45 // The variable has not been declared yet -> insert it. 45 // The variable has not been declared yet -> insert it.
46 DCHECK(p->key == name); 46 DCHECK(p->key == name);
47 p->value = new (zone()) 47 p->value = new (zone())
48 Variable(scope, name, mode, is_valid_lhs, kind, initialization_flag, 48 Variable(scope, name, mode, kind, initialization_flag,
49 maybe_assigned_flag, interface); 49 maybe_assigned_flag, interface);
50 } 50 }
51 return reinterpret_cast<Variable*>(p->value); 51 return reinterpret_cast<Variable*>(p->value);
52 } 52 }
53 53
54 54
55 Variable* VariableMap::Lookup(const AstRawString* name) { 55 Variable* VariableMap::Lookup(const AstRawString* name) {
56 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(), 56 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(),
57 false, ZoneAllocationPolicy(NULL)); 57 false, ZoneAllocationPolicy(NULL));
58 if (p != NULL) { 58 if (p != NULL) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 already_resolved_(true), 130 already_resolved_(true),
131 ast_value_factory_(value_factory), 131 ast_value_factory_(value_factory),
132 zone_(zone) { 132 zone_(zone) {
133 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); 133 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null());
134 AddInnerScope(inner_scope); 134 AddInnerScope(inner_scope);
135 ++num_var_or_const_; 135 ++num_var_or_const_;
136 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 136 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
137 Variable* variable = variables_.Declare(this, 137 Variable* variable = variables_.Declare(this,
138 catch_variable_name, 138 catch_variable_name,
139 VAR, 139 VAR,
140 true, // Valid left-hand side.
141 Variable::NORMAL, 140 Variable::NORMAL,
142 kCreatedInitialized); 141 kCreatedInitialized);
143 AllocateHeapSlot(variable); 142 AllocateHeapSlot(variable);
144 } 143 }
145 144
146 145
147 void Scope::SetDefaults(ScopeType scope_type, 146 void Scope::SetDefaults(ScopeType scope_type,
148 Scope* outer_scope, 147 Scope* outer_scope,
149 Handle<ScopeInfo> scope_info) { 148 Handle<ScopeInfo> scope_info) {
150 outer_scope_ = outer_scope; 149 outer_scope_ = outer_scope;
151 scope_type_ = scope_type; 150 scope_type_ = scope_type;
152 scope_name_ = ast_value_factory_->empty_string(); 151 scope_name_ = ast_value_factory_->empty_string();
153 dynamics_ = NULL; 152 dynamics_ = NULL;
154 receiver_ = NULL; 153 receiver_ = NULL;
155 function_ = NULL; 154 function_ = NULL;
156 arguments_ = NULL; 155 arguments_ = NULL;
157 illegal_redecl_ = NULL; 156 illegal_redecl_ = NULL;
158 scope_inside_with_ = false; 157 scope_inside_with_ = false;
159 scope_contains_with_ = false; 158 scope_contains_with_ = false;
160 scope_calls_eval_ = false; 159 scope_calls_eval_ = false;
161 scope_uses_arguments_ = false; 160 scope_uses_arguments_ = false;
162 scope_uses_super_property_ = false; 161 scope_uses_super_property_ = false;
163 scope_uses_super_constructor_call_ = false; 162 scope_uses_super_constructor_call_ = false;
164 scope_uses_this_ = false;
165 asm_module_ = false; 163 asm_module_ = false;
166 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; 164 asm_function_ = outer_scope != NULL && outer_scope->asm_module_;
167 // Inherit the strict mode from the parent scope. 165 // Inherit the strict mode from the parent scope.
168 strict_mode_ = outer_scope != NULL ? outer_scope->strict_mode_ : SLOPPY; 166 strict_mode_ = outer_scope != NULL ? outer_scope->strict_mode_ : SLOPPY;
169 outer_scope_calls_sloppy_eval_ = false; 167 outer_scope_calls_sloppy_eval_ = false;
170 inner_scope_calls_eval_ = false; 168 inner_scope_calls_eval_ = false;
171 inner_scope_uses_arguments_ = false; 169 inner_scope_uses_arguments_ = false;
172 inner_scope_uses_this_ = false;
173 inner_scope_uses_super_property_ = false; 170 inner_scope_uses_super_property_ = false;
174 inner_scope_uses_super_constructor_call_ = false; 171 inner_scope_uses_super_constructor_call_ = false;
175 force_eager_compilation_ = false; 172 force_eager_compilation_ = false;
176 force_context_allocation_ = (outer_scope != NULL && !is_function_scope()) 173 force_context_allocation_ = (outer_scope != NULL && !is_function_scope())
177 ? outer_scope->has_forced_context_allocation() : false; 174 ? outer_scope->has_forced_context_allocation() : false;
178 num_var_or_const_ = 0; 175 num_var_or_const_ = 0;
179 num_stack_slots_ = 0; 176 num_stack_slots_ = 0;
180 num_heap_slots_ = 0; 177 num_heap_slots_ = 0;
181 num_modules_ = 0; 178 num_modules_ = 0;
182 module_var_ = NULL, 179 module_var_ = NULL,
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 } 300 }
304 301
305 // Declare convenience variables. 302 // Declare convenience variables.
306 // Declare and allocate receiver (even for the script scope, and even 303 // Declare and allocate receiver (even for the script scope, and even
307 // if naccesses_ == 0). 304 // if naccesses_ == 0).
308 // NOTE: When loading parameters in the script scope, we must take 305 // NOTE: When loading parameters in the script scope, we must take
309 // 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
310 // instead load them directly from the stack. Currently, the only 307 // instead load them directly from the stack. Currently, the only
311 // such parameter is 'this' which is passed on the stack when 308 // such parameter is 'this' which is passed on the stack when
312 // invoking scripts 309 // invoking scripts
313 if (is_declaration_scope()) { 310 if (has_this_declaration()) {
314 Variable* var = 311 Variable* var =
315 variables_.Declare(this, 312 variables_.Declare(this,
316 ast_value_factory_->this_string(), 313 ast_value_factory_->this_string(),
317 VAR, 314 VAR,
318 false,
319 Variable::THIS, 315 Variable::THIS,
320 kCreatedInitialized); 316 kCreatedInitialized);
321 var->AllocateTo(Variable::PARAMETER, -1);
322 receiver_ = var; 317 receiver_ = var;
323 } else {
324 DCHECK(outer_scope() != NULL);
325 receiver_ = outer_scope()->receiver();
326 } 318 }
327 319
328 if (is_function_scope()) { 320 if (is_function_scope()) {
329 // Declare 'arguments' variable which exists in all functions. 321 // Declare 'arguments' variable which exists in all functions.
330 // Note that it might never be accessed, in which case it won't be 322 // Note that it might never be accessed, in which case it won't be
331 // allocated during variable allocation. 323 // allocated during variable allocation.
332 variables_.Declare(this, 324 variables_.Declare(this,
333 ast_value_factory_->arguments_string(), 325 ast_value_factory_->arguments_string(),
334 VAR, 326 VAR,
335 true,
336 Variable::ARGUMENTS, 327 Variable::ARGUMENTS,
337 kCreatedInitialized); 328 kCreatedInitialized);
338 } 329 }
339 } 330 }
340 331
341 332
342 Scope* Scope::FinalizeBlockScope() { 333 Scope* Scope::FinalizeBlockScope() {
343 DCHECK(is_block_scope()); 334 DCHECK(is_block_scope());
344 DCHECK(internals_.is_empty()); 335 DCHECK(internals_.is_empty());
345 DCHECK(temps_.is_empty()); 336 DCHECK(temps_.is_empty());
(...skipping 17 matching lines...) Expand all
363 // Move unresolved variables 354 // Move unresolved variables
364 for (int i = 0; i < unresolved_.length(); i++) { 355 for (int i = 0; i < unresolved_.length(); i++) {
365 outer_scope()->unresolved_.Add(unresolved_[i], zone()); 356 outer_scope()->unresolved_.Add(unresolved_[i], zone());
366 } 357 }
367 358
368 // Propagate usage flags to outer scope. 359 // Propagate usage flags to outer scope.
369 if (uses_arguments()) outer_scope_->RecordArgumentsUsage(); 360 if (uses_arguments()) outer_scope_->RecordArgumentsUsage();
370 if (uses_super_property()) outer_scope_->RecordSuperPropertyUsage(); 361 if (uses_super_property()) outer_scope_->RecordSuperPropertyUsage();
371 if (uses_super_constructor_call()) 362 if (uses_super_constructor_call())
372 outer_scope_->RecordSuperConstructorCallUsage(); 363 outer_scope_->RecordSuperConstructorCallUsage();
373 if (uses_this()) outer_scope_->RecordThisUsage();
374 364
375 return NULL; 365 return NULL;
376 } 366 }
377 367
378 368
379 Variable* Scope::LookupLocal(const AstRawString* name) { 369 Variable* Scope::LookupLocal(const AstRawString* name) {
380 Variable* result = variables_.Lookup(name); 370 Variable* result = variables_.Lookup(name);
381 if (result != NULL || scope_info_.is_null()) { 371 if (result != NULL || scope_info_.is_null()) {
382 return result; 372 return result;
383 } 373 }
(...skipping 19 matching lines...) Expand all
403 393
404 mode = DYNAMIC; 394 mode = DYNAMIC;
405 location = Variable::LOOKUP; 395 location = Variable::LOOKUP;
406 init_flag = kCreatedInitialized; 396 init_flag = kCreatedInitialized;
407 // Be conservative and flag parameters as maybe assigned. Better information 397 // Be conservative and flag parameters as maybe assigned. Better information
408 // would require ScopeInfo to serialize the maybe_assigned bit also for 398 // would require ScopeInfo to serialize the maybe_assigned bit also for
409 // parameters. 399 // parameters.
410 maybe_assigned_flag = kMaybeAssigned; 400 maybe_assigned_flag = kMaybeAssigned;
411 } 401 }
412 402
413 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, 403 Variable* var = variables_.Declare(this, name, mode, Variable::NORMAL,
414 init_flag, maybe_assigned_flag); 404 init_flag, maybe_assigned_flag);
415 var->AllocateTo(location, index); 405 var->AllocateTo(location, index);
416 return var; 406 return var;
417 } 407 }
418 408
419 409
420 Variable* Scope::LookupFunctionVar(const AstRawString* name, 410 Variable* Scope::LookupFunctionVar(const AstRawString* name,
421 AstNodeFactory* factory) { 411 AstNodeFactory* factory) {
422 if (function_ != NULL && function_->proxy()->raw_name() == name) { 412 if (function_ != NULL && function_->proxy()->raw_name() == name) {
423 return function_->proxy()->var(); 413 return function_->proxy()->var();
424 } else if (!scope_info_.is_null()) { 414 } else if (!scope_info_.is_null()) {
425 // If we are backed by a scope info, try to lookup the variable there. 415 // If we are backed by a scope info, try to lookup the variable there.
426 VariableMode mode; 416 VariableMode mode;
427 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); 417 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode);
428 if (index < 0) return NULL; 418 if (index < 0) return NULL;
429 Variable* var = new(zone()) Variable( 419 Variable* var = new(zone()) Variable(this, name,
430 this, name, mode, true /* is valid LHS */, 420 mode, Variable::NORMAL, kCreatedInitialized);
431 Variable::NORMAL, kCreatedInitialized);
432 VariableProxy* proxy = factory->NewVariableProxy(var); 421 VariableProxy* proxy = factory->NewVariableProxy(var);
433 VariableDeclaration* declaration = factory->NewVariableDeclaration( 422 VariableDeclaration* declaration = factory->NewVariableDeclaration(
434 proxy, mode, this, RelocInfo::kNoPosition); 423 proxy, mode, this, RelocInfo::kNoPosition);
435 DeclareFunctionVar(declaration); 424 DeclareFunctionVar(declaration);
436 var->AllocateTo(Variable::CONTEXT, index); 425 var->AllocateTo(Variable::CONTEXT, index);
437 return var; 426 return var;
438 } else { 427 } else {
439 return NULL; 428 return NULL;
440 } 429 }
441 } 430 }
442 431
443 432
444 Variable* Scope::Lookup(const AstRawString* name) { 433 Variable* Scope::Lookup(const AstRawString* name) {
445 for (Scope* scope = this; 434 for (Scope* scope = this;
446 scope != NULL; 435 scope != NULL;
447 scope = scope->outer_scope()) { 436 scope = scope->outer_scope()) {
448 Variable* var = scope->LookupLocal(name); 437 Variable* var = scope->LookupLocal(name);
449 if (var != NULL) return var; 438 if (var != NULL) return var;
450 } 439 }
451 return NULL; 440 return NULL;
452 } 441 }
453 442
454 443
455 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, 444 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode,
456 bool is_rest) { 445 bool is_rest) {
457 DCHECK(!already_resolved()); 446 DCHECK(!already_resolved());
458 DCHECK(is_function_scope()); 447 DCHECK(is_function_scope());
459 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, 448 Variable* var = variables_.Declare(this, name, mode, Variable::NORMAL,
460 kCreatedInitialized); 449 kCreatedInitialized);
461 if (is_rest) { 450 if (is_rest) {
462 DCHECK_NULL(rest_parameter_); 451 DCHECK_NULL(rest_parameter_);
463 rest_parameter_ = var; 452 rest_parameter_ = var;
464 rest_index_ = num_parameters(); 453 rest_index_ = num_parameters();
465 } 454 }
466 params_.Add(var, zone()); 455 params_.Add(var, zone());
467 return var; 456 return var;
468 } 457 }
469 458
470 459
471 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, 460 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
472 InitializationFlag init_flag, 461 InitializationFlag init_flag,
473 MaybeAssignedFlag maybe_assigned_flag, 462 MaybeAssignedFlag maybe_assigned_flag,
474 Interface* interface) { 463 Interface* interface) {
475 DCHECK(!already_resolved()); 464 DCHECK(!already_resolved());
476 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are 465 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are
477 // introduces during variable allocation, INTERNAL variables are allocated 466 // introduces during variable allocation, INTERNAL variables are allocated
478 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). 467 // explicitly, and TEMPORARY variables are allocated via NewTemporary().
479 DCHECK(IsDeclaredVariableMode(mode)); 468 DCHECK(IsDeclaredVariableMode(mode));
480 ++num_var_or_const_; 469 ++num_var_or_const_;
481 return variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag, 470 return variables_.Declare(this, name, mode, Variable::NORMAL, init_flag,
482 maybe_assigned_flag, interface); 471 maybe_assigned_flag, interface);
483 } 472 }
484 473
485 474
486 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { 475 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) {
487 DCHECK(is_script_scope()); 476 DCHECK(is_script_scope());
488 return variables_.Declare(this, 477 return variables_.Declare(this,
489 name, 478 name,
490 DYNAMIC_GLOBAL, 479 DYNAMIC_GLOBAL,
491 true,
492 Variable::NORMAL, 480 Variable::NORMAL,
493 kCreatedInitialized); 481 kCreatedInitialized);
494 } 482 }
495 483
496 484
497 void Scope::RemoveUnresolved(VariableProxy* var) { 485 void Scope::RemoveUnresolved(VariableProxy* var) {
498 // Most likely (always?) any variable we want to remove 486 // Most likely (always?) any variable we want to remove
499 // was just added before, so we search backwards. 487 // was just added before, so we search backwards.
500 for (int i = unresolved_.length(); i-- > 0;) { 488 for (int i = unresolved_.length(); i-- > 0;) {
501 if (unresolved_[i] == var) { 489 if (unresolved_[i] == var) {
502 unresolved_.Remove(i); 490 unresolved_.Remove(i);
503 return; 491 return;
504 } 492 }
505 } 493 }
506 } 494 }
507 495
508 496
509 Variable* Scope::NewInternal(const AstRawString* name) { 497 Variable* Scope::NewInternal(const AstRawString* name) {
510 DCHECK(!already_resolved()); 498 DCHECK(!already_resolved());
511 Variable* var = new(zone()) Variable(this, 499 Variable* var = new(zone()) Variable(this,
512 name, 500 name,
513 INTERNAL, 501 INTERNAL,
514 false,
515 Variable::NORMAL, 502 Variable::NORMAL,
516 kCreatedInitialized); 503 kCreatedInitialized);
517 internals_.Add(var, zone()); 504 internals_.Add(var, zone());
518 return var; 505 return var;
519 } 506 }
520 507
521 508
522 Variable* Scope::NewTemporary(const AstRawString* name) { 509 Variable* Scope::NewTemporary(const AstRawString* name) {
523 DCHECK(!already_resolved()); 510 DCHECK(!already_resolved());
524 Variable* var = new(zone()) Variable(this, 511 Variable* var = new(zone()) Variable(this,
525 name, 512 name,
526 TEMPORARY, 513 TEMPORARY,
527 true,
528 Variable::NORMAL, 514 Variable::NORMAL,
529 kCreatedInitialized); 515 kCreatedInitialized);
530 temps_.Add(var, zone()); 516 temps_.Add(var, zone());
531 return var; 517 return var;
532 } 518 }
533 519
534 520
535 void Scope::AddDeclaration(Declaration* declaration) { 521 void Scope::AddDeclaration(Declaration* declaration) {
536 decls_.Add(declaration, zone()); 522 decls_.Add(declaration, zone());
537 } 523 }
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 Indent(n1, "// strict mode scope\n"); 879 Indent(n1, "// strict mode scope\n");
894 } 880 }
895 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); 881 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n");
896 if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n"); 882 if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n");
897 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); 883 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
898 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n"); 884 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n");
899 if (scope_uses_super_property_) 885 if (scope_uses_super_property_)
900 Indent(n1, "// scope uses 'super' property\n"); 886 Indent(n1, "// scope uses 'super' property\n");
901 if (scope_uses_super_constructor_call_) 887 if (scope_uses_super_constructor_call_)
902 Indent(n1, "// scope uses 'super' constructor\n"); 888 Indent(n1, "// scope uses 'super' constructor\n");
903 if (scope_uses_this_) Indent(n1, "// scope uses 'this'\n");
904 if (inner_scope_uses_arguments_) { 889 if (inner_scope_uses_arguments_) {
905 Indent(n1, "// inner scope uses 'arguments'\n"); 890 Indent(n1, "// inner scope uses 'arguments'\n");
906 } 891 }
907 if (inner_scope_uses_super_property_) 892 if (inner_scope_uses_super_property_)
908 Indent(n1, "// inner scope uses 'super' property\n"); 893 Indent(n1, "// inner scope uses 'super' property\n");
909 if (inner_scope_uses_super_constructor_call_) { 894 if (inner_scope_uses_super_constructor_call_) {
910 Indent(n1, "// inner scope uses 'super' constructor\n"); 895 Indent(n1, "// inner scope uses 'super' constructor\n");
911 } 896 }
912 if (inner_scope_uses_this_) Indent(n1, "// inner scope uses 'this'\n");
913 if (outer_scope_calls_sloppy_eval_) { 897 if (outer_scope_calls_sloppy_eval_) {
914 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); 898 Indent(n1, "// outer scope calls 'eval' in sloppy context\n");
915 } 899 }
916 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); 900 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
917 if (num_stack_slots_ > 0) { Indent(n1, "// "); 901 if (num_stack_slots_ > 0) { Indent(n1, "// ");
918 PrintF("%d stack slots\n", num_stack_slots_); } 902 PrintF("%d stack slots\n", num_stack_slots_); }
919 if (num_heap_slots_ > 0) { Indent(n1, "// "); 903 if (num_heap_slots_ > 0) { Indent(n1, "// ");
920 PrintF("%d heap slots\n", num_heap_slots_); } 904 PrintF("%d heap slots\n", num_heap_slots_); }
921 905
922 // Print locals. 906 // Print locals.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); 952 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone());
969 VariableMap* map = dynamics_->GetMap(mode); 953 VariableMap* map = dynamics_->GetMap(mode);
970 Variable* var = map->Lookup(name); 954 Variable* var = map->Lookup(name);
971 if (var == NULL) { 955 if (var == NULL) {
972 // Declare a new non-local. 956 // Declare a new non-local.
973 InitializationFlag init_flag = (mode == VAR) 957 InitializationFlag init_flag = (mode == VAR)
974 ? kCreatedInitialized : kNeedsInitialization; 958 ? kCreatedInitialized : kNeedsInitialization;
975 var = map->Declare(NULL, 959 var = map->Declare(NULL,
976 name, 960 name,
977 mode, 961 mode,
978 true,
979 Variable::NORMAL, 962 Variable::NORMAL,
980 init_flag); 963 init_flag);
981 // Allocate it by giving it a dynamic lookup. 964 // Allocate it by giving it a dynamic lookup.
982 var->AllocateTo(Variable::LOOKUP, -1); 965 var->AllocateTo(Variable::LOOKUP, -1);
983 } 966 }
984 return var; 967 return var;
985 } 968 }
986 969
987 970
988 Variable* Scope::LookupRecursive(VariableProxy* proxy, 971 Variable* Scope::LookupRecursive(VariableProxy* proxy,
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 inner_scope_uses_arguments_ = true; 1165 inner_scope_uses_arguments_ = true;
1183 } 1166 }
1184 if (inner->scope_uses_super_property_ || 1167 if (inner->scope_uses_super_property_ ||
1185 inner->inner_scope_uses_super_property_) { 1168 inner->inner_scope_uses_super_property_) {
1186 inner_scope_uses_super_property_ = true; 1169 inner_scope_uses_super_property_ = true;
1187 } 1170 }
1188 if (inner->uses_super_constructor_call() || 1171 if (inner->uses_super_constructor_call() ||
1189 inner->inner_scope_uses_super_constructor_call_) { 1172 inner->inner_scope_uses_super_constructor_call_) {
1190 inner_scope_uses_super_constructor_call_ = true; 1173 inner_scope_uses_super_constructor_call_ = true;
1191 } 1174 }
1192 if (inner->scope_uses_this_ || inner->inner_scope_uses_this_) {
1193 inner_scope_uses_this_ = true;
1194 }
1195 } 1175 }
1196 if (inner->force_eager_compilation_) { 1176 if (inner->force_eager_compilation_) {
1197 force_eager_compilation_ = true; 1177 force_eager_compilation_ = true;
1198 } 1178 }
1199 if (asm_module_ && inner->scope_type() == FUNCTION_SCOPE) { 1179 if (asm_module_ && inner->scope_type() == FUNCTION_SCOPE) {
1200 inner->asm_function_ = true; 1180 inner->asm_function_ = true;
1201 } 1181 }
1202 } 1182 }
1203 } 1183 }
1204 1184
1205 1185
1206 bool Scope::MustAllocate(Variable* var) { 1186 bool Scope::MustAllocate(Variable* var) {
1207 // Give var a read/write use if there is a chance it might be accessed 1187 // Give var a read/write use if there is a chance it might be accessed
1208 // via an eval() call. This is only possible if the variable has a 1188 // via an eval() call. This is only possible if the variable has a
1209 // visible name. 1189 // visible name.
1210 if ((var->is_this() || !var->raw_name()->IsEmpty()) && 1190 if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
1211 (var->has_forced_context_allocation() || 1191 (var->has_forced_context_allocation() ||
1212 scope_calls_eval_ || 1192 scope_calls_eval_ ||
1213 inner_scope_calls_eval_ || 1193 inner_scope_calls_eval_ ||
1214 scope_contains_with_ || 1194 scope_contains_with_ ||
1215 is_catch_scope() || 1195 is_catch_scope() ||
1216 is_block_scope() || 1196 is_block_scope() ||
1217 is_module_scope() || 1197 is_module_scope() ||
1218 is_script_scope())) { 1198 is_script_scope())) {
1219 var->set_is_used(); 1199 var->set_is_used();
1220 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); 1200 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned();
1221 } 1201 }
1222 // Global variables do not need to be allocated. 1202 // Global variables do not need to be allocated.
1223 return !var->IsGlobalObjectProperty() && var->is_used(); 1203 return var->is_this() || (var->is_used() && !var->IsGlobalObjectProperty());
1224 } 1204 }
1225 1205
1226 1206
1227 bool Scope::MustAllocateInContext(Variable* var) { 1207 bool Scope::MustAllocateInContext(Variable* var) {
1228 // If var is accessed from an inner scope, or if there is a possibility 1208 // If var is accessed from an inner scope, or if there is a possibility
1229 // that it might be accessed from the current or an inner scope (through 1209 // that it might be accessed from the current or an inner scope (through
1230 // an eval() call or a runtime with lookup), it must be allocated in the 1210 // an eval() call or a runtime with lookup), it must be allocated in the
1231 // context. 1211 // context.
1232 // 1212 //
1233 // Exceptions: If the scope as a whole has forced context allocation, all 1213 // Exceptions: If the scope as a whole has forced context allocation, all
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 // order is relevant! 1284 // order is relevant!
1305 for (int i = params_.length() - 1; i >= 0; --i) { 1285 for (int i = params_.length() - 1; i >= 0; --i) {
1306 Variable* var = params_[i]; 1286 Variable* var = params_[i];
1307 if (var == rest_parameter_) continue; 1287 if (var == rest_parameter_) continue;
1308 1288
1309 DCHECK(var->scope() == this); 1289 DCHECK(var->scope() == this);
1310 if (uses_sloppy_arguments || has_forced_context_allocation()) { 1290 if (uses_sloppy_arguments || has_forced_context_allocation()) {
1311 // Force context allocation of the parameter. 1291 // Force context allocation of the parameter.
1312 var->ForceContextAllocation(); 1292 var->ForceContextAllocation();
1313 } 1293 }
1294 AllocateParameter(var, i);
1295 }
1296 }
1314 1297
1315 if (MustAllocate(var)) { 1298
1316 if (MustAllocateInContext(var)) { 1299 void Scope::AllocateReceiver() {
1317 DCHECK(var->IsUnallocated() || var->IsContextSlot()); 1300 DCHECK_EQ(receiver()->scope(), this);
1318 if (var->IsUnallocated()) { 1301
1319 AllocateHeapSlot(var); 1302 if (has_forced_context_allocation()) {
1320 } 1303 // Force context allocation of the receiver.
1321 } else { 1304 receiver()->ForceContextAllocation();
1322 DCHECK(var->IsUnallocated() || var->IsParameter()); 1305 }
1323 if (var->IsUnallocated()) { 1306 AllocateParameter(receiver(), -1);
1324 var->AllocateTo(Variable::PARAMETER, i); 1307 }
1325 } 1308
1309
1310 void Scope::AllocateParameter(Variable* var, int index) {
1311 if (MustAllocate(var)) {
1312 if (MustAllocateInContext(var)) {
1313 DCHECK(var->IsUnallocated() || var->IsContextSlot());
1314 if (var->IsUnallocated()) {
1315 AllocateHeapSlot(var);
1316 }
1317 } else {
1318 DCHECK(var->IsUnallocated() || var->IsParameter());
1319 if (var->IsUnallocated()) {
1320 var->AllocateTo(Variable::PARAMETER, index);
1326 } 1321 }
1327 } 1322 }
1328 } 1323 }
1329 } 1324 }
1330 1325
1331 1326
1332 void Scope::AllocateNonParameterLocal(Variable* var) { 1327 void Scope::AllocateNonParameterLocal(Variable* var) {
1333 DCHECK(var->scope() == this); 1328 DCHECK(var->scope() == this);
1334 DCHECK(!var->IsVariable(isolate_->factory()->dot_result_string()) || 1329 DCHECK(!var->IsVariable(isolate_->factory()->dot_result_string()) ||
1335 !var->IsStackLocal()); 1330 !var->IsStackLocal());
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 1383
1389 // If scope is already resolved, we still need to allocate 1384 // If scope is already resolved, we still need to allocate
1390 // variables in inner scopes which might not had been resolved yet. 1385 // variables in inner scopes which might not had been resolved yet.
1391 if (already_resolved()) return; 1386 if (already_resolved()) return;
1392 // The number of slots required for variables. 1387 // The number of slots required for variables.
1393 num_stack_slots_ = 0; 1388 num_stack_slots_ = 0;
1394 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 1389 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
1395 1390
1396 // Allocate variables for this scope. 1391 // Allocate variables for this scope.
1397 // Parameters must be allocated first, if any. 1392 // Parameters must be allocated first, if any.
1393 if (has_this_declaration()) AllocateReceiver();
1398 if (is_function_scope()) AllocateParameterLocals(); 1394 if (is_function_scope()) AllocateParameterLocals();
1399 AllocateNonParameterLocals(); 1395 AllocateNonParameterLocals();
1400 1396
1401 // Force allocation of a context for this scope if necessary. For a 'with' 1397 // Force allocation of a context for this scope if necessary. For a 'with'
1402 // scope and for a function scope that makes an 'eval' call we need a context, 1398 // scope and for a function scope that makes an 'eval' call we need a context,
1403 // even if no local variables were statically allocated in the scope. 1399 // even if no local variables were statically allocated in the scope.
1404 // Likewise for modules. 1400 // Likewise for modules.
1405 bool must_have_context = is_with_scope() || is_module_scope() || 1401 bool must_have_context = is_with_scope() || is_module_scope() ||
1406 (is_function_scope() && calls_eval()); 1402 (is_function_scope() && calls_eval());
1407 1403
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 } 1435 }
1440 1436
1441 1437
1442 int Scope::ContextLocalCount() const { 1438 int Scope::ContextLocalCount() const {
1443 if (num_heap_slots() == 0) return 0; 1439 if (num_heap_slots() == 0) return 0;
1444 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1440 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1445 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); 1441 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
1446 } 1442 }
1447 1443
1448 } } // namespace v8::internal 1444 } } // namespace v8::internal
OLDNEW
« src/scopes.h ('K') | « src/scopes.h ('k') | src/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698