Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     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.
     27 
     28 #include "v8.h"
     29 
     30 #include "scopes.h"
     31 
     32 #include "accessors.h"
     33 #include "bootstrapper.h"
     34 #include "compiler.h"
     35 #include "messages.h"
     36 #include "scopeinfo.h"
     37 
     38 #include "allocation-inl.h"
     39 
     40 namespace v8 {
     41 namespace internal {
     42 
     43 // ----------------------------------------------------------------------------
     44 // Implementation of LocalsMap
     45 //
     46 // Note: We are storing the handle locations as key values in the hash map.
     47 //       When inserting a new variable via Declare(), we rely on the fact that
     48 //       the handle location remains alive for the duration of that variable
     49 //       use. Because a Variable holding a handle with the same location exists
     50 //       this is ensured.
     51 
     52 static bool Match(void* key1, void* key2) {
     53   String* name1 = *reinterpret_cast<String**>(key1);
     54   String* name2 = *reinterpret_cast<String**>(key2);
     55   ASSERT(name1->IsInternalizedString());
     56   ASSERT(name2->IsInternalizedString());
     57   return name1 == name2;
     58 }
     59 
     60 
     61 VariableMap::VariableMap(Zone* zone)
     62     : ZoneHashMap(Match, 8, ZoneAllocationPolicy(zone)),
     63       zone_(zone) {}
     64 VariableMap::~VariableMap() {}
     65 
     66 
     67 Variable* VariableMap::Declare(
     68     Scope* scope,
     69     Handle<String> name,
     70     VariableMode mode,
     71     bool is_valid_lhs,
     72     Variable::Kind kind,
     73     InitializationFlag initialization_flag,
     74     Interface* interface) {
     75   Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), true,
     76                                  ZoneAllocationPolicy(zone()));
     77   if (p->value == NULL) {
     78     // The variable has not been declared yet -> insert it.
     79     ASSERT(p->key == name.location());
     80     p->value = new(zone()) Variable(scope,
     81                                     name,
     82                                     mode,
     83                                     is_valid_lhs,
     84                                     kind,
     85                                     initialization_flag,
     86                                     interface);
     87   }
     88   return reinterpret_cast<Variable*>(p->value);
     89 }
     90 
     91 
     92 Variable* VariableMap::Lookup(Handle<String> name) {
     93   Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), false,
     94                                  ZoneAllocationPolicy(NULL));
     95   if (p != NULL) {
     96     ASSERT(*reinterpret_cast<String**>(p->key) == *name);
     97     ASSERT(p->value != NULL);
     98     return reinterpret_cast<Variable*>(p->value);
     99   }
    100   return NULL;
    101 }
    102 
    103 
    104 // ----------------------------------------------------------------------------
    105 // Implementation of Scope
    106 
    107 Scope::Scope(Scope* outer_scope, ScopeType scope_type, Zone* zone)
    108     : isolate_(zone->isolate()),
    109       inner_scopes_(4, zone),
    110       variables_(zone),
    111       internals_(4, zone),
    112       temps_(4, zone),
    113       params_(4, zone),
    114       unresolved_(16, zone),
    115       decls_(4, zone),
    116       interface_(FLAG_harmony_modules &&
    117                  (scope_type == MODULE_SCOPE || scope_type == GLOBAL_SCOPE)
    118                      ? Interface::NewModule(zone) : NULL),
    119       already_resolved_(false),
    120       zone_(zone) {
    121   SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null());
    122   // The outermost scope must be a global scope.
    123   ASSERT(scope_type == GLOBAL_SCOPE || outer_scope != NULL);
    124   ASSERT(!HasIllegalRedeclaration());
    125 }
    126 
    127 
    128 Scope::Scope(Scope* inner_scope,
    129              ScopeType scope_type,
    130              Handle<ScopeInfo> scope_info,
    131              Zone* zone)
    132     : isolate_(Isolate::Current()),
    133       inner_scopes_(4, zone),
    134       variables_(zone),
    135       internals_(4, zone),
    136       temps_(4, zone),
    137       params_(4, zone),
    138       unresolved_(16, zone),
    139       decls_(4, zone),
    140       interface_(NULL),
    141       already_resolved_(true),
    142       zone_(zone) {
    143   SetDefaults(scope_type, NULL, scope_info);
    144   if (!scope_info.is_null()) {
    145     num_heap_slots_ = scope_info_->ContextLength();
    146   }
    147   // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context.
    148   num_heap_slots_ = Max(num_heap_slots_,
    149                         static_cast<int>(Context::MIN_CONTEXT_SLOTS));
    150   AddInnerScope(inner_scope);
    151 }
    152 
    153 
    154 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name, Zone* zone)
    155     : isolate_(Isolate::Current()),
    156       inner_scopes_(1, zone),
    157       variables_(zone),
    158       internals_(0, zone),
    159       temps_(0, zone),
    160       params_(0, zone),
    161       unresolved_(0, zone),
    162       decls_(0, zone),
    163       interface_(NULL),
    164       already_resolved_(true),
    165       zone_(zone) {
    166   SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null());
    167   AddInnerScope(inner_scope);
    168   ++num_var_or_const_;
    169   num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
    170   Variable* variable = variables_.Declare(this,
    171                                           catch_variable_name,
    172                                           VAR,
    173                                           true,  // Valid left-hand side.
    174                                           Variable::NORMAL,
    175                                           kCreatedInitialized);
    176   AllocateHeapSlot(variable);
    177 }
    178 
    179 
    180 void Scope::SetDefaults(ScopeType scope_type,
    181                         Scope* outer_scope,
    182                         Handle<ScopeInfo> scope_info) {
    183   outer_scope_ = outer_scope;
    184   scope_type_ = scope_type;
    185   scope_name_ = isolate_->factory()->empty_string();
    186   dynamics_ = NULL;
    187   receiver_ = NULL;
    188   function_ = NULL;
    189   arguments_ = NULL;
    190   illegal_redecl_ = NULL;
    191   scope_inside_with_ = false;
    192   scope_contains_with_ = false;
    193   scope_calls_eval_ = false;
    194   // Inherit the strict mode from the parent scope.
    195   language_mode_ = (outer_scope != NULL)
    196       ? outer_scope->language_mode_ : CLASSIC_MODE;
    197   outer_scope_calls_non_strict_eval_ = false;
    198   inner_scope_calls_eval_ = false;
    199   force_eager_compilation_ = false;
    200   force_context_allocation_ = (outer_scope != NULL && !is_function_scope())
    201       ? outer_scope->has_forced_context_allocation() : false;
    202   num_var_or_const_ = 0;
    203   num_stack_slots_ = 0;
    204   num_heap_slots_ = 0;
    205   num_modules_ = 0;
    206   module_var_ = NULL,
    207   scope_info_ = scope_info;
    208   start_position_ = RelocInfo::kNoPosition;
    209   end_position_ = RelocInfo::kNoPosition;
    210   if (!scope_info.is_null()) {
    211     scope_calls_eval_ = scope_info->CallsEval();
    212     language_mode_ = scope_info->language_mode();
    213   }
    214 }
    215 
    216 
    217 Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope,
    218                                     Zone* zone) {
    219   // Reconstruct the outer scope chain from a closure's context chain.
    220   Scope* current_scope = NULL;
    221   Scope* innermost_scope = NULL;
    222   bool contains_with = false;
    223   while (!context->IsNativeContext()) {
    224     if (context->IsWithContext()) {
    225       Scope* with_scope = new(zone) Scope(current_scope,
    226                                           WITH_SCOPE,
    227                                           Handle<ScopeInfo>::null(),
    228                                           zone);
    229       current_scope = with_scope;
    230       // All the inner scopes are inside a with.
    231       contains_with = true;
    232       for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) {
    233         s->scope_inside_with_ = true;
    234       }
    235     } else if (context->IsGlobalContext()) {
    236       ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
    237       current_scope = new(zone) Scope(current_scope,
    238                                       GLOBAL_SCOPE,
    239                                       Handle<ScopeInfo>(scope_info),
    240                                       zone);
    241     } else if (context->IsModuleContext()) {
    242       ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info());
    243       current_scope = new(zone) Scope(current_scope,
    244                                       MODULE_SCOPE,
    245                                       Handle<ScopeInfo>(scope_info),
    246                                       zone);
    247     } else if (context->IsFunctionContext()) {
    248       ScopeInfo* scope_info = context->closure()->shared()->scope_info();
    249       current_scope = new(zone) Scope(current_scope,
    250                                       FUNCTION_SCOPE,
    251                                       Handle<ScopeInfo>(scope_info),
    252                                       zone);
    253     } else if (context->IsBlockContext()) {
    254       ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
    255       current_scope = new(zone) Scope(current_scope,
    256                                       BLOCK_SCOPE,
    257                                       Handle<ScopeInfo>(scope_info),
    258                                       zone);
    259     } else {
    260       ASSERT(context->IsCatchContext());
    261       String* name = String::cast(context->extension());
    262       current_scope = new(zone) Scope(
    263           current_scope, Handle<String>(name), zone);
    264     }
    265     if (contains_with) current_scope->RecordWithStatement();
    266     if (innermost_scope == NULL) innermost_scope = current_scope;
    267 
    268     // Forget about a with when we move to a context for a different function.
    269     if (context->previous()->closure() != context->closure()) {
    270       contains_with = false;
    271     }
    272     context = context->previous();
    273   }
    274 
    275   global_scope->AddInnerScope(current_scope);
    276   global_scope->PropagateScopeInfo(false);
    277   return (innermost_scope == NULL) ? global_scope : innermost_scope;
    278 }
    279 
    280 
    281 bool Scope::Analyze(CompilationInfo* info) {
    282   ASSERT(info->function() != NULL);
    283   Scope* scope = info->function()->scope();
    284   Scope* top = scope;
    285 
    286   // Traverse the scope tree up to the first unresolved scope or the global
    287   // scope and start scope resolution and variable allocation from that scope.
    288   while (!top->is_global_scope() &&
    289          !top->outer_scope()->already_resolved()) {
    290     top = top->outer_scope();
    291   }
    292 
    293   // Allocate the variables.
    294   {
    295     AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate(),
    296                                                     info->zone());
    297     if (!top->AllocateVariables(info, &ast_node_factory)) return false;
    298   }
    299 
    300 #ifdef DEBUG
    301   if (info->isolate()->bootstrapper()->IsActive()
    302           ? FLAG_print_builtin_scopes
    303           : FLAG_print_scopes) {
    304     scope->Print();
    305   }
    306 
    307   if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_global_scope()) {
    308     PrintF("global : ");
    309     top->interface()->Print();
    310   }
    311 #endif
    312 
    313   info->SetScope(scope);
    314   return true;
    315 }
    316 
    317 
    318 void Scope::Initialize() {
    319   ASSERT(!already_resolved());
    320 
    321   // Add this scope as a new inner scope of the outer scope.
    322   if (outer_scope_ != NULL) {
    323     outer_scope_->inner_scopes_.Add(this, zone());
    324     scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope();
    325   } else {
    326     scope_inside_with_ = is_with_scope();
    327   }
    328 
    329   // Declare convenience variables.
    330   // Declare and allocate receiver (even for the global scope, and even
    331   // if naccesses_ == 0).
    332   // NOTE: When loading parameters in the global scope, we must take
    333   // care not to access them as properties of the global object, but
    334   // instead load them directly from the stack. Currently, the only
    335   // such parameter is 'this' which is passed on the stack when
    336   // invoking scripts
    337   if (is_declaration_scope()) {
    338     Variable* var =
    339         variables_.Declare(this,
    340                            isolate_->factory()->this_string(),
    341                            VAR,
    342                            false,
    343                            Variable::THIS,
    344                            kCreatedInitialized);
    345     var->AllocateTo(Variable::PARAMETER, -1);
    346     receiver_ = var;
    347   } else {
    348     ASSERT(outer_scope() != NULL);
    349     receiver_ = outer_scope()->receiver();
    350   }
    351 
    352   if (is_function_scope()) {
    353     // Declare 'arguments' variable which exists in all functions.
    354     // Note that it might never be accessed, in which case it won't be
    355     // allocated during variable allocation.
    356     variables_.Declare(this,
    357                        isolate_->factory()->arguments_string(),
    358                        VAR,
    359                        true,
    360                        Variable::ARGUMENTS,
    361                        kCreatedInitialized);
    362   }
    363 }
    364 
    365 
    366 Scope* Scope::FinalizeBlockScope() {
    367   ASSERT(is_block_scope());
    368   ASSERT(internals_.is_empty());
    369   ASSERT(temps_.is_empty());
    370   ASSERT(params_.is_empty());
    371 
    372   if (num_var_or_const() > 0) return this;
    373 
    374   // Remove this scope from outer scope.
    375   for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) {
    376     if (outer_scope_->inner_scopes_[i] == this) {
    377       outer_scope_->inner_scopes_.Remove(i);
    378       break;
    379     }
    380   }
    381 
    382   // Reparent inner scopes.
    383   for (int i = 0; i < inner_scopes_.length(); i++) {
    384     outer_scope()->AddInnerScope(inner_scopes_[i]);
    385   }
    386 
    387   // Move unresolved variables
    388   for (int i = 0; i < unresolved_.length(); i++) {
    389     outer_scope()->unresolved_.Add(unresolved_[i], zone());
    390   }
    391 
    392   return NULL;
    393 }
    394 
    395 
    396 Variable* Scope::LocalLookup(Handle<String> name) {
    397   Variable* result = variables_.Lookup(name);
    398   if (result != NULL || scope_info_.is_null()) {
    399     return result;
    400   }
    401   // If we have a serialized scope info, we might find the variable there.
    402   // There should be no local slot with the given name.
    403   ASSERT(scope_info_->StackSlotIndex(*name) < 0);
    404 
    405   // Check context slot lookup.
    406   VariableMode mode;
    407   Variable::Location location = Variable::CONTEXT;
    408   InitializationFlag init_flag;
    409   int index = scope_info_->ContextSlotIndex(*name, &mode, &init_flag);
    410   if (index < 0) {
    411     // Check parameters.
    412     index = scope_info_->ParameterIndex(*name);
    413     if (index < 0) return NULL;
    414 
    415     mode = DYNAMIC;
    416     location = Variable::LOOKUP;
    417     init_flag = kCreatedInitialized;
    418   }
    419 
    420   Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL,
    421                                      init_flag);
    422   var->AllocateTo(location, index);
    423   return var;
    424 }
    425 
    426 
    427 Variable* Scope::LookupFunctionVar(Handle<String> name,
    428                                    AstNodeFactory<AstNullVisitor>* factory) {
    429   if (function_ != NULL && function_->proxy()->name().is_identical_to(name)) {
    430     return function_->proxy()->var();
    431   } else if (!scope_info_.is_null()) {
    432     // If we are backed by a scope info, try to lookup the variable there.
    433     VariableMode mode;
    434     int index = scope_info_->FunctionContextSlotIndex(*name, &mode);
    435     if (index < 0) return NULL;
    436     Variable* var = new(zone()) Variable(
    437         this, name, mode, true /* is valid LHS */,
    438         Variable::NORMAL, kCreatedInitialized);
    439     VariableProxy* proxy = factory->NewVariableProxy(var);
    440     VariableDeclaration* declaration =
    441         factory->NewVariableDeclaration(proxy, mode, this);
    442     DeclareFunctionVar(declaration);
    443     var->AllocateTo(Variable::CONTEXT, index);
    444     return var;
    445   } else {
    446     return NULL;
    447   }
    448 }
    449 
    450 
    451 Variable* Scope::Lookup(Handle<String> name) {
    452   for (Scope* scope = this;
    453        scope != NULL;
    454        scope = scope->outer_scope()) {
    455     Variable* var = scope->LocalLookup(name);
    456     if (var != NULL) return var;
    457   }
    458   return NULL;
    459 }
    460 
    461 
    462 void Scope::DeclareParameter(Handle<String> name, VariableMode mode) {
    463   ASSERT(!already_resolved());
    464   ASSERT(is_function_scope());
    465   Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL,
    466                                      kCreatedInitialized);
    467   params_.Add(var, zone());
    468 }
    469 
    470 
    471 Variable* Scope::DeclareLocal(Handle<String> name,
    472                               VariableMode mode,
    473                               InitializationFlag init_flag,
    474                               Interface* interface) {
    475   ASSERT(!already_resolved());
    476   // This function handles VAR and CONST modes.  DYNAMIC variables are
    477   // introduces during variable allocation, INTERNAL variables are allocated
    478   // explicitly, and TEMPORARY variables are allocated via NewTemporary().
    479   ASSERT(IsDeclaredVariableMode(mode));
    480   ++num_var_or_const_;
    481   return variables_.Declare(
    482       this, name, mode, true, Variable::NORMAL, init_flag, interface);
    483 }
    484 
    485 
    486 Variable* Scope::DeclareDynamicGlobal(Handle<String> name) {
    487   ASSERT(is_global_scope());
    488   return variables_.Declare(this,
    489                             name,
    490                             DYNAMIC_GLOBAL,
    491                             true,
    492                             Variable::NORMAL,
    493                             kCreatedInitialized);
    494 }
    495 
    496 
    497 void Scope::RemoveUnresolved(VariableProxy* var) {
    498   // Most likely (always?) any variable we want to remove
    499   // was just added before, so we search backwards.
    500   for (int i = unresolved_.length(); i-- > 0;) {
    501     if (unresolved_[i] == var) {
    502       unresolved_.Remove(i);
    503       return;
    504     }
    505   }
    506 }
    507 
    508 
    509 Variable* Scope::NewInternal(Handle<String> name) {
    510   ASSERT(!already_resolved());
    511   Variable* var = new(zone()) Variable(this,
    512                                        name,
    513                                        INTERNAL,
    514                                        false,
    515                                        Variable::NORMAL,
    516                                        kCreatedInitialized);
    517   internals_.Add(var, zone());
    518   return var;
    519 }
    520 
    521 
    522 Variable* Scope::NewTemporary(Handle<String> name) {
    523   ASSERT(!already_resolved());
    524   Variable* var = new(zone()) Variable(this,
    525                                        name,
    526                                        TEMPORARY,
    527                                        true,
    528                                        Variable::NORMAL,
    529                                        kCreatedInitialized);
    530   temps_.Add(var, zone());
    531   return var;
    532 }
    533 
    534 
    535 void Scope::AddDeclaration(Declaration* declaration) {
    536   decls_.Add(declaration, zone());
    537 }
    538 
    539 
    540 void Scope::SetIllegalRedeclaration(Expression* expression) {
    541   // Record only the first illegal redeclaration.
    542   if (!HasIllegalRedeclaration()) {
    543     illegal_redecl_ = expression;
    544   }
    545   ASSERT(HasIllegalRedeclaration());
    546 }
    547 
    548 
    549 void Scope::VisitIllegalRedeclaration(AstVisitor* visitor) {
    550   ASSERT(HasIllegalRedeclaration());
    551   illegal_redecl_->Accept(visitor);
    552 }
    553 
    554 
    555 Declaration* Scope::CheckConflictingVarDeclarations() {
    556   int length = decls_.length();
    557   for (int i = 0; i < length; i++) {
    558     Declaration* decl = decls_[i];
    559     if (decl->mode() != VAR) continue;
    560     Handle<String> name = decl->proxy()->name();
    561 
    562     // Iterate through all scopes until and including the declaration scope.
    563     Scope* previous = NULL;
    564     Scope* current = decl->scope();
    565     do {
    566       // There is a conflict if there exists a non-VAR binding.
    567       Variable* other_var = current->variables_.Lookup(name);
    568       if (other_var != NULL && other_var->mode() != VAR) {
    569         return decl;
    570       }
    571       previous = current;
    572       current = current->outer_scope_;
    573     } while (!previous->is_declaration_scope());
    574   }
    575   return NULL;
    576 }
    577 
    578 
    579 class VarAndOrder {
    580  public:
    581   VarAndOrder(Variable* var, int order) : var_(var), order_(order) { }
    582   Variable* var() const { return var_; }
    583   int order() const { return order_; }
    584   static int Compare(const VarAndOrder* a, const VarAndOrder* b) {
    585     return a->order_ - b->order_;
    586   }
    587 
    588  private:
    589   Variable* var_;
    590   int order_;
    591 };
    592 
    593 
    594 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
    595                                          ZoneList<Variable*>* context_locals) {
    596   ASSERT(stack_locals != NULL);
    597   ASSERT(context_locals != NULL);
    598 
    599   // Collect internals which are always allocated on the heap.
    600   for (int i = 0; i < internals_.length(); i++) {
    601     Variable* var = internals_[i];
    602     if (var->is_used()) {
    603       ASSERT(var->IsContextSlot());
    604       context_locals->Add(var, zone());
    605     }
    606   }
    607 
    608   // Collect temporaries which are always allocated on the stack, unless the
    609   // context as a whole has forced context allocation.
    610   for (int i = 0; i < temps_.length(); i++) {
    611     Variable* var = temps_[i];
    612     if (var->is_used()) {
    613       if (var->IsContextSlot()) {
    614         ASSERT(has_forced_context_allocation());
    615         context_locals->Add(var, zone());
    616       } else {
    617         ASSERT(var->IsStackLocal());
    618         stack_locals->Add(var, zone());
    619       }
    620     }
    621   }
    622 
    623   // Collect declared local variables.
    624   ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
    625   for (VariableMap::Entry* p = variables_.Start();
    626        p != NULL;
    627        p = variables_.Next(p)) {
    628     Variable* var = reinterpret_cast<Variable*>(p->value);
    629     if (var->is_used()) {
    630       vars.Add(VarAndOrder(var, p->order), zone());
    631     }
    632   }
    633   vars.Sort(VarAndOrder::Compare);
    634   int var_count = vars.length();
    635   for (int i = 0; i < var_count; i++) {
    636     Variable* var = vars[i].var();
    637     if (var->IsStackLocal()) {
    638       stack_locals->Add(var, zone());
    639     } else if (var->IsContextSlot()) {
    640       context_locals->Add(var, zone());
    641     }
    642   }
    643 }
    644 
    645 
    646 bool Scope::AllocateVariables(CompilationInfo* info,
    647                               AstNodeFactory<AstNullVisitor>* factory) {
    648   // 1) Propagate scope information.
    649   bool outer_scope_calls_non_strict_eval = false;
    650   if (outer_scope_ != NULL) {
    651     outer_scope_calls_non_strict_eval =
    652         outer_scope_->outer_scope_calls_non_strict_eval() |
    653         outer_scope_->calls_non_strict_eval();
    654   }
    655   PropagateScopeInfo(outer_scope_calls_non_strict_eval);
    656 
    657   // 2) Allocate module instances.
    658   if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) {
    659     ASSERT(num_modules_ == 0);
    660     AllocateModulesRecursively(this);
    661   }
    662 
    663   // 3) Resolve variables.
    664   if (!ResolveVariablesRecursively(info, factory)) return false;
    665 
    666   // 4) Allocate variables.
    667   AllocateVariablesRecursively();
    668 
    669   return true;
    670 }
    671 
    672 
    673 bool Scope::HasTrivialContext() const {
    674   // A function scope has a trivial context if it always is the global
    675   // context. We iteratively scan out the context chain to see if
    676   // there is anything that makes this scope non-trivial; otherwise we
    677   // return true.
    678   for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) {
    679     if (scope->is_eval_scope()) return false;
    680     if (scope->scope_inside_with_) return false;
    681     if (scope->num_heap_slots_ > 0) return false;
    682   }
    683   return true;
    684 }
    685 
    686 
    687 bool Scope::HasTrivialOuterContext() const {
    688   Scope* outer = outer_scope_;
    689   if (outer == NULL) return true;
    690   // Note that the outer context may be trivial in general, but the current
    691   // scope may be inside a 'with' statement in which case the outer context
    692   // for this scope is not trivial.
    693   return !scope_inside_with_ && outer->HasTrivialContext();
    694 }
    695 
    696 
    697 bool Scope::HasLazyCompilableOuterContext() const {
    698   Scope* outer = outer_scope_;
    699   if (outer == NULL) return true;
    700   // We have to prevent lazy compilation if this scope is inside a with scope
    701   // and all declaration scopes between them have empty contexts. Such
    702   // declaration scopes may become invisible during scope info deserialization.
    703   outer = outer->DeclarationScope();
    704   bool found_non_trivial_declarations = false;
    705   for (const Scope* scope = outer; scope != NULL; scope = scope->outer_scope_) {
    706     if (scope->is_with_scope() && !found_non_trivial_declarations) return false;
    707     if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) {
    708       found_non_trivial_declarations = true;
    709     }
    710   }
    711   return true;
    712 }
    713 
    714 
    715 bool Scope::AllowsLazyCompilation() const {
    716   return !force_eager_compilation_ && HasLazyCompilableOuterContext();
    717 }
    718 
    719 
    720 bool Scope::AllowsLazyCompilationWithoutContext() const {
    721   return !force_eager_compilation_ && HasTrivialOuterContext();
    722 }
    723 
    724 
    725 int Scope::ContextChainLength(Scope* scope) {
    726   int n = 0;
    727   for (Scope* s = this; s != scope; s = s->outer_scope_) {
    728     ASSERT(s != NULL);  // scope must be in the scope chain
    729     if (s->is_with_scope() || s->num_heap_slots() > 0) n++;
    730     // Catch and module scopes always have heap slots.
    731     ASSERT(!s->is_catch_scope() || s->num_heap_slots() > 0);
    732     ASSERT(!s->is_module_scope() || s->num_heap_slots() > 0);
    733   }
    734   return n;
    735 }
    736 
    737 
    738 Scope* Scope::GlobalScope() {
    739   Scope* scope = this;
    740   while (!scope->is_global_scope()) {
    741     scope = scope->outer_scope();
    742   }
    743   return scope;
    744 }
    745 
    746 
    747 Scope* Scope::DeclarationScope() {
    748   Scope* scope = this;
    749   while (!scope->is_declaration_scope()) {
    750     scope = scope->outer_scope();
    751   }
    752   return scope;
    753 }
    754 
    755 
    756 Handle<ScopeInfo> Scope::GetScopeInfo() {
    757   if (scope_info_.is_null()) {
    758     scope_info_ = ScopeInfo::Create(this, zone());
    759   }
    760   return scope_info_;
    761 }
    762 
    763 
    764 void Scope::GetNestedScopeChain(
    765     List<Handle<ScopeInfo> >* chain,
    766     int position) {
    767   if (!is_eval_scope()) chain->Add(Handle<ScopeInfo>(GetScopeInfo()));
    768 
    769   for (int i = 0; i < inner_scopes_.length(); i++) {
    770     Scope* scope = inner_scopes_[i];
    771     int beg_pos = scope->start_position();
    772     int end_pos = scope->end_position();
    773     ASSERT(beg_pos >= 0 && end_pos >= 0);
    774     if (beg_pos <= position && position < end_pos) {
    775       scope->GetNestedScopeChain(chain, position);
    776       return;
    777     }
    778   }
    779 }
    780 
    781 
    782 #ifdef DEBUG
    783 static const char* Header(ScopeType scope_type) {
    784   switch (scope_type) {
    785     case EVAL_SCOPE: return "eval";
    786     case FUNCTION_SCOPE: return "function";
    787     case MODULE_SCOPE: return "module";
    788     case GLOBAL_SCOPE: return "global";
    789     case CATCH_SCOPE: return "catch";
    790     case BLOCK_SCOPE: return "block";
    791     case WITH_SCOPE: return "with";
    792   }
    793   UNREACHABLE();
    794   return NULL;
    795 }
    796 
    797 
    798 static void Indent(int n, const char* str) {
    799   PrintF("%*s%s", n, "", str);
    800 }
    801 
    802 
    803 static void PrintName(Handle<String> name) {
    804   SmartArrayPointer<char> s = name->ToCString(DISALLOW_NULLS);
    805   PrintF("%s", *s);
    806 }
    807 
    808 
    809 static void PrintLocation(Variable* var) {
    810   switch (var->location()) {
    811     case Variable::UNALLOCATED:
    812       break;
    813     case Variable::PARAMETER:
    814       PrintF("parameter[%d]", var->index());
    815       break;
    816     case Variable::LOCAL:
    817       PrintF("local[%d]", var->index());
    818       break;
    819     case Variable::CONTEXT:
    820       PrintF("context[%d]", var->index());
    821       break;
    822     case Variable::LOOKUP:
    823       PrintF("lookup");
    824       break;
    825   }
    826 }
    827 
    828 
    829 static void PrintVar(int indent, Variable* var) {
    830   if (var->is_used() || !var->IsUnallocated()) {
    831     Indent(indent, Variable::Mode2String(var->mode()));
    832     PrintF(" ");
    833     PrintName(var->name());
    834     PrintF(";  // ");
    835     PrintLocation(var);
    836     if (var->has_forced_context_allocation()) {
    837       if (!var->IsUnallocated()) PrintF(", ");
    838       PrintF("forced context allocation");
    839     }
    840     PrintF("\n");
    841   }
    842 }
    843 
    844 
    845 static void PrintMap(int indent, VariableMap* map) {
    846   for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
    847     Variable* var = reinterpret_cast<Variable*>(p->value);
    848     PrintVar(indent, var);
    849   }
    850 }
    851 
    852 
    853 void Scope::Print(int n) {
    854   int n0 = (n > 0 ? n : 0);
    855   int n1 = n0 + 2;  // indentation
    856 
    857   // Print header.
    858   Indent(n0, Header(scope_type_));
    859   if (scope_name_->length() > 0) {
    860     PrintF(" ");
    861     PrintName(scope_name_);
    862   }
    863 
    864   // Print parameters, if any.
    865   if (is_function_scope()) {
    866     PrintF(" (");
    867     for (int i = 0; i < params_.length(); i++) {
    868       if (i > 0) PrintF(", ");
    869       PrintName(params_[i]->name());
    870     }
    871     PrintF(")");
    872   }
    873 
    874   PrintF(" { // (%d, %d)\n", start_position(), end_position());
    875 
    876   // Function name, if any (named function literals, only).
    877   if (function_ != NULL) {
    878     Indent(n1, "// (local) function name: ");
    879     PrintName(function_->proxy()->name());
    880     PrintF("\n");
    881   }
    882 
    883   // Scope info.
    884   if (HasTrivialOuterContext()) {
    885     Indent(n1, "// scope has trivial outer context\n");
    886   }
    887   switch (language_mode()) {
    888     case CLASSIC_MODE:
    889       break;
    890     case STRICT_MODE:
    891       Indent(n1, "// strict mode scope\n");
    892       break;
    893     case EXTENDED_MODE:
    894       Indent(n1, "// extended mode scope\n");
    895       break;
    896   }
    897   if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n");
    898   if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n");
    899   if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
    900   if (outer_scope_calls_non_strict_eval_) {
    901     Indent(n1, "// outer scope calls 'eval' in non-strict context\n");
    902   }
    903   if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
    904   if (num_stack_slots_ > 0) { Indent(n1, "// ");
    905   PrintF("%d stack slots\n", num_stack_slots_); }
    906   if (num_heap_slots_ > 0) { Indent(n1, "// ");
    907   PrintF("%d heap slots\n", num_heap_slots_); }
    908 
    909   // Print locals.
    910   Indent(n1, "// function var\n");
    911   if (function_ != NULL) {
    912     PrintVar(n1, function_->proxy()->var());
    913   }
    914 
    915   Indent(n1, "// temporary vars\n");
    916   for (int i = 0; i < temps_.length(); i++) {
    917     PrintVar(n1, temps_[i]);
    918   }
    919 
    920   Indent(n1, "// internal vars\n");
    921   for (int i = 0; i < internals_.length(); i++) {
    922     PrintVar(n1, internals_[i]);
    923   }
    924 
    925   Indent(n1, "// local vars\n");
    926   PrintMap(n1, &variables_);
    927 
    928   Indent(n1, "// dynamic vars\n");
    929   if (dynamics_ != NULL) {
    930     PrintMap(n1, dynamics_->GetMap(DYNAMIC));
    931     PrintMap(n1, dynamics_->GetMap(DYNAMIC_LOCAL));
    932     PrintMap(n1, dynamics_->GetMap(DYNAMIC_GLOBAL));
    933   }
    934 
    935   // Print inner scopes (disable by providing negative n).
    936   if (n >= 0) {
    937     for (int i = 0; i < inner_scopes_.length(); i++) {
    938       PrintF("\n");
    939       inner_scopes_[i]->Print(n1);
    940     }
    941   }
    942 
    943   Indent(n0, "}\n");
    944 }
    945 #endif  // DEBUG
    946 
    947 
    948 Variable* Scope::NonLocal(Handle<String> name, VariableMode mode) {
    949   if (dynamics_ == NULL) dynamics_ = new(zone()) DynamicScopePart(zone());
    950   VariableMap* map = dynamics_->GetMap(mode);
    951   Variable* var = map->Lookup(name);
    952   if (var == NULL) {
    953     // Declare a new non-local.
    954     InitializationFlag init_flag = (mode == VAR)
    955         ? kCreatedInitialized : kNeedsInitialization;
    956     var = map->Declare(NULL,
    957                        name,
    958                        mode,
    959                        true,
    960                        Variable::NORMAL,
    961                        init_flag);
    962     // Allocate it by giving it a dynamic lookup.
    963     var->AllocateTo(Variable::LOOKUP, -1);
    964   }
    965   return var;
    966 }
    967 
    968 
    969 Variable* Scope::LookupRecursive(Handle<String> name,
    970                                  BindingKind* binding_kind,
    971                                  AstNodeFactory<AstNullVisitor>* factory) {
    972   ASSERT(binding_kind != NULL);
    973   if (already_resolved() && is_with_scope()) {
    974     // Short-cut: if the scope is deserialized from a scope info, variable
    975     // allocation is already fixed.  We can simply return with dynamic lookup.
    976     *binding_kind = DYNAMIC_LOOKUP;
    977     return NULL;
    978   }
    979 
    980   // Try to find the variable in this scope.
    981   Variable* var = LocalLookup(name);
    982 
    983   // We found a variable and we are done. (Even if there is an 'eval' in
    984   // this scope which introduces the same variable again, the resulting
    985   // variable remains the same.)
    986   if (var != NULL) {
    987     *binding_kind = BOUND;
    988     return var;
    989   }
    990 
    991   // We did not find a variable locally. Check against the function variable,
    992   // if any. We can do this for all scopes, since the function variable is
    993   // only present - if at all - for function scopes.
    994   *binding_kind = UNBOUND;
    995   var = LookupFunctionVar(name, factory);
    996   if (var != NULL) {
    997     *binding_kind = BOUND;
    998   } else if (outer_scope_ != NULL) {
    999     var = outer_scope_->LookupRecursive(name, binding_kind, factory);
   1000     if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) {
   1001       var->ForceContextAllocation();
   1002     }
   1003   } else {
   1004     ASSERT(is_global_scope());
   1005   }
   1006 
   1007   if (is_with_scope()) {
   1008     ASSERT(!already_resolved());
   1009     // The current scope is a with scope, so the variable binding can not be
   1010     // statically resolved. However, note that it was necessary to do a lookup
   1011     // in the outer scope anyway, because if a binding exists in an outer scope,
   1012     // the associated variable has to be marked as potentially being accessed
   1013     // from inside of an inner with scope (the property may not be in the 'with'
   1014     // object).
   1015     *binding_kind = DYNAMIC_LOOKUP;
   1016     return NULL;
   1017   } else if (calls_non_strict_eval()) {
   1018     // A variable binding may have been found in an outer scope, but the current
   1019     // scope makes a non-strict 'eval' call, so the found variable may not be
   1020     // the correct one (the 'eval' may introduce a binding with the same name).
   1021     // In that case, change the lookup result to reflect this situation.
   1022     if (*binding_kind == BOUND) {
   1023       *binding_kind = BOUND_EVAL_SHADOWED;
   1024     } else if (*binding_kind == UNBOUND) {
   1025       *binding_kind = UNBOUND_EVAL_SHADOWED;
   1026     }
   1027   }
   1028   return var;
   1029 }
   1030 
   1031 
   1032 bool Scope::ResolveVariable(CompilationInfo* info,
   1033                             VariableProxy* proxy,
   1034                             AstNodeFactory<AstNullVisitor>* factory) {
   1035   ASSERT(info->global_scope()->is_global_scope());
   1036 
   1037   // If the proxy is already resolved there's nothing to do
   1038   // (functions and consts may be resolved by the parser).
   1039   if (proxy->var() != NULL) return true;
   1040 
   1041   // Otherwise, try to resolve the variable.
   1042   BindingKind binding_kind;
   1043   Variable* var = LookupRecursive(proxy->name(), &binding_kind, factory);
   1044   switch (binding_kind) {
   1045     case BOUND:
   1046       // We found a variable binding.
   1047       break;
   1048 
   1049     case BOUND_EVAL_SHADOWED:
   1050       // We either found a variable binding that might be shadowed by eval  or
   1051       // gave up on it (e.g. by encountering a local with the same in the outer
   1052       // scope which was not promoted to a context, this can happen if we use
   1053       // debugger to evaluate arbitrary expressions at a break point).
   1054       if (var->IsGlobalObjectProperty()) {
   1055         var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
   1056       } else if (var->is_dynamic()) {
   1057         var = NonLocal(proxy->name(), DYNAMIC);
   1058       } else {
   1059         Variable* invalidated = var;
   1060         var = NonLocal(proxy->name(), DYNAMIC_LOCAL);
   1061         var->set_local_if_not_shadowed(invalidated);
   1062       }
   1063       break;
   1064 
   1065     case UNBOUND:
   1066       // No binding has been found. Declare a variable on the global object.
   1067       var = info->global_scope()->DeclareDynamicGlobal(proxy->name());
   1068       break;
   1069 
   1070     case UNBOUND_EVAL_SHADOWED:
   1071       // No binding has been found. But some scope makes a
   1072       // non-strict 'eval' call.
   1073       var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
   1074       break;
   1075 
   1076     case DYNAMIC_LOOKUP:
   1077       // The variable could not be resolved statically.
   1078       var = NonLocal(proxy->name(), DYNAMIC);
   1079       break;
   1080   }
   1081 
   1082   ASSERT(var != NULL);
   1083 
   1084   if (FLAG_harmony_scoping && is_extended_mode() &&
   1085       var->is_const_mode() && proxy->IsLValue()) {
   1086     // Assignment to const. Throw a syntax error.
   1087     MessageLocation location(
   1088         info->script(), proxy->position(), proxy->position());
   1089     Isolate* isolate = Isolate::Current();
   1090     Factory* factory = isolate->factory();
   1091     Handle<JSArray> array = factory->NewJSArray(0);
   1092     Handle<Object> result =
   1093         factory->NewSyntaxError("harmony_const_assign", array);
   1094     isolate->Throw(*result, &location);
   1095     return false;
   1096   }
   1097 
   1098   if (FLAG_harmony_modules) {
   1099     bool ok;
   1100 #ifdef DEBUG
   1101     if (FLAG_print_interface_details)
   1102       PrintF("# Resolve %s:\n", var->name()->ToAsciiArray());
   1103 #endif
   1104     proxy->interface()->Unify(var->interface(), zone(), &ok);
   1105     if (!ok) {
   1106 #ifdef DEBUG
   1107       if (FLAG_print_interfaces) {
   1108         PrintF("SCOPES TYPE ERROR\n");
   1109         PrintF("proxy: ");
   1110         proxy->interface()->Print();
   1111         PrintF("var: ");
   1112         var->interface()->Print();
   1113       }
   1114 #endif
   1115 
   1116       // Inconsistent use of module. Throw a syntax error.
   1117       // TODO(rossberg): generate more helpful error message.
   1118       MessageLocation location(
   1119           info->script(), proxy->position(), proxy->position());
   1120       Isolate* isolate = Isolate::Current();
   1121       Factory* factory = isolate->factory();
   1122       Handle<JSArray> array = factory->NewJSArray(1);
   1123       USE(JSObject::SetElement(array, 0, var->name(), NONE, kStrictMode));
   1124       Handle<Object> result =
   1125           factory->NewSyntaxError("module_type_error", array);
   1126       isolate->Throw(*result, &location);
   1127       return false;
   1128     }
   1129   }
   1130 
   1131   proxy->BindTo(var);
   1132 
   1133   return true;
   1134 }
   1135 
   1136 
   1137 bool Scope::ResolveVariablesRecursively(
   1138     CompilationInfo* info,
   1139     AstNodeFactory<AstNullVisitor>* factory) {
   1140   ASSERT(info->global_scope()->is_global_scope());
   1141 
   1142   // Resolve unresolved variables for this scope.
   1143   for (int i = 0; i < unresolved_.length(); i++) {
   1144     if (!ResolveVariable(info, unresolved_[i], factory)) return false;
   1145   }
   1146 
   1147   // Resolve unresolved variables for inner scopes.
   1148   for (int i = 0; i < inner_scopes_.length(); i++) {
   1149     if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory))
   1150       return false;
   1151   }
   1152 
   1153   return true;
   1154 }
   1155 
   1156 
   1157 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) {
   1158   if (outer_scope_calls_non_strict_eval) {
   1159     outer_scope_calls_non_strict_eval_ = true;
   1160   }
   1161 
   1162   bool calls_non_strict_eval =
   1163       this->calls_non_strict_eval() || outer_scope_calls_non_strict_eval_;
   1164   for (int i = 0; i < inner_scopes_.length(); i++) {
   1165     Scope* inner_scope = inner_scopes_[i];
   1166     if (inner_scope->PropagateScopeInfo(calls_non_strict_eval)) {
   1167       inner_scope_calls_eval_ = true;
   1168     }
   1169     if (inner_scope->force_eager_compilation_) {
   1170       force_eager_compilation_ = true;
   1171     }
   1172   }
   1173 
   1174   return scope_calls_eval_ || inner_scope_calls_eval_;
   1175 }
   1176 
   1177 
   1178 bool Scope::MustAllocate(Variable* var) {
   1179   // Give var a read/write use if there is a chance it might be accessed
   1180   // via an eval() call.  This is only possible if the variable has a
   1181   // visible name.
   1182   if ((var->is_this() || var->name()->length() > 0) &&
   1183       (var->has_forced_context_allocation() ||
   1184        scope_calls_eval_ ||
   1185        inner_scope_calls_eval_ ||
   1186        scope_contains_with_ ||
   1187        is_catch_scope() ||
   1188        is_block_scope() ||
   1189        is_module_scope() ||
   1190        is_global_scope())) {
   1191     var->set_is_used(true);
   1192   }
   1193   // Global variables do not need to be allocated.
   1194   return !var->IsGlobalObjectProperty() && var->is_used();
   1195 }
   1196 
   1197 
   1198 bool Scope::MustAllocateInContext(Variable* var) {
   1199   // If var is accessed from an inner scope, or if there is a possibility
   1200   // that it might be accessed from the current or an inner scope (through
   1201   // an eval() call or a runtime with lookup), it must be allocated in the
   1202   // context.
   1203   //
   1204   // Exceptions: If the scope as a whole has forced context allocation, all
   1205   // variables will have context allocation, even temporaries.  Otherwise
   1206   // temporary variables are always stack-allocated.  Catch-bound variables are
   1207   // always context-allocated.
   1208   if (has_forced_context_allocation()) return true;
   1209   if (var->mode() == TEMPORARY) return false;
   1210   if (var->mode() == INTERNAL) return true;
   1211   if (is_catch_scope() || is_block_scope() || is_module_scope()) return true;
   1212   if (is_global_scope() && IsLexicalVariableMode(var->mode())) return true;
   1213   return var->has_forced_context_allocation() ||
   1214       scope_calls_eval_ ||
   1215       inner_scope_calls_eval_ ||
   1216       scope_contains_with_;
   1217 }
   1218 
   1219 
   1220 bool Scope::HasArgumentsParameter() {
   1221   for (int i = 0; i < params_.length(); i++) {
   1222     if (params_[i]->name().is_identical_to(
   1223             isolate_->factory()->arguments_string())) {
   1224       return true;
   1225     }
   1226   }
   1227   return false;
   1228 }
   1229 
   1230 
   1231 void Scope::AllocateStackSlot(Variable* var) {
   1232   var->AllocateTo(Variable::LOCAL, num_stack_slots_++);
   1233 }
   1234 
   1235 
   1236 void Scope::AllocateHeapSlot(Variable* var) {
   1237   var->AllocateTo(Variable::CONTEXT, num_heap_slots_++);
   1238 }
   1239 
   1240 
   1241 void Scope::AllocateParameterLocals() {
   1242   ASSERT(is_function_scope());
   1243   Variable* arguments = LocalLookup(isolate_->factory()->arguments_string());
   1244   ASSERT(arguments != NULL);  // functions have 'arguments' declared implicitly
   1245 
   1246   bool uses_nonstrict_arguments = false;
   1247 
   1248   if (MustAllocate(arguments) && !HasArgumentsParameter()) {
   1249     // 'arguments' is used. Unless there is also a parameter called
   1250     // 'arguments', we must be conservative and allocate all parameters to
   1251     // the context assuming they will be captured by the arguments object.
   1252     // If we have a parameter named 'arguments', a (new) value is always
   1253     // assigned to it via the function invocation. Then 'arguments' denotes
   1254     // that specific parameter value and cannot be used to access the
   1255     // parameters, which is why we don't need to allocate an arguments
   1256     // object in that case.
   1257 
   1258     // We are using 'arguments'. Tell the code generator that is needs to
   1259     // allocate the arguments object by setting 'arguments_'.
   1260     arguments_ = arguments;
   1261 
   1262     // In strict mode 'arguments' does not alias formal parameters.
   1263     // Therefore in strict mode we allocate parameters as if 'arguments'
   1264     // were not used.
   1265     uses_nonstrict_arguments = is_classic_mode();
   1266   }
   1267 
   1268   // The same parameter may occur multiple times in the parameters_ list.
   1269   // If it does, and if it is not copied into the context object, it must
   1270   // receive the highest parameter index for that parameter; thus iteration
   1271   // order is relevant!
   1272   for (int i = params_.length() - 1; i >= 0; --i) {
   1273     Variable* var = params_[i];
   1274     ASSERT(var->scope() == this);
   1275     if (uses_nonstrict_arguments) {
   1276       // Force context allocation of the parameter.
   1277       var->ForceContextAllocation();
   1278     }
   1279 
   1280     if (MustAllocate(var)) {
   1281       if (MustAllocateInContext(var)) {
   1282         ASSERT(var->IsUnallocated() || var->IsContextSlot());
   1283         if (var->IsUnallocated()) {
   1284           AllocateHeapSlot(var);
   1285         }
   1286       } else {
   1287         ASSERT(var->IsUnallocated() || var->IsParameter());
   1288         if (var->IsUnallocated()) {
   1289           var->AllocateTo(Variable::PARAMETER, i);
   1290         }
   1291       }
   1292     }
   1293   }
   1294 }
   1295 
   1296 
   1297 void Scope::AllocateNonParameterLocal(Variable* var) {
   1298   ASSERT(var->scope() == this);
   1299   ASSERT(!var->IsVariable(isolate_->factory()->result_string()) ||
   1300          !var->IsStackLocal());
   1301   if (var->IsUnallocated() && MustAllocate(var)) {
   1302     if (MustAllocateInContext(var)) {
   1303       AllocateHeapSlot(var);
   1304     } else {
   1305       AllocateStackSlot(var);
   1306     }
   1307   }
   1308 }
   1309 
   1310 
   1311 void Scope::AllocateNonParameterLocals() {
   1312   // All variables that have no rewrite yet are non-parameter locals.
   1313   for (int i = 0; i < temps_.length(); i++) {
   1314     AllocateNonParameterLocal(temps_[i]);
   1315   }
   1316 
   1317   for (int i = 0; i < internals_.length(); i++) {
   1318     AllocateNonParameterLocal(internals_[i]);
   1319   }
   1320 
   1321   ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
   1322   for (VariableMap::Entry* p = variables_.Start();
   1323        p != NULL;
   1324        p = variables_.Next(p)) {
   1325     Variable* var = reinterpret_cast<Variable*>(p->value);
   1326     vars.Add(VarAndOrder(var, p->order), zone());
   1327   }
   1328   vars.Sort(VarAndOrder::Compare);
   1329   int var_count = vars.length();
   1330   for (int i = 0; i < var_count; i++) {
   1331     AllocateNonParameterLocal(vars[i].var());
   1332   }
   1333 
   1334   // For now, function_ must be allocated at the very end.  If it gets
   1335   // allocated in the context, it must be the last slot in the context,
   1336   // because of the current ScopeInfo implementation (see
   1337   // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
   1338   if (function_ != NULL) {
   1339     AllocateNonParameterLocal(function_->proxy()->var());
   1340   }
   1341 }
   1342 
   1343 
   1344 void Scope::AllocateVariablesRecursively() {
   1345   // Allocate variables for inner scopes.
   1346   for (int i = 0; i < inner_scopes_.length(); i++) {
   1347     inner_scopes_[i]->AllocateVariablesRecursively();
   1348   }
   1349 
   1350   // If scope is already resolved, we still need to allocate
   1351   // variables in inner scopes which might not had been resolved yet.
   1352   if (already_resolved()) return;
   1353   // The number of slots required for variables.
   1354   num_stack_slots_ = 0;
   1355   num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
   1356 
   1357   // Allocate variables for this scope.
   1358   // Parameters must be allocated first, if any.
   1359   if (is_function_scope()) AllocateParameterLocals();
   1360   AllocateNonParameterLocals();
   1361 
   1362   // Force allocation of a context for this scope if necessary. For a 'with'
   1363   // scope and for a function scope that makes an 'eval' call we need a context,
   1364   // even if no local variables were statically allocated in the scope.
   1365   // Likewise for modules.
   1366   bool must_have_context = is_with_scope() || is_module_scope() ||
   1367       (is_function_scope() && calls_eval());
   1368 
   1369   // If we didn't allocate any locals in the local context, then we only
   1370   // need the minimal number of slots if we must have a context.
   1371   if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
   1372     num_heap_slots_ = 0;
   1373   }
   1374 
   1375   // Allocation done.
   1376   ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
   1377 }
   1378 
   1379 
   1380 void Scope::AllocateModulesRecursively(Scope* host_scope) {
   1381   if (already_resolved()) return;
   1382   if (is_module_scope()) {
   1383     ASSERT(interface_->IsFrozen());
   1384     Handle<String> name = isolate_->factory()->InternalizeOneByteString(
   1385         STATIC_ASCII_VECTOR(".module"));
   1386     ASSERT(module_var_ == NULL);
   1387     module_var_ = host_scope->NewInternal(name);
   1388     ++host_scope->num_modules_;
   1389   }
   1390 
   1391   for (int i = 0; i < inner_scopes_.length(); i++) {
   1392     Scope* inner_scope = inner_scopes_.at(i);
   1393     inner_scope->AllocateModulesRecursively(host_scope);
   1394   }
   1395 }
   1396 
   1397 
   1398 int Scope::StackLocalCount() const {
   1399   return num_stack_slots() -
   1400       (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0);
   1401 }
   1402 
   1403 
   1404 int Scope::ContextLocalCount() const {
   1405   if (num_heap_slots() == 0) return 0;
   1406   return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
   1407       (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
   1408 }
   1409 
   1410 } }  // namespace v8::internal
   1411