| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 // ---------------------------------------------------------------------------- | 105 // ---------------------------------------------------------------------------- |
| 106 // Implementation of Scope | 106 // Implementation of Scope |
| 107 | 107 |
| 108 | 108 |
| 109 // Dummy constructor | 109 // Dummy constructor |
| 110 Scope::Scope() | 110 Scope::Scope() |
| 111 : inner_scopes_(0), | 111 : inner_scopes_(0), |
| 112 locals_(false), | 112 locals_(false), |
| 113 temps_(0), | 113 temps_(0), |
| 114 params_(0), | 114 params_(0), |
| 115 nonlocals_(0), | 115 dynamics_(false), |
| 116 dynamics_local_(false), |
| 117 dynamics_global_(false), |
| 116 unresolved_(0), | 118 unresolved_(0), |
| 117 decls_(0) { | 119 decls_(0) { |
| 118 } | 120 } |
| 119 | 121 |
| 120 | 122 |
| 121 Scope::Scope(Scope* outer_scope, Type type) | 123 Scope::Scope(Scope* outer_scope, Type type) |
| 122 : outer_scope_(outer_scope), | 124 : outer_scope_(outer_scope), |
| 123 inner_scopes_(4), | 125 inner_scopes_(4), |
| 124 type_(type), | 126 type_(type), |
| 125 scope_name_(Factory::empty_symbol()), | 127 scope_name_(Factory::empty_symbol()), |
| 126 locals_(), | 128 locals_(), |
| 127 temps_(4), | 129 temps_(4), |
| 128 params_(4), | 130 params_(4), |
| 129 nonlocals_(4), | |
| 130 unresolved_(16), | 131 unresolved_(16), |
| 131 decls_(4), | 132 decls_(4), |
| 132 receiver_(NULL), | 133 receiver_(NULL), |
| 133 function_(NULL), | 134 function_(NULL), |
| 134 arguments_(NULL), | 135 arguments_(NULL), |
| 135 arguments_shadow_(NULL), | 136 arguments_shadow_(NULL), |
| 136 illegal_redecl_(NULL), | 137 illegal_redecl_(NULL), |
| 137 scope_inside_with_(false), | 138 scope_inside_with_(false), |
| 138 scope_contains_with_(false), | 139 scope_contains_with_(false), |
| 139 scope_calls_eval_(false), | 140 scope_calls_eval_(false), |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 if (var->is_accessed_from_inner_scope()) PrintF("inner scope access, "); | 399 if (var->is_accessed_from_inner_scope()) PrintF("inner scope access, "); |
| 399 PrintF("var "); | 400 PrintF("var "); |
| 400 var->var_uses()->Print(); | 401 var->var_uses()->Print(); |
| 401 PrintF(", obj "); | 402 PrintF(", obj "); |
| 402 var->obj_uses()->Print(); | 403 var->obj_uses()->Print(); |
| 403 PrintF("\n"); | 404 PrintF("\n"); |
| 404 } | 405 } |
| 405 } | 406 } |
| 406 | 407 |
| 407 | 408 |
| 409 static void PrintMap(PrettyPrinter* printer, int indent, LocalsMap* map) { |
| 410 for (LocalsMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { |
| 411 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 412 PrintVar(printer, indent, var); |
| 413 } |
| 414 } |
| 415 |
| 416 |
| 408 void Scope::Print(int n) { | 417 void Scope::Print(int n) { |
| 409 int n0 = (n > 0 ? n : 0); | 418 int n0 = (n > 0 ? n : 0); |
| 410 int n1 = n0 + 2; // indentation | 419 int n1 = n0 + 2; // indentation |
| 411 | 420 |
| 412 // Print header. | 421 // Print header. |
| 413 Indent(n0, Header(type_)); | 422 Indent(n0, Header(type_)); |
| 414 if (scope_name_->length() > 0) { | 423 if (scope_name_->length() > 0) { |
| 415 PrintF(" "); | 424 PrintF(" "); |
| 416 PrintName(scope_name_); | 425 PrintName(scope_name_); |
| 417 } | 426 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 if (function_ != NULL) { | 467 if (function_ != NULL) { |
| 459 PrintVar(&printer, n1, function_); | 468 PrintVar(&printer, n1, function_); |
| 460 } | 469 } |
| 461 | 470 |
| 462 Indent(n1, "// temporary vars\n"); | 471 Indent(n1, "// temporary vars\n"); |
| 463 for (int i = 0; i < temps_.length(); i++) { | 472 for (int i = 0; i < temps_.length(); i++) { |
| 464 PrintVar(&printer, n1, temps_[i]); | 473 PrintVar(&printer, n1, temps_[i]); |
| 465 } | 474 } |
| 466 | 475 |
| 467 Indent(n1, "// local vars\n"); | 476 Indent(n1, "// local vars\n"); |
| 468 for (LocalsMap::Entry* p = locals_.Start(); p != NULL; p = locals_.Next(p)) { | 477 PrintMap(&printer, n1, &locals_); |
| 469 Variable* var = reinterpret_cast<Variable*>(p->value); | |
| 470 PrintVar(&printer, n1, var); | |
| 471 } | |
| 472 | 478 |
| 473 Indent(n1, "// nonlocal vars\n"); | 479 Indent(n1, "// dynamic vars\n"); |
| 474 for (int i = 0; i < nonlocals_.length(); i++) | 480 PrintMap(&printer, n1, &dynamics_); |
| 475 PrintVar(&printer, n1, nonlocals_[i]); | 481 PrintMap(&printer, n1, &dynamics_local_); |
| 482 PrintMap(&printer, n1, &dynamics_global_); |
| 476 | 483 |
| 477 // Print inner scopes (disable by providing negative n). | 484 // Print inner scopes (disable by providing negative n). |
| 478 if (n >= 0) { | 485 if (n >= 0) { |
| 479 for (int i = 0; i < inner_scopes_.length(); i++) { | 486 for (int i = 0; i < inner_scopes_.length(); i++) { |
| 480 PrintF("\n"); | 487 PrintF("\n"); |
| 481 inner_scopes_[i]->Print(n1); | 488 inner_scopes_[i]->Print(n1); |
| 482 } | 489 } |
| 483 } | 490 } |
| 484 | 491 |
| 485 Indent(n0, "}\n"); | 492 Indent(n0, "}\n"); |
| 486 } | 493 } |
| 487 #endif // DEBUG | 494 #endif // DEBUG |
| 488 | 495 |
| 489 | 496 |
| 490 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { | 497 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { |
| 491 // Space optimization: reuse existing non-local with the same name | 498 // Space optimization: reuse existing non-local with the same name |
| 492 // and mode. | 499 // and mode. |
| 493 for (int i = 0; i < nonlocals_.length(); i++) { | 500 LocalsMap* map = NULL; |
| 494 Variable* var = nonlocals_[i]; | 501 switch (mode) { |
| 495 if (var->name().is_identical_to(name) && var->mode() == mode) { | 502 case Variable::DYNAMIC: |
| 496 return var; | 503 map = &dynamics_; |
| 497 } | 504 break; |
| 505 case Variable::DYNAMIC_LOCAL: |
| 506 map = &dynamics_local_; |
| 507 break; |
| 508 case Variable::DYNAMIC_GLOBAL: |
| 509 map = &dynamics_global_; |
| 510 break; |
| 511 default: |
| 512 UNREACHABLE(); |
| 513 break; |
| 498 } | 514 } |
| 499 | 515 Variable* var = map->Lookup(name); |
| 500 // Otherwise create a new non-local and add it to the list. | 516 if (var == NULL) { |
| 501 Variable* var = new Variable(NULL, name, mode, true, false); | 517 // Declare a new non-local. |
| 502 nonlocals_.Add(var); | 518 var = map->Declare(NULL, name, mode, true, false); |
| 503 | 519 // Allocate it by giving it a dynamic lookup. |
| 504 // Allocate it by giving it a dynamic lookup. | 520 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1); |
| 505 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1); | 521 } |
| 506 | |
| 507 return var; | 522 return var; |
| 508 } | 523 } |
| 509 | 524 |
| 510 | 525 |
| 511 // Lookup a variable starting with this scope. The result is either | 526 // Lookup a variable starting with this scope. The result is either |
| 512 // the statically resolved (local!) variable belonging to an outer scope, | 527 // the statically resolved (local!) variable belonging to an outer scope, |
| 513 // or NULL. It may be NULL because a) we couldn't find a variable, or b) | 528 // or NULL. It may be NULL because a) we couldn't find a variable, or b) |
| 514 // because the variable is just a guess (and may be shadowed by another | 529 // because the variable is just a guess (and may be shadowed by another |
| 515 // variable that is introduced dynamically via an 'eval' call or a 'with' | 530 // variable that is introduced dynamically via an 'eval' call or a 'with' |
| 516 // statement). | 531 // statement). |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 // a local or outer eval() call, or an outer 'with' statement), | 625 // a local or outer eval() call, or an outer 'with' statement), |
| 611 // or we don't know about the outer scope (because we are | 626 // or we don't know about the outer scope (because we are |
| 612 // in an eval scope). | 627 // in an eval scope). |
| 613 if (is_global_scope() || | 628 if (is_global_scope() || |
| 614 !(scope_inside_with_ || outer_scope_is_eval_scope_ || | 629 !(scope_inside_with_ || outer_scope_is_eval_scope_ || |
| 615 scope_calls_eval_ || outer_scope_calls_eval_)) { | 630 scope_calls_eval_ || outer_scope_calls_eval_)) { |
| 616 // We must have a global variable. | 631 // We must have a global variable. |
| 617 ASSERT(global_scope != NULL); | 632 ASSERT(global_scope != NULL); |
| 618 var = new Variable(global_scope, proxy->name(), | 633 var = new Variable(global_scope, proxy->name(), |
| 619 Variable::DYNAMIC, true, false); | 634 Variable::DYNAMIC, true, false); |
| 620 // Ideally we simply rewrite these variables into property | |
| 621 // accesses. Unfortunately, we cannot do this here at the | |
| 622 // moment because then we can't differentiate between | |
| 623 // global variable ('x') and global property ('this.x') access. | |
| 624 // If 'x' doesn't exist, the former leads to an error, while the | |
| 625 // latter returns undefined. Sigh... | |
| 626 // var->rewrite_ = new Property(new Literal(env_->global()), | |
| 627 // new Literal(proxy->name())); | |
| 628 | 635 |
| 629 } else if (scope_inside_with_) { | 636 } else if (scope_inside_with_) { |
| 630 // If we are inside a with statement we give up and look up | 637 // If we are inside a with statement we give up and look up |
| 631 // the variable at runtime. | 638 // the variable at runtime. |
| 632 var = NonLocal(proxy->name(), Variable::DYNAMIC); | 639 var = NonLocal(proxy->name(), Variable::DYNAMIC); |
| 633 | 640 |
| 634 } else if (invalidated_local != NULL) { | 641 } else if (invalidated_local != NULL) { |
| 635 // No with statements are involved and we found a local | 642 // No with statements are involved and we found a local |
| 636 // variable that might be shadowed by eval introduced | 643 // variable that might be shadowed by eval introduced |
| 637 // variables. | 644 // variables. |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 937 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && | 944 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && |
| 938 !must_have_local_context) { | 945 !must_have_local_context) { |
| 939 num_heap_slots_ = 0; | 946 num_heap_slots_ = 0; |
| 940 } | 947 } |
| 941 | 948 |
| 942 // Allocation done. | 949 // Allocation done. |
| 943 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 950 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
| 944 } | 951 } |
| 945 | 952 |
| 946 } } // namespace v8::internal | 953 } } // namespace v8::internal |
| OLD | NEW |