13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_SCOPES_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_SCOPES_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ast.h"
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "zone.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
37f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochclass CompilationInfo;
38f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A hash map to support fast variable declaration and lookup.
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass VariableMap: public ZoneHashMap {
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VariableMap();
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual ~VariableMap();
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Variable* Declare(Scope* scope,
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    Handle<String> name,
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    VariableMode mode,
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    bool is_valid_lhs,
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    Variable::Kind kind,
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    InitializationFlag initialization_flag,
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    Interface* interface = Interface::NewValue());
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Variable* Lookup(Handle<String> name);
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The dynamic scope part holds hash maps for the variables that will
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be looked up dynamically from within eval and with scopes. The objects
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// are allocated on-demand from Scope::NonLocal to avoid wasting memory
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and setup time for scopes that don't need them.
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DynamicScopePart : public ZoneObject {
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  VariableMap* GetMap(VariableMode mode) {
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int index = mode - DYNAMIC;
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(index >= 0 && index < 3);
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return &maps_[index];
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VariableMap maps_[3];
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Global invariants after AST construction: Each reference (i.e. identifier)
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to a JavaScript variable (including global properties) is represented by a
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// VariableProxy node. Immediately after AST construction and before variable
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// corresponding variable (though some are bound during parse time). Variable
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// allocation binds each unresolved VariableProxy to one Variable and assigns
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// a location. Note that many VariableProxy nodes may refer to the same Java-
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Script variable.
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Scope: public ZoneObject {
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Construction
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Scope(Scope* outer_scope, ScopeType type);
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
92f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  // Compute top scope and allocate variables. For lazy compilation the top
93f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  // scope only contains the single lazily compiled function, so this
94f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  // doesn't re-allocate variables repeatedly.
95f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  static bool Analyze(CompilationInfo* info);
96f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Scope* DeserializeScopeChain(Context* context, Scope* global_scope);
9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The scope name is only used for printing/debugging.
100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetScopeName(Handle<String> scope_name) { scope_name_ = scope_name; }
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Initialize();
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
104589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Checks if the block scope is redundant, i.e. it does not contain any
105589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // block scoped declarations. In that case it is removed from the scope
106589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // tree and its children are reparented.
107589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Scope* FinalizeBlockScope();
108589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Declarations
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Lookup a variable in this scope. Returns the variable or NULL if not found.
1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Variable* LocalLookup(Handle<String> name);
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // This lookup corresponds to a lookup in the "intermediate" scope sitting
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // between this scope and the outer scope. (ECMA-262, 3rd., requires that
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the name of named function literal is kept in an intermediate scope
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // in between this scope and the next outer scope.)
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Variable* LookupFunctionVar(Handle<String> name,
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              AstNodeFactory<AstNullVisitor>* factory);
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Lookup a variable in this scope or outer scopes.
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the variable or NULL if not found.
1243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Variable* Lookup(Handle<String> name);
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Declare the function variable for a function literal. This variable
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is in an intermediate scope between this function scope and the the
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // outer scope. Only possible for function scopes; at most one variable.
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  template<class Visitor>
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Variable* DeclareFunctionVar(Handle<String> name,
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               VariableMode mode,
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               AstNodeFactory<Visitor>* factory) {
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(is_function_scope() && function_ == NULL);
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Variable* function_var = new Variable(
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        this, name, mode, true, Variable::NORMAL, kCreatedInitialized);
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    function_ = factory->NewVariableProxy(function_var);
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return function_var;
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Declare a parameter in this scope.  When there are duplicated
1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // parameters the rightmost one 'wins'.  However, the implementation
1423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // expects all parameters to be declared and from left to right.
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void DeclareParameter(Handle<String> name, VariableMode mode);
1443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Declare a local variable in this scope. If the variable has been
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // declared before, the previously declared variable is returned.
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Variable* DeclareLocal(Handle<String> name,
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         VariableMode mode,
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         InitializationFlag init_flag,
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         Interface* interface = Interface::NewValue());
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Declare an implicit global variable in this scope which must be a
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // global scope.  The variable was introduced (possibly from an inner
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope) by a reference to an unresolved variable with no intervening
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // with statements or eval calls.
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Variable* DeclareGlobal(Handle<String> name);
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create a new unresolved variable.
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  template<class Visitor>
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory,
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Handle<String> name,
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               int position = RelocInfo::kNoPosition,
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Interface* interface = Interface::NewValue()) {
1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Note that we must not share the unresolved variables with
1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // the same name because they may be removed selectively via
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // RemoveUnresolved().
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(!already_resolved());
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    VariableProxy* proxy =
1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        factory->NewVariableProxy(name, false, position, interface);
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    unresolved_.Add(proxy);
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return proxy;
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Remove a unresolved variable. During parsing, an unresolved variable
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // may have been added optimistically, but then only the variable name
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // was used (typically for labels). If the variable was not declared, the
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // addition introduced a new unresolved variable which may end up being
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // allocated globally as a "ghost" variable. RemoveUnresolved removes
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // such a variable again if it was added; otherwise this is a no-op.
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void RemoveUnresolved(VariableProxy* var);
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Creates a new temporary variable in this scope.  The name is only used
183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // for printing and cannot be used to find the variable.  In particular,
184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // the only way to get hold of the temporary is by keeping the Variable*
185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // around.
1863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Variable* NewTemporary(Handle<String> name);
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Adds the specific declaration node to the list of declarations in
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // this scope. The declarations are processed as part of entering
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the scope; see codegen.cc:ProcessDeclarations.
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AddDeclaration(Declaration* declaration);
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Illegal redeclaration support.
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set an expression node that will be executed when the scope is
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // entered. We only keep track of one illegal redeclaration node per
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope - the first one - so if you try to set it multiple times
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the additional requests will be silently ignored.
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetIllegalRedeclaration(Expression* expression);
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Visit the illegal redeclaration expression. Do not call if the
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope doesn't have an illegal redeclaration node.
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void VisitIllegalRedeclaration(AstVisitor* visitor);
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if the scope has (at least) one illegal redeclaration.
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool HasIllegalRedeclaration() const { return illegal_redecl_ != NULL; }
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
209589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // For harmony block scoping mode: Check if the scope has conflicting var
210589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // declarations, i.e. a var declaration that has been hoisted from a nested
211589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // scope over a let binding of the same name.
212589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Declaration* CheckConflictingVarDeclarations();
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // For harmony block scoping mode: Check if the scope has variable proxies
2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // that are used as lvalues and point to const variables. Assumes that scopes
2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // have been analyzed and variables been resolved.
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  VariableProxy* CheckAssignmentToConst();
2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Scope-specific info.
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Inform the scope that the corresponding code contains a with statement.
223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RecordWithStatement() { scope_contains_with_ = true; }
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Inform the scope that the corresponding code contains an eval call.
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RecordEvalCall() { if (!is_global_scope()) scope_calls_eval_ = true; }
227592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set the strict mode flag (unless disabled by a global flag).
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void SetLanguageMode(LanguageMode language_mode) {
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    language_mode_ = language_mode;
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Position in the source where this scope begins and ends.
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // * For the scope of a with statement
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //     with (obj) stmt
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   start position: start position of first token of 'stmt'
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   end position: end position of last token of 'stmt'
2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // * For the scope of a block
2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //     { stmts }
2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   start position: start position of '{'
2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   end position: end position of '}'
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // * For the scope of a function literal or decalaration
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //     function fun(a,b) { stmts }
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   start position: start position of '('
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   end position: end position of '}'
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // * For the scope of a catch block
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //     try { stms } catch(e) { stmts }
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   start position: start position of '('
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   end position: end position of ')'
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // * For the scope of a for-statement
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //     for (let x ...) stmt
2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   start position: start position of '('
2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   end position: end position of last token of 'stmt'
2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int start_position() const { return start_position_; }
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void set_start_position(int statement_pos) {
2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    start_position_ = statement_pos;
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int end_position() const { return end_position_; }
2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void set_end_position(int statement_pos) {
2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    end_position_ = statement_pos;
26244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Predicates.
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Specific scope types.
2680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  bool is_eval_scope() const { return type_ == EVAL_SCOPE; }
2690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  bool is_function_scope() const { return type_ == FUNCTION_SCOPE; }
2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool is_module_scope() const { return type_ == MODULE_SCOPE; }
2710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  bool is_global_scope() const { return type_ == GLOBAL_SCOPE; }
2723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool is_catch_scope() const { return type_ == CATCH_SCOPE; }
27369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  bool is_block_scope() const { return type_ == BLOCK_SCOPE; }
2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool is_with_scope() const { return type_ == WITH_SCOPE; }
2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool is_declaration_scope() const {
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return is_eval_scope() || is_function_scope() || is_global_scope();
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool is_classic_mode() const {
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return language_mode() == CLASSIC_MODE;
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool is_extended_mode() const {
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return language_mode() == EXTENDED_MODE;
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool is_strict_or_extended_eval_scope() const {
2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return is_eval_scope() && !is_classic_mode();
286257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Information about which scopes calls eval.
2890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  bool calls_eval() const { return scope_calls_eval_; }
2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool calls_non_strict_eval() {
2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return scope_calls_eval_ && is_classic_mode();
2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
293257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool outer_scope_calls_non_strict_eval() const {
294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return outer_scope_calls_non_strict_eval_;
295257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Is this scope inside a with statement.
2980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  bool inside_with() const { return scope_inside_with_; }
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Does this scope contain a with statement.
3000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  bool contains_with() const { return scope_contains_with_; }
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Accessors.
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The type of this scope.
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ScopeType type() const { return type_; }
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The language mode of this scope.
3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LanguageMode language_mode() const { return language_mode_; }
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // The variable corresponding the 'this' value.
3123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Variable* receiver() { return receiver_; }
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The variable holding the function literal for named function
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // literals, or NULL.
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Only valid for function scopes.
317589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  VariableProxy* function() const {
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(is_function_scope());
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return function_;
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Parameters. The left-most parameter has index 0.
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Only valid for function scopes.
3240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Variable* parameter(int index) const {
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(is_function_scope());
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return params_[index];
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int num_parameters() const { return params_.length(); }
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The local variable 'arguments' if we need to allocate it; NULL otherwise.
3320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Variable* arguments() const { return arguments_; }
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Declarations list.
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Declaration*>* declarations() { return &decls_; }
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Inner scope list.
3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Scope*>* inner_scopes() { return &inner_scopes_; }
3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The scope immediately surrounding this scope, or NULL.
3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Scope* outer_scope() const { return outer_scope_; }
3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The interface as inferred so far; only for module scopes.
3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Interface* interface() const { return interface_; }
3455d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Variable allocation.
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Collect stack and context allocated local variables in this scope. Note
3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // that the function variable - if present - is not collected and should be
3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // handled separately.
3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    ZoneList<Variable*>* context_locals);
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
355053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  // Current number of var or const locals.
356053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  int num_var_or_const() { return num_var_or_const_; }
357053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Result of variable allocation.
3590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int num_stack_slots() const { return num_stack_slots_; }
3600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int num_heap_slots() const { return num_heap_slots_; }
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int StackLocalCount() const;
3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int ContextLocalCount() const;
3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure this scope and all outer scopes are eagerly compiled.
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ForceEagerCompilation()  { force_eager_compilation_ = true; }
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Determine if we can use lazy compilation for this scope.
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool AllowsLazyCompilation() const;
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // True if we can lazily recompile functions with this scope.
3724768e9d22b13edbae2ae177109420028748bf872Ben Murdoch  bool AllowsLazyRecompilation() const;
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // True if the outer context of this scope is always the global context.
3753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool HasTrivialOuterContext() const;
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3774768e9d22b13edbae2ae177109420028748bf872Ben Murdoch  // True if this scope is inside a with scope and all declaration scopes
3784768e9d22b13edbae2ae177109420028748bf872Ben Murdoch  // between them have empty contexts. Such declaration scopes become
3794768e9d22b13edbae2ae177109420028748bf872Ben Murdoch  // invisible during scope info deserialization.
3804768e9d22b13edbae2ae177109420028748bf872Ben Murdoch  bool TrivialDeclarationScopesBeforeWithScope() const;
3814768e9d22b13edbae2ae177109420028748bf872Ben Murdoch
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The number of contexts between this and scope; zero if this == scope.
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int ContextChainLength(Scope* scope);
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Find the first function, global, or eval scope.  This is the scope
3863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // where var declarations will be hoisted to in the implementation.
3873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Scope* DeclarationScope();
3883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<ScopeInfo> GetScopeInfo();
3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Get the chain of nested scopes within this scope for the source statement
3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // position. The scopes will be added to the list from the outermost scope to
3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the innermost scope. Only nested block, catch or with scopes are tracked
3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // and will be returned, but no inner function scopes.
3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void GetNestedScopeChain(List<Handle<ScopeInfo> >* chain,
3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           int statement_position);
39769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
3991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Strict mode support.
4001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool IsDeclared(Handle<String> name) {
4011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // During formal parameter list parsing the scope only contains
4021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // two variables inserted at initialization: "this" and "arguments".
4031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // "this" is an invalid parameter name and "arguments" is invalid parameter
4041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // name in strict mode. Therefore looking up with the map which includes
4051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // "this" and "arguments" in addition to all formal parameters is safe.
4061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return variables_.Lookup(name) != NULL;
4071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
4081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // ---------------------------------------------------------------------------
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Debugging.
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Print(int n = 0);  // n = indentation; n < 0 => don't print recursively
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Implementation.
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected:
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class ParserFactory;
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Isolate* const isolate_;
4223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Scope tree.
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Scope* outer_scope_;  // the immediately enclosing outer scope, or NULL
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Scope*> inner_scopes_;  // the immediately enclosed inner scopes
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The scope type.
4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ScopeType type_;
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Debugging support.
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> scope_name_;
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The variables declared in this scope:
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // All user-declared variables (incl. parameters).  For global scopes
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // variables may be implicitly 'declared' by being used (possibly in
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // an inner scope) with no intervening with statements or eval calls.
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VariableMap variables_;
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compiler-allocated (user-invisible) temporaries.
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Variable*> temps_;
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Parameter list in source order.
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Variable*> params_;
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Variables that must be looked up dynamically.
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DynamicScopePart* dynamics_;
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Unresolved variables referred to from this scope.
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<VariableProxy*> unresolved_;
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Declarations.
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Declaration*> decls_;
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convenience variable.
450e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Variable* receiver_;
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Function variable, if any; function scopes only.
452589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  VariableProxy* function_;
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convenience variable; function scopes only.
4540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Variable* arguments_;
4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Interface; module scopes only.
4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Interface* interface_;
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Illegal redeclaration.
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* illegal_redecl_;
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Scope-specific information computed during parsing.
46269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  //
46369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // This scope is inside a 'with' of some outer scope.
46469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  bool scope_inside_with_;
46569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // This scope contains a 'with' statement.
46669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  bool scope_contains_with_;
46769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // This scope or a nested catch scope or with scope contain an 'eval' call. At
46869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // the 'eval' call site this scope is the declaration scope.
46969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  bool scope_calls_eval_;
4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The language mode of this scope.
4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LanguageMode language_mode_;
4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Source positions.
4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int start_position_;
4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int end_position_;
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Computed via PropagateScopeInfo.
477257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool outer_scope_calls_non_strict_eval_;
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool inner_scope_calls_eval_;
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool force_eager_compilation_;
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // True if it doesn't need scope resolution (e.g., if the scope was
4823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // constructed based on a serialized scope info or a catch context).
4833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool already_resolved_;
4843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
485053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  // Computed as variables are declared.
486053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  int num_var_or_const_;
487053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block
4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Computed via AllocateVariables; function, block and catch scopes only.
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int num_stack_slots_;
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int num_heap_slots_;
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Serialized scope info support.
4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<ScopeInfo> scope_info_;
4943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool already_resolved() { return already_resolved_; }
495b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create a non-local variable with a given name.
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // These variables are looked up dynamically at runtime.
4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Variable* NonLocal(Handle<String> name, VariableMode mode);
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Variable resolution.
5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Possible results of a recursive variable lookup telling if and how a
5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // variable is bound. These are returned in the output parameter *binding_kind
5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // of the LookupRecursive function.
5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum BindingKind {
5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // The variable reference could be statically resolved to a variable binding
5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // which is returned. There is no 'with' statement between the reference and
5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // the binding and no scope between the reference scope (inclusive) and
5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // binding scope (exclusive) makes a non-strict 'eval' call.
5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    BOUND,
5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // The variable reference could be statically resolved to a variable binding
5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // which is returned. There is no 'with' statement between the reference and
5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // the binding, but some scope between the reference scope (inclusive) and
5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // binding scope (exclusive) makes a non-strict 'eval' call, that might
5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // possibly introduce variable bindings shadowing the found one. Thus the
5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // found variable binding is just a guess.
5173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    BOUND_EVAL_SHADOWED,
5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // The variable reference could not be statically resolved to any binding
5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // and thus should be considered referencing a global variable. NULL is
5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // returned. The variable reference is not inside any 'with' statement and
5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // no scope between the reference scope (inclusive) and global scope
5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // (exclusive) makes a non-strict 'eval' call.
5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    UNBOUND,
5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // The variable reference could not be statically resolved to any binding
5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // NULL is returned. The variable reference is not inside any 'with'
5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // statement, but some scope between the reference scope (inclusive) and
5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // global scope (exclusive) makes a non-strict 'eval' call, that might
5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // possibly introduce a variable binding. Thus the reference should be
5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // considered referencing a global variable unless it is shadowed by an
5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // 'eval' introduced binding.
5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    UNBOUND_EVAL_SHADOWED,
5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // The variable could not be statically resolved and needs to be looked up
5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // dynamically. NULL is returned. There are two possible reasons:
5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // * A 'with' statement has been encountered and there is no variable
5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    //   binding for the name between the variable reference and the 'with'.
5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    //   The variable potentially references a property of the 'with' object.
5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // * The code is being executed as part of a call to 'eval' and the calling
5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    //   context chain contains either a variable binding for the name or it
5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    //   contains a 'with' context.
5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    DYNAMIC_LOOKUP
5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Lookup a variable reference given by name recursively starting with this
5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // scope. If the code is executed because of a call to 'eval', the context
5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // parameter should be set to the calling context of 'eval'.
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Variable* LookupRecursive(Handle<String> name,
5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            BindingKind* binding_kind,
5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            AstNodeFactory<AstNullVisitor>* factory);
5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT
5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool ResolveVariable(CompilationInfo* info,
5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       VariableProxy* proxy,
5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       AstNodeFactory<AstNullVisitor>* factory);
5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT
5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool ResolveVariablesRecursively(CompilationInfo* info,
5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   AstNodeFactory<AstNullVisitor>* factory);
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Scope analysis.
5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool PropagateScopeInfo(bool outer_scope_calls_non_strict_eval);
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool HasTrivialContext() const;
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Predicates.
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool MustAllocate(Variable* var);
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool MustAllocateInContext(Variable* var);
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool HasArgumentsParameter();
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Variable allocation.
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateStackSlot(Variable* var);
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateHeapSlot(Variable* var);
572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateParameterLocals();
573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateNonParameterLocal(Variable* var);
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateNonParameterLocals();
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateVariablesRecursively();
576b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Resolve and fill in the allocation information for all variables
5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // in this scopes. Must be called *after* all scopes have been
5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // processed (parsed) to ensure that unresolved variables can be
5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // resolved properly.
5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //
5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // In the case of code compiled and run using 'eval', the context
5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // parameter is the context in which eval was called.  In all other
5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // cases the context parameter is an empty handle.
5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT
5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool AllocateVariables(CompilationInfo* info,
5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         AstNodeFactory<AstNullVisitor>* factory);
5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
589b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private:
5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Construct a scope based on the scope info.
5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Scope(Scope* inner_scope, ScopeType type, Handle<ScopeInfo> scope_info);
592b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Construct a catch scope with a binding for the name.
5943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Scope(Scope* inner_scope, Handle<String> catch_variable_name);
5953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
59644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void AddInnerScope(Scope* inner_scope) {
59744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (inner_scope != NULL) {
59844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      inner_scopes_.Add(inner_scope);
59944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      inner_scope->outer_scope_ = this;
60044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
60144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
60244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void SetDefaults(ScopeType type,
604b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                   Scope* outer_scope,
6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   Handle<ScopeInfo> scope_info);
606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_SCOPES_H_
611