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