1b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopes.h"
8b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/accessors.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compiler.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/messages.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopeinfo.h"
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
1671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of LocalsMap
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Note: We are storing the handle locations as key values in the hash map.
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       When inserting a new variable via Declare(), we rely on the fact that
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       the handle location remains alive for the duration of that variable
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       use. Because a Variable holding a handle with the same location exists
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       this is ensured.
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgVariableMap::VariableMap(Zone* zone)
2808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    : ZoneHashMap(ZoneHashMap::PointersMatch, 8, ZoneAllocationPolicy(zone)),
297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      zone_(zone) {}
3068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgVariableMap::~VariableMap() {}
3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgVariable* VariableMap::Declare(Scope* scope, const AstRawString* name,
347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                               VariableMode mode, bool is_valid_lhs,
357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                               Variable::Kind kind,
367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                               InitializationFlag initialization_flag,
377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                               MaybeAssignedFlag maybe_assigned_flag,
387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                               Interface* interface) {
3908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  // AstRawStrings are unambiguous, i.e., the same string is always represented
4008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  // by the same AstRawString*.
4108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  // FIXME(marja): fix the type of Lookup.
4208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(),
4308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                 true, ZoneAllocationPolicy(zone()));
4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (p->value == NULL) {
4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // The variable has not been declared yet -> insert it.
46e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(p->key == name);
477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    p->value = new (zone())
487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Variable(scope, name, mode, is_valid_lhs, kind, initialization_flag,
497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                 maybe_assigned_flag, interface);
5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
5143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return reinterpret_cast<Variable*>(p->value);
5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgVariable* VariableMap::Lookup(const AstRawString* name) {
5608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(),
5708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                 false, ZoneAllocationPolicy(NULL));
5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (p != NULL) {
59e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
60e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(p->value != NULL);
6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return reinterpret_cast<Variable*>(p->value);
6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of Scope
6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgScope::Scope(Scope* outer_scope, ScopeType scope_type,
7108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org             AstValueFactory* ast_value_factory, Zone* zone)
728432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    : isolate_(zone->isolate()),
737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      inner_scopes_(4, zone),
747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      variables_(zone),
758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      internals_(4, zone),
767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      temps_(4, zone),
777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      params_(4, zone),
787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      unresolved_(16, zone),
797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      decls_(4, zone),
80bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      interface_(FLAG_harmony_modules &&
81dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                 (scope_type == MODULE_SCOPE || scope_type == GLOBAL_SCOPE)
827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                     ? Interface::NewModule(zone) : NULL),
837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      already_resolved_(false),
8408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      ast_value_factory_(ast_value_factory),
857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      zone_(zone) {
86dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null());
87355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // The outermost scope must be a global scope.
88e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(scope_type == GLOBAL_SCOPE || outer_scope != NULL);
89e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!HasIllegalRedeclaration());
9043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
934acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.orgScope::Scope(Scope* inner_scope,
94dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org             ScopeType scope_type,
957028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org             Handle<ScopeInfo> scope_info,
9608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org             AstValueFactory* value_factory,
977028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org             Zone* zone)
983d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    : isolate_(zone->isolate()),
997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      inner_scopes_(4, zone),
1007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      variables_(zone),
1018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      internals_(4, zone),
1027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      temps_(4, zone),
1037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      params_(4, zone),
1047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      unresolved_(16, zone),
1057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      decls_(4, zone),
106bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      interface_(NULL),
1077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      already_resolved_(true),
10808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      ast_value_factory_(value_factory),
1097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      zone_(zone) {
110dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  SetDefaults(scope_type, NULL, scope_info);
111c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (!scope_info.is_null()) {
112c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    num_heap_slots_ = scope_info_->ContextLength();
113c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  }
1141145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context.
1151145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  num_heap_slots_ = Max(num_heap_slots_,
1161145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org                        static_cast<int>(Context::MIN_CONTEXT_SLOTS));
1174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  AddInnerScope(inner_scope);
1184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
1194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
12108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgScope::Scope(Scope* inner_scope, const AstRawString* catch_variable_name,
12208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org             AstValueFactory* value_factory, Zone* zone)
1233d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    : isolate_(zone->isolate()),
1247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      inner_scopes_(1, zone),
1257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      variables_(zone),
1268e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      internals_(0, zone),
1277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      temps_(0, zone),
1287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      params_(0, zone),
1297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      unresolved_(0, zone),
1307028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      decls_(0, zone),
131bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      interface_(NULL),
1327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      already_resolved_(true),
13308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      ast_value_factory_(value_factory),
1347028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      zone_(zone) {
135c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null());
1364d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  AddInnerScope(inner_scope);
1374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  ++num_var_or_const_;
13827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
1394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Variable* variable = variables_.Declare(this,
1404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                          catch_variable_name,
141b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                          VAR,
1424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                          true,  // Valid left-hand side.
143c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                          Variable::NORMAL,
144c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                          kCreatedInitialized);
1454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  AllocateHeapSlot(variable);
146c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org}
147c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
148c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
149dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgvoid Scope::SetDefaults(ScopeType scope_type,
1503475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org                        Scope* outer_scope,
151c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        Handle<ScopeInfo> scope_info) {
1523475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  outer_scope_ = outer_scope;
153dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  scope_type_ = scope_type;
15408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  scope_name_ = ast_value_factory_->empty_string();
1553475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  dynamics_ = NULL;
1563475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  receiver_ = NULL;
1573475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  function_ = NULL;
1583475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  arguments_ = NULL;
1593475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  illegal_redecl_ = NULL;
1603475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  scope_inside_with_ = false;
1613475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  scope_contains_with_ = false;
1623475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  scope_calls_eval_ = false;
163a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  asm_module_ = false;
164a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  asm_function_ = outer_scope != NULL && outer_scope->asm_module_;
1653475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  // Inherit the strict mode from the parent scope.
166486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  strict_mode_ = outer_scope != NULL ? outer_scope->strict_mode_ : SLOPPY;
167486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  outer_scope_calls_sloppy_eval_ = false;
1683475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  inner_scope_calls_eval_ = false;
1693475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  force_eager_compilation_ = false;
170e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  force_context_allocation_ = (outer_scope != NULL && !is_function_scope())
171e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      ? outer_scope->has_forced_context_allocation() : false;
1727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  num_var_or_const_ = 0;
1733475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  num_stack_slots_ = 0;
1743475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  num_heap_slots_ = 0;
1758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  num_modules_ = 0;
1768e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  module_var_ = NULL,
1773475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org  scope_info_ = scope_info;
178394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  start_position_ = RelocInfo::kNoPosition;
179394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  end_position_ = RelocInfo::kNoPosition;
18027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  if (!scope_info.is_null()) {
18127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    scope_calls_eval_ = scope_info->CallsEval();
182486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    strict_mode_ = scope_info->strict_mode();
18327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  }
1843475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org}
1853475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org
1863475509e36d49b28dd5a12ee647284718fc3ddbbsgjesse@chromium.org
1877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgScope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope,
1887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                    Zone* zone) {
1894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Reconstruct the outer scope chain from a closure's context chain.
1904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Scope* current_scope = NULL;
1914d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  Scope* innermost_scope = NULL;
1924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  bool contains_with = false;
19346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  while (!context->IsNativeContext()) {
1944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if (context->IsWithContext()) {
1957028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      Scope* with_scope = new(zone) Scope(current_scope,
1967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                          WITH_SCOPE,
1977028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                          Handle<ScopeInfo>::null(),
19808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                          global_scope->ast_value_factory_,
1997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                          zone);
200394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      current_scope = with_scope;
2014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      // All the inner scopes are inside a with.
2024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      contains_with = true;
2034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) {
2044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        s->scope_inside_with_ = true;
2054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      }
20646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    } else if (context->IsGlobalContext()) {
20746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
20846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      current_scope = new(zone) Scope(current_scope,
20946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                                      GLOBAL_SCOPE,
21046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                                      Handle<ScopeInfo>(scope_info),
21108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                      global_scope->ast_value_factory_,
21246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                                      zone);
21381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    } else if (context->IsModuleContext()) {
21481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info());
21581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      current_scope = new(zone) Scope(current_scope,
21681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org                                      MODULE_SCOPE,
21781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org                                      Handle<ScopeInfo>(scope_info),
21808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                      global_scope->ast_value_factory_,
21981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org                                      zone);
220394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } else if (context->IsFunctionContext()) {
221c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ScopeInfo* scope_info = context->closure()->shared()->scope_info();
2227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      current_scope = new(zone) Scope(current_scope,
2237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                      FUNCTION_SCOPE,
2247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                      Handle<ScopeInfo>(scope_info),
22508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                      global_scope->ast_value_factory_,
2267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                      zone);
227a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true;
228a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      if (scope_info->IsAsmModule()) current_scope->asm_module_ = true;
229394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } else if (context->IsBlockContext()) {
230c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
2317028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      current_scope = new(zone) Scope(current_scope,
2327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                      BLOCK_SCOPE,
2337028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                      Handle<ScopeInfo>(scope_info),
23408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                      global_scope->ast_value_factory_,
2357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                      zone);
2364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    } else {
237e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(context->IsCatchContext());
238394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      String* name = String::cast(context->extension());
23908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      current_scope = new (zone) Scope(
24008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org          current_scope,
24108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org          global_scope->ast_value_factory_->GetString(Handle<String>(name)),
24208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org          global_scope->ast_value_factory_, zone);
2434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    }
2445de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org    if (contains_with) current_scope->RecordWithStatement();
245394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (innermost_scope == NULL) innermost_scope = current_scope;
2464d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
2474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    // Forget about a with when we move to a context for a different function.
2484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if (context->previous()->closure() != context->closure()) {
2494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      contains_with = false;
2504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    }
2514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    context = context->previous();
2524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
2534d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
2544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  global_scope->AddInnerScope(current_scope);
25527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  global_scope->PropagateScopeInfo(false);
2564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return (innermost_scope == NULL) ? global_scope : innermost_scope;
2574d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org}
2584d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
259c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
260b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.orgbool Scope::Analyze(CompilationInfo* info) {
261e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(info->function() != NULL);
26227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  Scope* scope = info->function()->scope();
26327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  Scope* top = scope;
264c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
26527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  // Traverse the scope tree up to the first unresolved scope or the global
26627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  // scope and start scope resolution and variable allocation from that scope.
26727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  while (!top->is_global_scope() &&
26827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org         !top->outer_scope()->already_resolved()) {
26927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    top = top->outer_scope();
27027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  }
27127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
272b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  // Allocate the variables.
273b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  {
274a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    AstNodeFactory<AstNullVisitor> ast_node_factory(
275a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        info->zone(), info->ast_value_factory(), info->ast_node_id_gen());
276bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (!top->AllocateVariables(info, &ast_node_factory)) return false;
277b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  }
278b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org
279b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org#ifdef DEBUG
280ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (info->isolate()->bootstrapper()->IsActive()
281b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org          ? FLAG_print_builtin_scopes
282b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org          : FLAG_print_scopes) {
28327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    scope->Print();
284b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  }
285bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
286bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_global_scope()) {
287bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    PrintF("global : ");
288bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    top->interface()->Print();
289bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  }
290b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org#endif
291b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org
292f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  info->PrepareForCompilation(scope);
29364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  return true;
294b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org}
295b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org
296b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org
297394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid Scope::Initialize() {
298e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!already_resolved());
299c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add this scope as a new inner scope of the outer scope.
30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (outer_scope_ != NULL) {
3027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    outer_scope_->inner_scopes_.Add(this, zone());
303394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope();
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
305394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    scope_inside_with_ = is_with_scope();
30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Declare convenience variables.
30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Declare and allocate receiver (even for the global scope, and even
31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // if naccesses_ == 0).
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // NOTE: When loading parameters in the global scope, we must take
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // care not to access them as properties of the global object, but
31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // instead load them directly from the stack. Currently, the only
31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // such parameter is 'this' which is passed on the stack when
31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // invoking scripts
316394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (is_declaration_scope()) {
3174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    Variable* var =
31884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        variables_.Declare(this,
31908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                           ast_value_factory_->this_string(),
320b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                           VAR,
32184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org                           false,
322c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                           Variable::THIS,
323c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                           kCreatedInitialized);
324486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    var->AllocateTo(Variable::PARAMETER, -1);
3254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    receiver_ = var;
326394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  } else {
327e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(outer_scope() != NULL);
328394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    receiver_ = outer_scope()->receiver();
3294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (is_function_scope()) {
33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Declare 'arguments' variable which exists in all functions.
33368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org    // Note that it might never be accessed, in which case it won't be
33468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org    // allocated during variable allocation.
33584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    variables_.Declare(this,
33608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                       ast_value_factory_->arguments_string(),
337b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                       VAR,
33884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org                       true,
339c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       Variable::ARGUMENTS,
340c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       kCreatedInitialized);
34143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
34343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3451805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgScope* Scope::FinalizeBlockScope() {
346e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_block_scope());
347e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(internals_.is_empty());
348e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(temps_.is_empty());
349e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(params_.is_empty());
3501805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
3511805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  if (num_var_or_const() > 0) return this;
3521805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
3531805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // Remove this scope from outer scope.
3541805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) {
3551805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    if (outer_scope_->inner_scopes_[i] == this) {
3561805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      outer_scope_->inner_scopes_.Remove(i);
3571805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      break;
3581805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    }
3591805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  }
3601805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
3611805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // Reparent inner scopes.
3621805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  for (int i = 0; i < inner_scopes_.length(); i++) {
3631805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    outer_scope()->AddInnerScope(inner_scopes_[i]);
3641805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  }
3651805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
3661805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // Move unresolved variables
3671805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  for (int i = 0; i < unresolved_.length(); i++) {
3687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    outer_scope()->unresolved_.Add(unresolved_[i], zone());
3691805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  }
3701805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
3711805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  return NULL;
3721805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org}
3731805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
3741805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
37508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgVariable* Scope::LookupLocal(const AstRawString* name) {
376c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  Variable* result = variables_.Lookup(name);
3774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (result != NULL || scope_info_.is_null()) {
378c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    return result;
379c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  }
38008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  // The Scope is backed up by ScopeInfo. This means it cannot operate in a
38108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  // heap-independent mode, and all strings must be internalized immediately. So
38208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  // it's ok to get the Handle<String> here.
38308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Handle<String> name_handle = name->string();
3844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // If we have a serialized scope info, we might find the variable there.
3857b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // There should be no local slot with the given name.
386e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0);
3870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
388c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Check context slot lookup.
389b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  VariableMode mode;
39028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  Variable::Location location = Variable::CONTEXT;
391c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  InitializationFlag init_flag;
3927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  MaybeAssignedFlag maybe_assigned_flag;
3937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
3947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                          &init_flag, &maybe_assigned_flag);
3957b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (index < 0) {
3967b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // Check parameters.
39708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    index = scope_info_->ParameterIndex(*name_handle);
39827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    if (index < 0) return NULL;
39928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
40028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    mode = DYNAMIC;
40128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    location = Variable::LOOKUP;
40228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    init_flag = kCreatedInitialized;
4037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // Be conservative and flag parameters as maybe assigned. Better information
4047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // would require ScopeInfo to serialize the maybe_assigned bit also for
4057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // parameters.
4067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    maybe_assigned_flag = kMaybeAssigned;
4070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  }
4080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
4097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL,
4107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                     init_flag, maybe_assigned_flag);
41128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  var->AllocateTo(location, index);
4127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  return var;
41343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
41443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgVariable* Scope::LookupFunctionVar(const AstRawString* name,
417b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                   AstNodeFactory<AstNullVisitor>* factory) {
41808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  if (function_ != NULL && function_->proxy()->raw_name() == name) {
419ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    return function_->proxy()->var();
42027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  } else if (!scope_info_.is_null()) {
42127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    // If we are backed by a scope info, try to lookup the variable there.
42227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    VariableMode mode;
42308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode);
42427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    if (index < 0) return NULL;
4257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    Variable* var = new(zone()) Variable(
426ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        this, name, mode, true /* is valid LHS */,
427ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        Variable::NORMAL, kCreatedInitialized);
428ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    VariableProxy* proxy = factory->NewVariableProxy(var);
429a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    VariableDeclaration* declaration = factory->NewVariableDeclaration(
430a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        proxy, mode, this, RelocInfo::kNoPosition);
431ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    DeclareFunctionVar(declaration);
43227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    var->AllocateTo(Variable::CONTEXT, index);
43327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    return var;
43427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  } else {
43527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    return NULL;
43627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  }
43727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org}
43827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
43927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
44008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgVariable* Scope::Lookup(const AstRawString* name) {
441a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  for (Scope* scope = this;
442a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org       scope != NULL;
443a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org       scope = scope->outer_scope()) {
444fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    Variable* var = scope->LookupLocal(name);
445a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (var != NULL) return var;
446a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
447a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return NULL;
448a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
449a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
450a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
4517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgVariable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode) {
452e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!already_resolved());
453e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_function_scope());
4547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL,
4557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                     kCreatedInitialized);
4567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  params_.Add(var, zone());
4577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return var;
458c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org}
459c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org
460c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org
4617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgVariable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
462bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com                              InitializationFlag init_flag,
4637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                              MaybeAssignedFlag maybe_assigned_flag,
464bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com                              Interface* interface) {
465e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!already_resolved());
466486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  // This function handles VAR, LET, and CONST modes.  DYNAMIC variables are
467c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  // introduces during variable allocation, INTERNAL variables are allocated
468c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  // explicitly, and TEMPORARY variables are allocated via NewTemporary().
469e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDeclaredVariableMode(mode));
470c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  ++num_var_or_const_;
4717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag,
4727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                            maybe_assigned_flag, interface);
47368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}
47468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
47568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org
47608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgVariable* Scope::DeclareDynamicGlobal(const AstRawString* name) {
477e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_global_scope());
478c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return variables_.Declare(this,
479c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                            name,
480c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                            DYNAMIC_GLOBAL,
481486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org                            true,
482c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                            Variable::NORMAL,
483c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                            kCreatedInitialized);
48443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
48543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Scope::RemoveUnresolved(VariableProxy* var) {
48843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Most likely (always?) any variable we want to remove
48943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // was just added before, so we search backwards.
49043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = unresolved_.length(); i-- > 0;) {
49143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (unresolved_[i] == var) {
49243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      unresolved_.Remove(i);
49343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return;
49443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
49543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
49643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
49743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgVariable* Scope::NewInternal(const AstRawString* name) {
500e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!already_resolved());
5018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Variable* var = new(zone()) Variable(this,
5028e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                       name,
5038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                       INTERNAL,
5048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                       false,
5058e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                       Variable::NORMAL,
5068e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                       kCreatedInitialized);
5078e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  internals_.Add(var, zone());
5088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return var;
5098e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
5108e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
5118e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
51208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgVariable* Scope::NewTemporary(const AstRawString* name) {
513e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!already_resolved());
5147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Variable* var = new(zone()) Variable(this,
5157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                       name,
5167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                       TEMPORARY,
5177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                       true,
5187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                       Variable::NORMAL,
5197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                       kCreatedInitialized);
5207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  temps_.Add(var, zone());
521a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return var;
52243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
52343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Scope::AddDeclaration(Declaration* declaration) {
5267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  decls_.Add(declaration, zone());
52743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
52843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
53043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Scope::SetIllegalRedeclaration(Expression* expression) {
53183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  // Record only the first illegal redeclaration.
53243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!HasIllegalRedeclaration()) {
53343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    illegal_redecl_ = expression;
53443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
535e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(HasIllegalRedeclaration());
53643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
53743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
53843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
539a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid Scope::VisitIllegalRedeclaration(AstVisitor* visitor) {
540e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(HasIllegalRedeclaration());
54143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  illegal_redecl_->Accept(visitor);
54243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
54343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5451805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgDeclaration* Scope::CheckConflictingVarDeclarations() {
5461805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  int length = decls_.length();
5471805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  for (int i = 0; i < length; i++) {
5481805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    Declaration* decl = decls_[i];
549b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    if (decl->mode() != VAR) continue;
55008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    const AstRawString* name = decl->proxy()->raw_name();
551394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
552394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // Iterate through all scopes until and including the declaration scope.
553394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Scope* previous = NULL;
554394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Scope* current = decl->scope();
555394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    do {
5561805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      // There is a conflict if there exists a non-VAR binding.
557394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Variable* other_var = current->variables_.Lookup(name);
558b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      if (other_var != NULL && other_var->mode() != VAR) {
5591805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org        return decl;
5601805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      }
561394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      previous = current;
562394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      current = current->outer_scope_;
563394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } while (!previous->is_declaration_scope());
5641805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  }
5651805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  return NULL;
5661805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org}
5671805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
5681805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
56946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgclass VarAndOrder {
57046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org public:
57146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  VarAndOrder(Variable* var, int order) : var_(var), order_(order) { }
57246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Variable* var() const { return var_; }
57346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  int order() const { return order_; }
57446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  static int Compare(const VarAndOrder* a, const VarAndOrder* b) {
57546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    return a->order_ - b->order_;
57646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
57746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
57846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org private:
57946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Variable* var_;
58046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  int order_;
58146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org};
58246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
58346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
585c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                         ZoneList<Variable*>* context_locals) {
586e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(stack_locals != NULL);
587e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(context_locals != NULL);
588c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5898e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Collect internals which are always allocated on the heap.
5908e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  for (int i = 0; i < internals_.length(); i++) {
5918e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Variable* var = internals_[i];
5928e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (var->is_used()) {
593e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(var->IsContextSlot());
5948e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      context_locals->Add(var, zone());
5958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    }
5968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
5978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
598e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Collect temporaries which are always allocated on the stack, unless the
599e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // context as a whole has forced context allocation.
60043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < temps_.length(); i++) {
60143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Variable* var = temps_[i];
602ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (var->is_used()) {
603e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      if (var->IsContextSlot()) {
604e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(has_forced_context_allocation());
605e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        context_locals->Add(var, zone());
606e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      } else {
607e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(var->IsStackLocal());
608e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        stack_locals->Add(var, zone());
609e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      }
61043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
61143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
612c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Collect declared local variables.
6148e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
61568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  for (VariableMap::Entry* p = variables_.Start();
61668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org       p != NULL;
61768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org       p = variables_.Next(p)) {
61843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Variable* var = reinterpret_cast<Variable*>(p->value);
619ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (var->is_used()) {
62046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      vars.Add(VarAndOrder(var, p->order), zone());
62146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    }
62246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
62346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  vars.Sort(VarAndOrder::Compare);
62446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  int var_count = vars.length();
62546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  for (int i = 0; i < var_count; i++) {
62646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    Variable* var = vars[i].var();
62746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (var->IsStackLocal()) {
62846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      stack_locals->Add(var, zone());
62946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    } else if (var->IsContextSlot()) {
63046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      context_locals->Add(var, zone());
63143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
63243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
63343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
63443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
63543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
636bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.combool Scope::AllocateVariables(CompilationInfo* info,
637b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                              AstNodeFactory<AstNullVisitor>* factory) {
63843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // 1) Propagate scope information.
639486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  bool outer_scope_calls_sloppy_eval = false;
64027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  if (outer_scope_ != NULL) {
641486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    outer_scope_calls_sloppy_eval =
642486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        outer_scope_->outer_scope_calls_sloppy_eval() |
643486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        outer_scope_->calls_sloppy_eval();
64483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
645486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  PropagateScopeInfo(outer_scope_calls_sloppy_eval);
64643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6478e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // 2) Allocate module instances.
6488e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) {
649e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(num_modules_ == 0);
6508e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    AllocateModulesRecursively(this);
6518e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
6528e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
6538e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // 3) Resolve variables.
654bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (!ResolveVariablesRecursively(info, factory)) return false;
65543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6568e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // 4) Allocate variables.
65743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  AllocateVariablesRecursively();
658bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
659bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  return true;
66043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
66143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
66243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
66343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Scope::HasTrivialContext() const {
66443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // A function scope has a trivial context if it always is the global
66543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // context. We iteratively scan out the context chain to see if
66643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // there is anything that makes this scope non-trivial; otherwise we
66743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // return true.
66843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) {
66943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (scope->is_eval_scope()) return false;
67043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (scope->scope_inside_with_) return false;
67143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (scope->num_heap_slots_ > 0) return false;
67243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
67343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
67443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
67543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
67643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
67743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Scope::HasTrivialOuterContext() const {
67843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Scope* outer = outer_scope_;
67943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (outer == NULL) return true;
68043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note that the outer context may be trivial in general, but the current
68143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // scope may be inside a 'with' statement in which case the outer context
68243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // for this scope is not trivial.
68343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return !scope_inside_with_ && outer->HasTrivialContext();
68443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
68543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
687c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgbool Scope::HasLazyCompilableOuterContext() const {
688c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  Scope* outer = outer_scope_;
689c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  if (outer == NULL) return true;
690cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org  // We have to prevent lazy compilation if this scope is inside a with scope
691cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org  // and all declaration scopes between them have empty contexts. Such
692cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org  // declaration scopes may become invisible during scope info deserialization.
693c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  outer = outer->DeclarationScope();
694c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  bool found_non_trivial_declarations = false;
695c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  for (const Scope* scope = outer; scope != NULL; scope = scope->outer_scope_) {
696c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    if (scope->is_with_scope() && !found_non_trivial_declarations) return false;
697c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) {
698c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      found_non_trivial_declarations = true;
699c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    }
700c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  }
701c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  return true;
702d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org}
703d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org
704d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org
705c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgbool Scope::AllowsLazyCompilation() const {
706c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  return !force_eager_compilation_ && HasLazyCompilableOuterContext();
7075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}
7085a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
7095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
710c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgbool Scope::AllowsLazyCompilationWithoutContext() const {
711c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  return !force_eager_compilation_ && HasTrivialOuterContext();
712d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org}
713d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org
714d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org
71543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint Scope::ContextChainLength(Scope* scope) {
71643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int n = 0;
71743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (Scope* s = this; s != scope; s = s->outer_scope_) {
718e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(s != NULL);  // scope must be in the scope chain
719ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if (s->is_with_scope() || s->num_heap_slots() > 0) n++;
720f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    // Catch and module scopes always have heap slots.
721e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!s->is_catch_scope() || s->num_heap_slots() > 0);
722e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!s->is_module_scope() || s->num_heap_slots() > 0);
72343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
72443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return n;
72543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
72643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7288e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgScope* Scope::GlobalScope() {
7298e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Scope* scope = this;
7308e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  while (!scope->is_global_scope()) {
7318e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    scope = scope->outer_scope();
7328e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
7338e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return scope;
7348e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
7358e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
7368e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
7374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgScope* Scope::DeclarationScope() {
7384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  Scope* scope = this;
739394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  while (!scope->is_declaration_scope()) {
7404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    scope = scope->outer_scope();
7414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
7424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return scope;
7434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
7444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
7454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
746c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<ScopeInfo> Scope::GetScopeInfo() {
7474acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  if (scope_info_.is_null()) {
7487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    scope_info_ = ScopeInfo::Create(this, zone());
7494acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
7504acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  return scope_info_;
7514acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org}
7524acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
7534acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
754394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid Scope::GetNestedScopeChain(
755c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    List<Handle<ScopeInfo> >* chain,
756394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    int position) {
7571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (!is_eval_scope()) chain->Add(Handle<ScopeInfo>(GetScopeInfo()));
758394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
759394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  for (int i = 0; i < inner_scopes_.length(); i++) {
760394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Scope* scope = inner_scopes_[i];
761394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    int beg_pos = scope->start_position();
762394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    int end_pos = scope->end_position();
763e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(beg_pos >= 0 && end_pos >= 0);
7641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (beg_pos <= position && position < end_pos) {
765394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      scope->GetNestedScopeChain(chain, position);
766394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      return;
767394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
768394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
769394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
770394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
771394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
77243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
773dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgstatic const char* Header(ScopeType scope_type) {
774dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  switch (scope_type) {
775394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case EVAL_SCOPE: return "eval";
776394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case FUNCTION_SCOPE: return "function";
777f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    case MODULE_SCOPE: return "module";
778394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case GLOBAL_SCOPE: return "global";
779394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case CATCH_SCOPE: return "catch";
780394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case BLOCK_SCOPE: return "block";
781394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case WITH_SCOPE: return "with";
78243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
78343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  UNREACHABLE();
78443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
78543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
78643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Indent(int n, const char* str) {
78943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("%*s%s", n, "", str);
79043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
79143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgstatic void PrintName(const AstRawString* name) {
79408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  PrintF("%.*s", name->length(), name->raw_data());
79543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
79643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
798486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgstatic void PrintLocation(Variable* var) {
799486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  switch (var->location()) {
800486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::UNALLOCATED:
801486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      break;
802486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::PARAMETER:
803486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      PrintF("parameter[%d]", var->index());
804486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      break;
805486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::LOCAL:
806486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      PrintF("local[%d]", var->index());
807486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      break;
808486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::CONTEXT:
809486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      PrintF("context[%d]", var->index());
810486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      break;
811486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::LOOKUP:
812486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      PrintF("lookup");
813486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      break;
814486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
815486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org}
816486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
817486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
818486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgstatic void PrintVar(int indent, Variable* var) {
819486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (var->is_used() || !var->IsUnallocated()) {
82043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Indent(indent, Variable::Mode2String(var->mode()));
82143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF(" ");
82208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    PrintName(var->raw_name());
82343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF(";  // ");
824486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    PrintLocation(var);
825248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    bool comma = !var->IsUnallocated();
826c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (var->has_forced_context_allocation()) {
827248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org      if (comma) PrintF(", ");
828c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      PrintF("forced context allocation");
829248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org      comma = true;
830248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    }
8317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (var->maybe_assigned() == kMaybeAssigned) {
832248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org      if (comma) PrintF(", ");
833248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org      PrintF("maybe assigned");
834ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
83543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("\n");
83643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
83743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
83843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
83943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
840486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgstatic void PrintMap(int indent, VariableMap* map) {
84168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
842b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    Variable* var = reinterpret_cast<Variable*>(p->value);
843486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    PrintVar(indent, var);
844b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  }
845b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org}
846b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
847b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org
84843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Scope::Print(int n) {
84943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int n0 = (n > 0 ? n : 0);
85043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int n1 = n0 + 2;  // indentation
85143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Print header.
853dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Indent(n0, Header(scope_type_));
85408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  if (!scope_name_->IsEmpty()) {
85543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF(" ");
85643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintName(scope_name_);
85743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
85843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
85943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Print parameters, if any.
86043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (is_function_scope()) {
86143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF(" (");
86243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (int i = 0; i < params_.length(); i++) {
86343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (i > 0) PrintF(", ");
86408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      PrintName(params_[i]->raw_name());
86543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
86643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF(")");
86743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
86843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
869f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  PrintF(" { // (%d, %d)\n", start_position(), end_position());
87043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Function name, if any (named function literals, only).
87243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (function_ != NULL) {
87343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Indent(n1, "// (local) function name: ");
87408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    PrintName(function_->proxy()->raw_name());
87543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("\n");
87643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
87743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Scope info.
87943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (HasTrivialOuterContext()) {
88043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Indent(n1, "// scope has trivial outer context\n");
88143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
882486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (strict_mode() == STRICT) {
883486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    Indent(n1, "// strict mode scope\n");
8841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
88543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n");
88643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n");
88743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
888486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (outer_scope_calls_sloppy_eval_) {
889486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    Indent(n1, "// outer scope calls 'eval' in sloppy context\n");
89083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
89143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
89243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (num_stack_slots_ > 0) { Indent(n1, "// ");
89343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("%d stack slots\n", num_stack_slots_); }
89443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (num_heap_slots_ > 0) { Indent(n1, "// ");
89543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("%d heap slots\n", num_heap_slots_); }
89643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Print locals.
89843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (function_ != NULL) {
8991e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    Indent(n1, "// function var:\n");
900ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    PrintVar(n1, function_->proxy()->var());
90143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
90243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9031e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  if (temps_.length() > 0) {
9041e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    Indent(n1, "// temporary vars:\n");
9051e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    for (int i = 0; i < temps_.length(); i++) {
9061e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      PrintVar(n1, temps_[i]);
9071e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    }
90843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
90943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9101e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  if (internals_.length() > 0) {
9111e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    Indent(n1, "// internal vars:\n");
9121e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    for (int i = 0; i < internals_.length(); i++) {
9131e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      PrintVar(n1, internals_[i]);
9141e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    }
9158e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
9168e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
9171e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  if (variables_.Start() != NULL) {
9181e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    Indent(n1, "// local vars:\n");
9191e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    PrintMap(n1, &variables_);
9201e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  }
92143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
922b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  if (dynamics_ != NULL) {
9231e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    Indent(n1, "// dynamic vars:\n");
924b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    PrintMap(n1, dynamics_->GetMap(DYNAMIC));
925b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    PrintMap(n1, dynamics_->GetMap(DYNAMIC_LOCAL));
926b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    PrintMap(n1, dynamics_->GetMap(DYNAMIC_GLOBAL));
927b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  }
92843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Print inner scopes (disable by providing negative n).
93043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (n >= 0) {
93143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (int i = 0; i < inner_scopes_.length(); i++) {
93243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      PrintF("\n");
93343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      inner_scopes_[i]->Print(n1);
93443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
93543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
93643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
93743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Indent(n0, "}\n");
93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
93943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif  // DEBUG
94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgVariable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
94308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone());
94468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  VariableMap* map = dynamics_->GetMap(mode);
945b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  Variable* var = map->Lookup(name);
946b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org  if (var == NULL) {
947b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // Declare a new non-local.
948c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    InitializationFlag init_flag = (mode == VAR)
949c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        ? kCreatedInitialized : kNeedsInitialization;
950c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    var = map->Declare(NULL,
951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       name,
952c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       mode,
953c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       true,
954c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       Variable::NORMAL,
955c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       init_flag);
956b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org    // Allocate it by giving it a dynamic lookup.
957486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    var->AllocateTo(Variable::LOOKUP, -1);
95843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
95943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return var;
96043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
96143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
963248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.orgVariable* Scope::LookupRecursive(VariableProxy* proxy,
964b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                 BindingKind* binding_kind,
965b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                                 AstNodeFactory<AstNullVisitor>* factory) {
966e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(binding_kind != NULL);
967ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (already_resolved() && is_with_scope()) {
968ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Short-cut: if the scope is deserialized from a scope info, variable
969ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // allocation is already fixed.  We can simply return with dynamic lookup.
970ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    *binding_kind = DYNAMIC_LOOKUP;
971ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return NULL;
972ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
973ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
97443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Try to find the variable in this scope.
975248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  Variable* var = LookupLocal(proxy->raw_name());
97643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
977394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // We found a variable and we are done. (Even if there is an 'eval' in
978394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // this scope which introduces the same variable again, the resulting
979394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // variable remains the same.)
98043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (var != NULL) {
981394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    *binding_kind = BOUND;
982394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return var;
98343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
98443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
985394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // We did not find a variable locally. Check against the function variable,
986394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // if any. We can do this for all scopes, since the function variable is
987394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // only present - if at all - for function scopes.
988394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  *binding_kind = UNBOUND;
989248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  var = LookupFunctionVar(proxy->raw_name(), factory);
99027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  if (var != NULL) {
991394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    *binding_kind = BOUND;
992394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  } else if (outer_scope_ != NULL) {
993248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    var = outer_scope_->LookupRecursive(proxy, binding_kind, factory);
994c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) {
995c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      var->ForceContextAllocation();
996c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
99727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  } else {
998e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_global_scope());
999394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
1000394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1001394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (is_with_scope()) {
1002e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!already_resolved());
1003394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // The current scope is a with scope, so the variable binding can not be
1004394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // statically resolved. However, note that it was necessary to do a lookup
1005394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // in the outer scope anyway, because if a binding exists in an outer scope,
1006394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // the associated variable has to be marked as potentially being accessed
1007394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // from inside of an inner with scope (the property may not be in the 'with'
1008394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // object).
1009248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    if (var != NULL && proxy->is_assigned()) var->set_maybe_assigned();
1010394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    *binding_kind = DYNAMIC_LOOKUP;
1011394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return NULL;
1012486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  } else if (calls_sloppy_eval()) {
1013394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // A variable binding may have been found in an outer scope, but the current
1014486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // scope makes a sloppy 'eval' call, so the found variable may not be
1015394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // the correct one (the 'eval' may introduce a binding with the same name).
1016394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // In that case, change the lookup result to reflect this situation.
1017394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (*binding_kind == BOUND) {
1018394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      *binding_kind = BOUND_EVAL_SHADOWED;
1019394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } else if (*binding_kind == UNBOUND) {
1020394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      *binding_kind = UNBOUND_EVAL_SHADOWED;
1021394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
1022381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  }
102343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return var;
102443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
102543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
102643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1027bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.combool Scope::ResolveVariable(CompilationInfo* info,
1028b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                            VariableProxy* proxy,
1029b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org                            AstNodeFactory<AstNullVisitor>* factory) {
1030e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(info->global_scope()->is_global_scope());
103143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
103243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the proxy is already resolved there's nothing to do
103343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // (functions and consts may be resolved by the parser).
1034bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (proxy->var() != NULL) return true;
103543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
103643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Otherwise, try to resolve the variable.
1037394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  BindingKind binding_kind;
1038248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  Variable* var = LookupRecursive(proxy, &binding_kind, factory);
1039394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  switch (binding_kind) {
1040394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case BOUND:
1041394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // We found a variable binding.
1042394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      break;
104343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1044394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case BOUND_EVAL_SHADOWED:
104528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      // We either found a variable binding that might be shadowed by eval  or
104628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      // gave up on it (e.g. by encountering a local with the same in the outer
104728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      // scope which was not promoted to a context, this can happen if we use
104828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      // debugger to evaluate arbitrary expressions at a break point).
1049355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      if (var->IsGlobalObjectProperty()) {
105008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org        var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL);
105128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      } else if (var->is_dynamic()) {
105208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org        var = NonLocal(proxy->raw_name(), DYNAMIC);
1053394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      } else {
1054394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        Variable* invalidated = var;
105508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org        var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL);
1056394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        var->set_local_if_not_shadowed(invalidated);
1057394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
1058394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      break;
1059381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
1060394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case UNBOUND:
106146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      // No binding has been found. Declare a variable on the global object.
106208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      var = info->global_scope()->DeclareDynamicGlobal(proxy->raw_name());
1063394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      break;
1064381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
1065394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case UNBOUND_EVAL_SHADOWED:
1066486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      // No binding has been found. But some scope makes a sloppy 'eval' call.
106708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL);
1068394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      break;
1069381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
1070394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case DYNAMIC_LOOKUP:
1071394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // The variable could not be resolved statically.
107208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      var = NonLocal(proxy->raw_name(), DYNAMIC);
1073394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      break;
107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
107543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1076e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(var != NULL);
1077248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  if (proxy->is_assigned()) var->set_maybe_assigned();
1078bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1079486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (FLAG_harmony_scoping && strict_mode() == STRICT &&
1080248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org      var->is_const_mode() && proxy->is_assigned()) {
1081a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // Assignment to const. Throw a syntax error.
1082a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    MessageLocation location(
1083a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        info->script(), proxy->position(), proxy->position());
10843d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    Isolate* isolate = info->isolate();
1085a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Factory* factory = isolate->factory();
1086a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Handle<JSArray> array = factory->NewJSArray(0);
1087ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    Handle<Object> error;
1088ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    MaybeHandle<Object> maybe_error =
1089a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        factory->NewSyntaxError("harmony_const_assign", array);
1090ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    if (maybe_error.ToHandle(&error)) isolate->Throw(*error, &location);
1091a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return false;
1092a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
1093a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1094bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (FLAG_harmony_modules) {
1095bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    bool ok;
1096bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
109708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    if (FLAG_print_interface_details) {
109808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      PrintF("# Resolve %.*s:\n", var->raw_name()->length(),
109908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org             var->raw_name()->raw_data());
110008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    }
1101bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
11027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    proxy->interface()->Unify(var->interface(), zone(), &ok);
1103bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (!ok) {
1104bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#ifdef DEBUG
1105bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      if (FLAG_print_interfaces) {
1106bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("SCOPES TYPE ERROR\n");
1107bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("proxy: ");
1108bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        proxy->interface()->Print();
1109bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        PrintF("var: ");
1110bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        var->interface()->Print();
1111bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      }
1112bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com#endif
1113bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1114bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      // Inconsistent use of module. Throw a syntax error.
1115bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      // TODO(rossberg): generate more helpful error message.
1116a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      MessageLocation location(
1117a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          info->script(), proxy->position(), proxy->position());
11183d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      Isolate* isolate = info->isolate();
1119bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      Factory* factory = isolate->factory();
1120bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      Handle<JSArray> array = factory->NewJSArray(1);
11219e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      JSObject::SetElement(array, 0, var->name(), NONE, STRICT).Assert();
1122ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      Handle<Object> error;
1123ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      MaybeHandle<Object> maybe_error =
1124bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com          factory->NewSyntaxError("module_type_error", array);
1125ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      if (maybe_error.ToHandle(&error)) isolate->Throw(*error, &location);
1126bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      return false;
1127bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    }
1128bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  }
1129bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
11308e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  proxy->BindTo(var);
11318e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
1132bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  return true;
113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
113443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1136bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.combool Scope::ResolveVariablesRecursively(
1137bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    CompilationInfo* info,
1138b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    AstNodeFactory<AstNullVisitor>* factory) {
1139e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(info->global_scope()->is_global_scope());
114043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
114143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Resolve unresolved variables for this scope.
114243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < unresolved_.length(); i++) {
1143bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (!ResolveVariable(info, unresolved_[i], factory)) return false;
114443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
114543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
114643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Resolve unresolved variables for inner scopes.
114743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < inner_scopes_.length(); i++) {
1148bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory))
1149bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com      return false;
115043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1151bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1152bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  return true;
115343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1156248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.orgvoid Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) {
1157486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (outer_scope_calls_sloppy_eval) {
1158486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    outer_scope_calls_sloppy_eval_ = true;
115983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
116083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1161486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  bool calls_sloppy_eval =
1162486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_;
116343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < inner_scopes_.length(); i++) {
1164248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    Scope* inner = inner_scopes_[i];
1165248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    inner->PropagateScopeInfo(calls_sloppy_eval);
1166248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) {
116743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      inner_scope_calls_eval_ = true;
116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1169248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    if (inner->force_eager_compilation_) {
117043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      force_eager_compilation_ = true;
117143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1172a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    if (asm_module_ && inner->scope_type() == FUNCTION_SCOPE) {
1173a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      inner->asm_function_ = true;
1174a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    }
117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
117643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Scope::MustAllocate(Variable* var) {
118068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // Give var a read/write use if there is a chance it might be accessed
118168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // via an eval() call.  This is only possible if the variable has a
118268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // visible name.
118308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
1184c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      (var->has_forced_context_allocation() ||
11854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org       scope_calls_eval_ ||
11864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org       inner_scope_calls_eval_ ||
11874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org       scope_contains_with_ ||
11884acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org       is_catch_scope() ||
118981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org       is_block_scope() ||
1190355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org       is_module_scope() ||
1191355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org       is_global_scope())) {
1192248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    var->set_is_used();
1193248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org    if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned();
119443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
119568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // Global variables do not need to be allocated.
1196355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  return !var->IsGlobalObjectProperty() && var->is_used();
119743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
119843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
119943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
120043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Scope::MustAllocateInContext(Variable* var) {
12014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // If var is accessed from an inner scope, or if there is a possibility
12024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // that it might be accessed from the current or an inner scope (through
12034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // an eval() call or a runtime with lookup), it must be allocated in the
120468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // context.
12054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  //
1206e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Exceptions: If the scope as a whole has forced context allocation, all
1207e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // variables will have context allocation, even temporaries.  Otherwise
1208e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // temporary variables are always stack-allocated.  Catch-bound variables are
1209e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // always context-allocated.
1210e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (has_forced_context_allocation()) return true;
1211b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  if (var->mode() == TEMPORARY) return false;
12128e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (var->mode() == INTERNAL) return true;
1213ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  if (is_catch_scope() || is_block_scope() || is_module_scope()) return true;
1214355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (is_global_scope() && IsLexicalVariableMode(var->mode())) return true;
1215c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return var->has_forced_context_allocation() ||
12164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      scope_calls_eval_ ||
12174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      inner_scope_calls_eval_ ||
1218355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      scope_contains_with_;
121943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
122043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
122143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
122243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Scope::HasArgumentsParameter() {
122343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < params_.length(); i++) {
122484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    if (params_[i]->name().is_identical_to(
12254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org            isolate_->factory()->arguments_string())) {
122643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return true;
122784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    }
122843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
122943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
123043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
123143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Scope::AllocateStackSlot(Variable* var) {
1234486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  var->AllocateTo(Variable::LOCAL, num_stack_slots_++);
123543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
123643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Scope::AllocateHeapSlot(Variable* var) {
1239486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  var->AllocateTo(Variable::CONTEXT, num_heap_slots_++);
124043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
124143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Scope::AllocateParameterLocals() {
1244e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_function_scope());
124508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Variable* arguments = LookupLocal(ast_value_factory_->arguments_string());
1246e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(arguments != NULL);  // functions have 'arguments' declared implicitly
12474d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
1248486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  bool uses_sloppy_arguments = false;
12494d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (MustAllocate(arguments) && !HasArgumentsParameter()) {
125143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // 'arguments' is used. Unless there is also a parameter called
12527b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // 'arguments', we must be conservative and allocate all parameters to
12537b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // the context assuming they will be captured by the arguments object.
12547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // If we have a parameter named 'arguments', a (new) value is always
12557b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // assigned to it via the function invocation. Then 'arguments' denotes
12567b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // that specific parameter value and cannot be used to access the
12577b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // parameters, which is why we don't need to allocate an arguments
12587b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // object in that case.
125943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
126043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // We are using 'arguments'. Tell the code generator that is needs to
126143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // allocate the arguments object by setting 'arguments_'.
12624a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    arguments_ = arguments;
126343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12644d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    // In strict mode 'arguments' does not alias formal parameters.
12654d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    // Therefore in strict mode we allocate parameters as if 'arguments'
12664d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    // were not used.
1267486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    uses_sloppy_arguments = strict_mode() == SLOPPY;
12687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
12697b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
12707b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // The same parameter may occur multiple times in the parameters_ list.
12717b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // If it does, and if it is not copied into the context object, it must
12727b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // receive the highest parameter index for that parameter; thus iteration
12737b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // order is relevant!
12747b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  for (int i = params_.length() - 1; i >= 0; --i) {
12757b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    Variable* var = params_[i];
1276e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(var->scope() == this);
1277a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    if (uses_sloppy_arguments || has_forced_context_allocation()) {
1278c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // Force context allocation of the parameter.
1279c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      var->ForceContextAllocation();
128043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
128143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12827b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (MustAllocate(var)) {
12837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      if (MustAllocateInContext(var)) {
1284e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(var->IsUnallocated() || var->IsContextSlot());
1285486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        if (var->IsUnallocated()) {
12867b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          AllocateHeapSlot(var);
12877b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        }
12887b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      } else {
1289e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(var->IsUnallocated() || var->IsParameter());
1290486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        if (var->IsUnallocated()) {
1291486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          var->AllocateTo(Variable::PARAMETER, i);
129243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
129343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
129443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
129543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
129643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
129743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
129843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
129943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Scope::AllocateNonParameterLocal(Variable* var) {
1300e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(var->scope() == this);
1301e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!var->IsVariable(isolate_->factory()->dot_result_string()) ||
1302486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org         !var->IsStackLocal());
1303486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (var->IsUnallocated() && MustAllocate(var)) {
130443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (MustAllocateInContext(var)) {
130543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      AllocateHeapSlot(var);
130643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
130743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      AllocateStackSlot(var);
130843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
130943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
131043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
131143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
131243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
131343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Scope::AllocateNonParameterLocals() {
131468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // All variables that have no rewrite yet are non-parameter locals.
131543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < temps_.length(); i++) {
131643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    AllocateNonParameterLocal(temps_[i]);
131743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
131843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13198e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  for (int i = 0; i < internals_.length(); i++) {
13208e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    AllocateNonParameterLocal(internals_[i]);
13218e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
132246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
13238e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
132468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  for (VariableMap::Entry* p = variables_.Start();
132568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org       p != NULL;
132668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org       p = variables_.Next(p)) {
132743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Variable* var = reinterpret_cast<Variable*>(p->value);
132846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    vars.Add(VarAndOrder(var, p->order), zone());
132946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
133046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  vars.Sort(VarAndOrder::Compare);
133146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  int var_count = vars.length();
133246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  for (int i = 0; i < var_count; i++) {
133346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    AllocateNonParameterLocal(vars[i].var());
133443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
133543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
133668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // For now, function_ must be allocated at the very end.  If it gets
133768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // allocated in the context, it must be the last slot in the context,
133868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // because of the current ScopeInfo implementation (see
133943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
134043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (function_ != NULL) {
1341ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    AllocateNonParameterLocal(function_->proxy()->var());
134243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
134343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
134443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
134543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
134643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Scope::AllocateVariablesRecursively() {
134743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate variables for inner scopes.
134843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < inner_scopes_.length(); i++) {
134943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    inner_scopes_[i]->AllocateVariablesRecursively();
135043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
135143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1352c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // If scope is already resolved, we still need to allocate
1353c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // variables in inner scopes which might not had been resolved yet.
13544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (already_resolved()) return;
1355c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // The number of slots required for variables.
1356c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  num_stack_slots_ = 0;
1357c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
1358c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
135943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate variables for this scope.
136043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Parameters must be allocated first, if any.
136143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (is_function_scope()) AllocateParameterLocals();
136243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  AllocateNonParameterLocals();
136343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1364c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Force allocation of a context for this scope if necessary. For a 'with'
1365c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // scope and for a function scope that makes an 'eval' call we need a context,
1366c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // even if no local variables were statically allocated in the scope.
1367ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  // Likewise for modules.
1368ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  bool must_have_context = is_with_scope() || is_module_scope() ||
1369c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      (is_function_scope() && calls_eval());
137043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
137143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If we didn't allocate any locals in the local context, then we only
1372c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // need the minimal number of slots if we must have a context.
1373c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
137443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    num_heap_slots_ = 0;
137543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
137643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
137743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocation done.
1378e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
137943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
138043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1381c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
13828e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgvoid Scope::AllocateModulesRecursively(Scope* host_scope) {
13838e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (already_resolved()) return;
138481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  if (is_module_scope()) {
1385e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(interface_->IsFrozen());
1386e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(module_var_ == NULL);
138708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    module_var_ =
138808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org        host_scope->NewInternal(ast_value_factory_->dot_module_string());
13898e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    ++host_scope->num_modules_;
139081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  }
139181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
139281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  for (int i = 0; i < inner_scopes_.length(); i++) {
139381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    Scope* inner_scope = inner_scopes_.at(i);
13948e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    inner_scope->AllocateModulesRecursively(host_scope);
139581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  }
139681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org}
139781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
139881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
13998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgint Scope::StackLocalCount() const {
14008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return num_stack_slots() -
14018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0);
14028e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
140381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
140481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
14058e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgint Scope::ContextLocalCount() const {
14068e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (num_heap_slots() == 0) return 0;
14078e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
14088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
140981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org}
141081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
141143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
1412