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

Side by Side Diff: src/scopes.cc

Issue 7860035: Merge bleeding edge up to 9192 into the GC branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Created 9 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « src/scopes.h ('k') | src/spaces.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "scopes.h" 30 #include "scopes.h"
31 31
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "compiler.h" 33 #include "compiler.h"
34 #include "prettyprinter.h"
35 #include "scopeinfo.h" 34 #include "scopeinfo.h"
36 35
37 #include "allocation-inl.h" 36 #include "allocation-inl.h"
38 37
39 namespace v8 { 38 namespace v8 {
40 namespace internal { 39 namespace internal {
41 40
42 // ---------------------------------------------------------------------------- 41 // ----------------------------------------------------------------------------
43 // A Zone allocator for use with LocalsMap. 42 // A Zone allocator for use with LocalsMap.
44 43
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 } else { 306 } else {
308 ASSERT(is_function_scope() || 307 ASSERT(is_function_scope() ||
309 is_global_scope() || 308 is_global_scope() ||
310 is_eval_scope()); 309 is_eval_scope());
311 Variable* var = 310 Variable* var =
312 variables_.Declare(this, 311 variables_.Declare(this,
313 isolate_->factory()->this_symbol(), 312 isolate_->factory()->this_symbol(),
314 Variable::VAR, 313 Variable::VAR,
315 false, 314 false,
316 Variable::THIS); 315 Variable::THIS);
317 var->set_rewrite(NewSlot(var, Slot::PARAMETER, -1)); 316 var->AllocateTo(Variable::PARAMETER, -1);
318 receiver_ = var; 317 receiver_ = var;
319 } 318 }
320 319
321 if (is_function_scope()) { 320 if (is_function_scope()) {
322 // Declare 'arguments' variable which exists in all functions. 321 // Declare 'arguments' variable which exists in all functions.
323 // 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
324 // allocated during variable allocation. 323 // allocated during variable allocation.
325 variables_.Declare(this, 324 variables_.Declare(this,
326 isolate_->factory()->arguments_symbol(), 325 isolate_->factory()->arguments_symbol(),
327 Variable::VAR, 326 Variable::VAR,
328 true, 327 true,
329 Variable::ARGUMENTS); 328 Variable::ARGUMENTS);
330 } 329 }
331 } 330 }
332 331
333 332
333 Scope* Scope::FinalizeBlockScope() {
334 ASSERT(is_block_scope());
335 ASSERT(temps_.is_empty());
336 ASSERT(params_.is_empty());
337
338 if (num_var_or_const() > 0) return this;
339
340 // Remove this scope from outer scope.
341 for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) {
342 if (outer_scope_->inner_scopes_[i] == this) {
343 outer_scope_->inner_scopes_.Remove(i);
344 break;
345 }
346 }
347
348 // Reparent inner scopes.
349 for (int i = 0; i < inner_scopes_.length(); i++) {
350 outer_scope()->AddInnerScope(inner_scopes_[i]);
351 }
352
353 // Move unresolved variables
354 for (int i = 0; i < unresolved_.length(); i++) {
355 outer_scope()->unresolved_.Add(unresolved_[i]);
356 }
357
358 return NULL;
359 }
360
361
334 Variable* Scope::LocalLookup(Handle<String> name) { 362 Variable* Scope::LocalLookup(Handle<String> name) {
335 Variable* result = variables_.Lookup(name); 363 Variable* result = variables_.Lookup(name);
336 if (result != NULL || scope_info_.is_null()) { 364 if (result != NULL || scope_info_.is_null()) {
337 return result; 365 return result;
338 } 366 }
339 // If we have a serialized scope info, we might find the variable there. 367 // If we have a serialized scope info, we might find the variable there.
340 // 368 //
341 // We should never lookup 'arguments' in this scope as it is implicitly 369 // We should never lookup 'arguments' in this scope as it is implicitly
342 // present in every scope. 370 // present in every scope.
343 ASSERT(*name != *isolate_->factory()->arguments_symbol()); 371 ASSERT(*name != *isolate_->factory()->arguments_symbol());
344 // There should be no local slot with the given name. 372 // There should be no local slot with the given name.
345 ASSERT(scope_info_->StackSlotIndex(*name) < 0); 373 ASSERT(scope_info_->StackSlotIndex(*name) < 0);
346 374
347 // Check context slot lookup. 375 // Check context slot lookup.
348 Variable::Mode mode; 376 Variable::Mode mode;
349 int index = scope_info_->ContextSlotIndex(*name, &mode); 377 int index = scope_info_->ContextSlotIndex(*name, &mode);
350 if (index < 0) { 378 if (index < 0) {
351 // Check parameters. 379 // Check parameters.
352 mode = Variable::VAR; 380 mode = Variable::VAR;
353 index = scope_info_->ParameterIndex(*name); 381 index = scope_info_->ParameterIndex(*name);
354 if (index < 0) { 382 if (index < 0) {
355 // Check the function name. 383 // Check the function name.
356 index = scope_info_->FunctionContextSlotIndex(*name); 384 index = scope_info_->FunctionContextSlotIndex(*name);
357 if (index < 0) return NULL; 385 if (index < 0) return NULL;
358 } 386 }
359 } 387 }
360 388
361 Variable* var = 389 Variable* var =
362 variables_.Declare(this, name, mode, true, Variable::NORMAL); 390 variables_.Declare(this, name, mode, true, Variable::NORMAL);
363 var->set_rewrite(NewSlot(var, Slot::CONTEXT, index)); 391 var->AllocateTo(Variable::CONTEXT, index);
364 return var; 392 return var;
365 } 393 }
366 394
367 395
368 Variable* Scope::Lookup(Handle<String> name) { 396 Variable* Scope::Lookup(Handle<String> name) {
369 for (Scope* scope = this; 397 for (Scope* scope = this;
370 scope != NULL; 398 scope != NULL;
371 scope = scope->outer_scope()) { 399 scope = scope->outer_scope()) {
372 Variable* var = scope->LocalLookup(name); 400 Variable* var = scope->LocalLookup(name);
373 if (var != NULL) return var; 401 if (var != NULL) return var;
374 } 402 }
375 return NULL; 403 return NULL;
376 } 404 }
377 405
378 406
379 Variable* Scope::DeclareFunctionVar(Handle<String> name) { 407 Variable* Scope::DeclareFunctionVar(Handle<String> name) {
380 ASSERT(is_function_scope() && function_ == NULL); 408 ASSERT(is_function_scope() && function_ == NULL);
381 function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL); 409 Variable* function_var =
382 return function_; 410 new Variable(this, name, Variable::CONST, true, Variable::NORMAL);
411 function_ = new(isolate_->zone()) VariableProxy(isolate_, function_var);
412 return function_var;
383 } 413 }
384 414
385 415
386 void Scope::DeclareParameter(Handle<String> name) { 416 void Scope::DeclareParameter(Handle<String> name, Variable::Mode mode) {
387 ASSERT(!already_resolved()); 417 ASSERT(!already_resolved());
388 ASSERT(is_function_scope()); 418 ASSERT(is_function_scope());
389 Variable* var = 419 Variable* var =
390 variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL); 420 variables_.Declare(this, name, mode, true, Variable::NORMAL);
391 params_.Add(var); 421 params_.Add(var);
392 } 422 }
393 423
394 424
395 Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) { 425 Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) {
396 ASSERT(!already_resolved()); 426 ASSERT(!already_resolved());
397 // This function handles VAR and CONST modes. DYNAMIC variables are 427 // This function handles VAR and CONST modes. DYNAMIC variables are
398 // introduces during variable allocation, INTERNAL variables are allocated 428 // introduces during variable allocation, INTERNAL variables are allocated
399 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). 429 // explicitly, and TEMPORARY variables are allocated via NewTemporary().
400 ASSERT(mode == Variable::VAR || 430 ASSERT(mode == Variable::VAR ||
401 mode == Variable::CONST || 431 mode == Variable::CONST ||
402 mode == Variable::LET); 432 mode == Variable::LET);
403 ++num_var_or_const_; 433 ++num_var_or_const_;
404 return variables_.Declare(this, name, mode, true, Variable::NORMAL); 434 return variables_.Declare(this, name, mode, true, Variable::NORMAL);
405 } 435 }
406 436
407 437
408 Variable* Scope::DeclareGlobal(Handle<String> name) { 438 Variable* Scope::DeclareGlobal(Handle<String> name) {
409 ASSERT(is_global_scope()); 439 ASSERT(is_global_scope());
410 return variables_.Declare(this, name, Variable::DYNAMIC_GLOBAL, true, 440 return variables_.Declare(this, name, Variable::DYNAMIC_GLOBAL,
441 true,
411 Variable::NORMAL); 442 Variable::NORMAL);
412 } 443 }
413 444
414 445
415 VariableProxy* Scope::NewUnresolved(Handle<String> name, 446 VariableProxy* Scope::NewUnresolved(Handle<String> name,
416 bool inside_with, 447 bool inside_with,
417 int position) { 448 int position) {
418 // Note that we must not share the unresolved variables with 449 // Note that we must not share the unresolved variables with
419 // the same name because they may be removed selectively via 450 // the same name because they may be removed selectively via
420 // RemoveUnresolved(). 451 // RemoveUnresolved().
(...skipping 12 matching lines...) Expand all
433 if (unresolved_[i] == var) { 464 if (unresolved_[i] == var) {
434 unresolved_.Remove(i); 465 unresolved_.Remove(i);
435 return; 466 return;
436 } 467 }
437 } 468 }
438 } 469 }
439 470
440 471
441 Variable* Scope::NewTemporary(Handle<String> name) { 472 Variable* Scope::NewTemporary(Handle<String> name) {
442 ASSERT(!already_resolved()); 473 ASSERT(!already_resolved());
443 Variable* var = 474 Variable* var = new Variable(this,
444 new Variable(this, name, Variable::TEMPORARY, true, Variable::NORMAL); 475 name,
476 Variable::TEMPORARY,
477 true,
478 Variable::NORMAL);
445 temps_.Add(var); 479 temps_.Add(var);
446 return var; 480 return var;
447 } 481 }
448 482
449 483
450 void Scope::AddDeclaration(Declaration* declaration) { 484 void Scope::AddDeclaration(Declaration* declaration) {
451 decls_.Add(declaration); 485 decls_.Add(declaration);
452 } 486 }
453 487
454 488
455 void Scope::SetIllegalRedeclaration(Expression* expression) { 489 void Scope::SetIllegalRedeclaration(Expression* expression) {
456 // Record only the first illegal redeclaration. 490 // Record only the first illegal redeclaration.
457 if (!HasIllegalRedeclaration()) { 491 if (!HasIllegalRedeclaration()) {
458 illegal_redecl_ = expression; 492 illegal_redecl_ = expression;
459 } 493 }
460 ASSERT(HasIllegalRedeclaration()); 494 ASSERT(HasIllegalRedeclaration());
461 } 495 }
462 496
463 497
464 void Scope::VisitIllegalRedeclaration(AstVisitor* visitor) { 498 void Scope::VisitIllegalRedeclaration(AstVisitor* visitor) {
465 ASSERT(HasIllegalRedeclaration()); 499 ASSERT(HasIllegalRedeclaration());
466 illegal_redecl_->Accept(visitor); 500 illegal_redecl_->Accept(visitor);
467 } 501 }
468 502
469 503
504 Declaration* Scope::CheckConflictingVarDeclarations() {
505 int length = decls_.length();
506 for (int i = 0; i < length; i++) {
507 Declaration* decl = decls_[i];
508 if (decl->mode() != Variable::VAR) continue;
509 Handle<String> name = decl->proxy()->name();
510 bool cond = true;
511 for (Scope* scope = decl->scope(); cond ; scope = scope->outer_scope_) {
512 // There is a conflict if there exists a non-VAR binding.
513 Variable* other_var = scope->variables_.Lookup(name);
514 if (other_var != NULL && other_var->mode() != Variable::VAR) {
515 return decl;
516 }
517
518 // Include declaration scope in the iteration but stop after.
519 if (!scope->is_block_scope() && !scope->is_catch_scope()) cond = false;
520 }
521 }
522 return NULL;
523 }
524
525
470 template<class Allocator> 526 template<class Allocator>
471 void Scope::CollectUsedVariables(List<Variable*, Allocator>* locals) { 527 void Scope::CollectUsedVariables(List<Variable*, Allocator>* locals) {
472 // Collect variables in this scope. 528 // Collect variables in this scope.
473 // Note that the function_ variable - if present - is not 529 // Note that the function_ variable - if present - is not
474 // collected here but handled separately in ScopeInfo 530 // collected here but handled separately in ScopeInfo
475 // which is the current user of this function). 531 // which is the current user of this function).
476 for (int i = 0; i < temps_.length(); i++) { 532 for (int i = 0; i < temps_.length(); i++) {
477 Variable* var = temps_[i]; 533 Variable* var = temps_[i];
478 if (var->is_used()) { 534 if (var->is_used()) {
479 locals->Add(var); 535 locals->Add(var);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 PrintF("%*s%s", n, "", str); 661 PrintF("%*s%s", n, "", str);
606 } 662 }
607 663
608 664
609 static void PrintName(Handle<String> name) { 665 static void PrintName(Handle<String> name) {
610 SmartPointer<char> s = name->ToCString(DISALLOW_NULLS); 666 SmartPointer<char> s = name->ToCString(DISALLOW_NULLS);
611 PrintF("%s", *s); 667 PrintF("%s", *s);
612 } 668 }
613 669
614 670
615 static void PrintVar(PrettyPrinter* printer, int indent, Variable* var) { 671 static void PrintLocation(Variable* var) {
616 if (var->is_used() || var->rewrite() != NULL) { 672 switch (var->location()) {
673 case Variable::UNALLOCATED:
674 break;
675 case Variable::PARAMETER:
676 PrintF("parameter[%d]", var->index());
677 break;
678 case Variable::LOCAL:
679 PrintF("local[%d]", var->index());
680 break;
681 case Variable::CONTEXT:
682 PrintF("context[%d]", var->index());
683 break;
684 case Variable::LOOKUP:
685 PrintF("lookup");
686 break;
687 }
688 }
689
690
691 static void PrintVar(int indent, Variable* var) {
692 if (var->is_used() || !var->IsUnallocated()) {
617 Indent(indent, Variable::Mode2String(var->mode())); 693 Indent(indent, Variable::Mode2String(var->mode()));
618 PrintF(" "); 694 PrintF(" ");
619 PrintName(var->name()); 695 PrintName(var->name());
620 PrintF("; // "); 696 PrintF("; // ");
621 if (var->rewrite() != NULL) { 697 PrintLocation(var);
622 PrintF("%s, ", printer->Print(var->rewrite()));
623 if (var->is_accessed_from_inner_function_scope()) PrintF(", ");
624 }
625 if (var->is_accessed_from_inner_function_scope()) { 698 if (var->is_accessed_from_inner_function_scope()) {
699 if (!var->IsUnallocated()) PrintF(", ");
626 PrintF("inner scope access"); 700 PrintF("inner scope access");
627 } 701 }
628 PrintF("\n"); 702 PrintF("\n");
629 } 703 }
630 } 704 }
631 705
632 706
633 static void PrintMap(PrettyPrinter* printer, int indent, VariableMap* map) { 707 static void PrintMap(int indent, VariableMap* map) {
634 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { 708 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
635 Variable* var = reinterpret_cast<Variable*>(p->value); 709 Variable* var = reinterpret_cast<Variable*>(p->value);
636 PrintVar(printer, indent, var); 710 PrintVar(indent, var);
637 } 711 }
638 } 712 }
639 713
640 714
641 void Scope::Print(int n) { 715 void Scope::Print(int n) {
642 int n0 = (n > 0 ? n : 0); 716 int n0 = (n > 0 ? n : 0);
643 int n1 = n0 + 2; // indentation 717 int n1 = n0 + 2; // indentation
644 718
645 // Print header. 719 // Print header.
646 Indent(n0, Header(type_)); 720 Indent(n0, Header(type_));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); 757 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
684 if (outer_scope_is_eval_scope_) { 758 if (outer_scope_is_eval_scope_) {
685 Indent(n1, "// outer scope is 'eval' scope\n"); 759 Indent(n1, "// outer scope is 'eval' scope\n");
686 } 760 }
687 if (num_stack_slots_ > 0) { Indent(n1, "// "); 761 if (num_stack_slots_ > 0) { Indent(n1, "// ");
688 PrintF("%d stack slots\n", num_stack_slots_); } 762 PrintF("%d stack slots\n", num_stack_slots_); }
689 if (num_heap_slots_ > 0) { Indent(n1, "// "); 763 if (num_heap_slots_ > 0) { Indent(n1, "// ");
690 PrintF("%d heap slots\n", num_heap_slots_); } 764 PrintF("%d heap slots\n", num_heap_slots_); }
691 765
692 // Print locals. 766 // Print locals.
693 PrettyPrinter printer;
694 Indent(n1, "// function var\n"); 767 Indent(n1, "// function var\n");
695 if (function_ != NULL) { 768 if (function_ != NULL) {
696 PrintVar(&printer, n1, function_); 769 PrintVar(n1, function_->var());
697 } 770 }
698 771
699 Indent(n1, "// temporary vars\n"); 772 Indent(n1, "// temporary vars\n");
700 for (int i = 0; i < temps_.length(); i++) { 773 for (int i = 0; i < temps_.length(); i++) {
701 PrintVar(&printer, n1, temps_[i]); 774 PrintVar(n1, temps_[i]);
702 } 775 }
703 776
704 Indent(n1, "// local vars\n"); 777 Indent(n1, "// local vars\n");
705 PrintMap(&printer, n1, &variables_); 778 PrintMap(n1, &variables_);
706 779
707 Indent(n1, "// dynamic vars\n"); 780 Indent(n1, "// dynamic vars\n");
708 if (dynamics_ != NULL) { 781 if (dynamics_ != NULL) {
709 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC)); 782 PrintMap(n1, dynamics_->GetMap(Variable::DYNAMIC));
710 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC_LOCAL)); 783 PrintMap(n1, dynamics_->GetMap(Variable::DYNAMIC_LOCAL));
711 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC_GLOBAL)); 784 PrintMap(n1, dynamics_->GetMap(Variable::DYNAMIC_GLOBAL));
712 } 785 }
713 786
714 // Print inner scopes (disable by providing negative n). 787 // Print inner scopes (disable by providing negative n).
715 if (n >= 0) { 788 if (n >= 0) {
716 for (int i = 0; i < inner_scopes_.length(); i++) { 789 for (int i = 0; i < inner_scopes_.length(); i++) {
717 PrintF("\n"); 790 PrintF("\n");
718 inner_scopes_[i]->Print(n1); 791 inner_scopes_[i]->Print(n1);
719 } 792 }
720 } 793 }
721 794
722 Indent(n0, "}\n"); 795 Indent(n0, "}\n");
723 } 796 }
724 #endif // DEBUG 797 #endif // DEBUG
725 798
726 799
727 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { 800 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
728 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); 801 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart();
729 VariableMap* map = dynamics_->GetMap(mode); 802 VariableMap* map = dynamics_->GetMap(mode);
730 Variable* var = map->Lookup(name); 803 Variable* var = map->Lookup(name);
731 if (var == NULL) { 804 if (var == NULL) {
732 // Declare a new non-local. 805 // Declare a new non-local.
733 var = map->Declare(NULL, name, mode, true, Variable::NORMAL); 806 var = map->Declare(NULL, name, mode, true, Variable::NORMAL);
734 // Allocate it by giving it a dynamic lookup. 807 // Allocate it by giving it a dynamic lookup.
735 var->set_rewrite(NewSlot(var, Slot::LOOKUP, -1)); 808 var->AllocateTo(Variable::LOOKUP, -1);
736 } 809 }
737 return var; 810 return var;
738 } 811 }
739 812
740 813
741 // Lookup a variable starting with this scope. The result is either 814 // Lookup a variable starting with this scope. The result is either
742 // the statically resolved variable belonging to an outer scope, or 815 // the statically resolved variable belonging to an outer scope, or
743 // NULL. It may be NULL because a) we couldn't find a variable, or b) 816 // NULL. It may be NULL because a) we couldn't find a variable, or b)
744 // because the variable is just a guess (and may be shadowed by 817 // because the variable is just a guess (and may be shadowed by
745 // another variable that is introduced dynamically via an 'eval' call 818 // another variable that is introduced dynamically via an 'eval' call
(...skipping 21 matching lines...) Expand all
767 } else { 840 } else {
768 // We did not find a variable locally. Check against the function variable, 841 // We did not find a variable locally. Check against the function variable,
769 // if any. We can do this for all scopes, since the function variable is 842 // if any. We can do this for all scopes, since the function variable is
770 // only present - if at all - for function scopes. 843 // only present - if at all - for function scopes.
771 // 844 //
772 // This lookup corresponds to a lookup in the "intermediate" scope sitting 845 // This lookup corresponds to a lookup in the "intermediate" scope sitting
773 // between this scope and the outer scope. (ECMA-262, 3rd., requires that 846 // between this scope and the outer scope. (ECMA-262, 3rd., requires that
774 // the name of named function literal is kept in an intermediate scope 847 // the name of named function literal is kept in an intermediate scope
775 // in between this scope and the next outer scope.) 848 // in between this scope and the next outer scope.)
776 if (function_ != NULL && function_->name().is_identical_to(name)) { 849 if (function_ != NULL && function_->name().is_identical_to(name)) {
777 var = function_; 850 var = function_->var();
778 851
779 } else if (outer_scope_ != NULL) { 852 } else if (outer_scope_ != NULL) {
780 var = outer_scope_->LookupRecursive( 853 var = outer_scope_->LookupRecursive(
781 name, 854 name,
782 is_function_scope() || from_inner_function, 855 is_function_scope() || from_inner_function,
783 invalidated_local); 856 invalidated_local);
784 // We may have found a variable in an outer scope. However, if 857 // We may have found a variable in an outer scope. However, if
785 // the current scope is inside a 'with', the actual variable may 858 // the current scope is inside a 'with', the actual variable may
786 // be a property introduced via the 'with' statement. Then, the 859 // be a property introduced via the 'with' statement. Then, the
787 // variable we may have found is just a guess. 860 // variable we may have found is just a guess.
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 if (params_[i]->name().is_identical_to( 1058 if (params_[i]->name().is_identical_to(
986 isolate_->factory()->arguments_symbol())) { 1059 isolate_->factory()->arguments_symbol())) {
987 return true; 1060 return true;
988 } 1061 }
989 } 1062 }
990 return false; 1063 return false;
991 } 1064 }
992 1065
993 1066
994 void Scope::AllocateStackSlot(Variable* var) { 1067 void Scope::AllocateStackSlot(Variable* var) {
995 var->set_rewrite(NewSlot(var, Slot::LOCAL, num_stack_slots_++)); 1068 var->AllocateTo(Variable::LOCAL, num_stack_slots_++);
996 } 1069 }
997 1070
998 1071
999 void Scope::AllocateHeapSlot(Variable* var) { 1072 void Scope::AllocateHeapSlot(Variable* var) {
1000 var->set_rewrite(NewSlot(var, Slot::CONTEXT, num_heap_slots_++)); 1073 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++);
1001 } 1074 }
1002 1075
1003 1076
1004 void Scope::AllocateParameterLocals() { 1077 void Scope::AllocateParameterLocals() {
1005 ASSERT(is_function_scope()); 1078 ASSERT(is_function_scope());
1006 Variable* arguments = LocalLookup(isolate_->factory()->arguments_symbol()); 1079 Variable* arguments = LocalLookup(isolate_->factory()->arguments_symbol());
1007 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly 1080 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly
1008 1081
1009 bool uses_nonstrict_arguments = false; 1082 bool uses_nonstrict_arguments = false;
1010 1083
(...skipping 25 matching lines...) Expand all
1036 Variable* var = params_[i]; 1109 Variable* var = params_[i];
1037 ASSERT(var->scope() == this); 1110 ASSERT(var->scope() == this);
1038 if (uses_nonstrict_arguments) { 1111 if (uses_nonstrict_arguments) {
1039 // Give the parameter a use from an inner scope, to force allocation 1112 // Give the parameter a use from an inner scope, to force allocation
1040 // to the context. 1113 // to the context.
1041 var->MarkAsAccessedFromInnerFunctionScope(); 1114 var->MarkAsAccessedFromInnerFunctionScope();
1042 } 1115 }
1043 1116
1044 if (MustAllocate(var)) { 1117 if (MustAllocate(var)) {
1045 if (MustAllocateInContext(var)) { 1118 if (MustAllocateInContext(var)) {
1046 ASSERT(var->rewrite() == NULL || var->IsContextSlot()); 1119 ASSERT(var->IsUnallocated() || var->IsContextSlot());
1047 if (var->rewrite() == NULL) { 1120 if (var->IsUnallocated()) {
1048 AllocateHeapSlot(var); 1121 AllocateHeapSlot(var);
1049 } 1122 }
1050 } else { 1123 } else {
1051 ASSERT(var->rewrite() == NULL || var->IsParameter()); 1124 ASSERT(var->IsUnallocated() || var->IsParameter());
1052 if (var->rewrite() == NULL) { 1125 if (var->IsUnallocated()) {
1053 var->set_rewrite(NewSlot(var, Slot::PARAMETER, i)); 1126 var->AllocateTo(Variable::PARAMETER, i);
1054 } 1127 }
1055 } 1128 }
1056 } 1129 }
1057 } 1130 }
1058 } 1131 }
1059 1132
1060 1133
1061 void Scope::AllocateNonParameterLocal(Variable* var) { 1134 void Scope::AllocateNonParameterLocal(Variable* var) {
1062 ASSERT(var->scope() == this); 1135 ASSERT(var->scope() == this);
1063 ASSERT(var->rewrite() == NULL || 1136 ASSERT(!var->IsVariable(isolate_->factory()->result_symbol()) ||
1064 !var->IsVariable(isolate_->factory()->result_symbol()) || 1137 !var->IsStackLocal());
1065 var->AsSlot() == NULL || 1138 if (var->IsUnallocated() && MustAllocate(var)) {
1066 var->AsSlot()->type() != Slot::LOCAL);
1067 if (var->rewrite() == NULL && MustAllocate(var)) {
1068 if (MustAllocateInContext(var)) { 1139 if (MustAllocateInContext(var)) {
1069 AllocateHeapSlot(var); 1140 AllocateHeapSlot(var);
1070 } else { 1141 } else {
1071 AllocateStackSlot(var); 1142 AllocateStackSlot(var);
1072 } 1143 }
1073 } 1144 }
1074 } 1145 }
1075 1146
1076 1147
1077 void Scope::AllocateNonParameterLocals() { 1148 void Scope::AllocateNonParameterLocals() {
1078 // All variables that have no rewrite yet are non-parameter locals. 1149 // All variables that have no rewrite yet are non-parameter locals.
1079 for (int i = 0; i < temps_.length(); i++) { 1150 for (int i = 0; i < temps_.length(); i++) {
1080 AllocateNonParameterLocal(temps_[i]); 1151 AllocateNonParameterLocal(temps_[i]);
1081 } 1152 }
1082 1153
1083 for (VariableMap::Entry* p = variables_.Start(); 1154 for (VariableMap::Entry* p = variables_.Start();
1084 p != NULL; 1155 p != NULL;
1085 p = variables_.Next(p)) { 1156 p = variables_.Next(p)) {
1086 Variable* var = reinterpret_cast<Variable*>(p->value); 1157 Variable* var = reinterpret_cast<Variable*>(p->value);
1087 AllocateNonParameterLocal(var); 1158 AllocateNonParameterLocal(var);
1088 } 1159 }
1089 1160
1090 // For now, function_ must be allocated at the very end. If it gets 1161 // For now, function_ must be allocated at the very end. If it gets
1091 // allocated in the context, it must be the last slot in the context, 1162 // allocated in the context, it must be the last slot in the context,
1092 // because of the current ScopeInfo implementation (see 1163 // because of the current ScopeInfo implementation (see
1093 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). 1164 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
1094 if (function_ != NULL) { 1165 if (function_ != NULL) {
1095 AllocateNonParameterLocal(function_); 1166 AllocateNonParameterLocal(function_->var());
1096 } 1167 }
1097 } 1168 }
1098 1169
1099 1170
1100 void Scope::AllocateVariablesRecursively() { 1171 void Scope::AllocateVariablesRecursively() {
1101 // Allocate variables for inner scopes. 1172 // Allocate variables for inner scopes.
1102 for (int i = 0; i < inner_scopes_.length(); i++) { 1173 for (int i = 0; i < inner_scopes_.length(); i++) {
1103 inner_scopes_[i]->AllocateVariablesRecursively(); 1174 inner_scopes_[i]->AllocateVariablesRecursively();
1104 } 1175 }
1105 1176
(...skipping 25 matching lines...) Expand all
1131 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 1202 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
1132 !must_have_local_context) { 1203 !must_have_local_context) {
1133 num_heap_slots_ = 0; 1204 num_heap_slots_ = 0;
1134 } 1205 }
1135 1206
1136 // Allocation done. 1207 // Allocation done.
1137 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 1208 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
1138 } 1209 }
1139 1210
1140 } } // namespace v8::internal 1211 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | src/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698