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