18b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Copyright 2011 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_VARIABLES_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_VARIABLES_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "zone.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The AST refers to variables via VariableProxies - placeholders for the actual
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// variables. Variables themselves are never directly referred to from the AST,
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// they are maintained by scopes, and referred to from VariableProxies and Slots
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// after binding and variable allocation.
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Variable: public ZoneObject {
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Mode {
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // User declared variables:
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    VAR,       // declared via 'var', and 'function' declarations
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CONST,     // declared via 'const' declarations
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Variables introduced by the compiler:
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    DYNAMIC,         // always require dynamic lookup (we don't know
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     // the declaration)
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    DYNAMIC_GLOBAL,  // requires dynamic lookup, but we know that the
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     // variable is global unless it has been shadowed
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     // by an eval-introduced variable
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    DYNAMIC_LOCAL,   // requires dynamic lookup, but we know that the
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     // variable is local and where it is unless it
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     // has been shadowed by an eval-introduced
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     // variable
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    INTERNAL,        // like VAR, but not user-visible (may or may not
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     // be in a context)
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    TEMPORARY        // temporary variables (not user-visible), never
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     // in a context
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Kind {
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    NORMAL,
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    THIS,
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ARGUMENTS
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Variable(Scope* scope,
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           Handle<String> name,
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           Mode mode,
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           bool is_valid_lhs,
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           Kind kind);
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Printing support
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const char* Mode2String(Mode mode);
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Type testing & conversion
850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Property* AsProperty() const;
860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Slot* AsSlot() const;
870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool IsValidLeftHandSide() { return is_valid_LHS_; }
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The source code for an eval() call may refer to a variable that is
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in an outer scope about which we don't know anything (it may not
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // be the global scope). scope() is NULL in that case. Currently the
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scope is only used to follow the context chain length.
940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Scope* scope() const { return scope_; }
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Handle<String> name() const { return name_; }
970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Mode mode() const { return mode_; }
980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  bool is_accessed_from_inner_scope() const {
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return is_accessed_from_inner_scope_;
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
101b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void MarkAsAccessedFromInnerScope() {
102b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    is_accessed_from_inner_scope_ = true;
103b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
1046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool is_used() { return is_used_; }
1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void set_is_used(bool flag) { is_used_ = flag; }
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool IsVariable(Handle<String> n) const {
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return !is_this() && name().is_identical_to(n);
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool IsStackAllocated() const;
112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsParameter() const;  // Includes 'this'.
113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsStackLocal() const;
114b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  bool IsContextSlot() const;
1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_dynamic() const {
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return (mode_ == DYNAMIC ||
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block            mode_ == DYNAMIC_GLOBAL ||
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block            mode_ == DYNAMIC_LOCAL);
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_global() const;
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_this() const { return kind_ == THIS; }
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_arguments() const { return kind_ == ARGUMENTS; }
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // True if the variable is named eval and not known to be shadowed.
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_possibly_eval() const {
12844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return IsVariable(FACTORY->eval_symbol()) &&
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        (mode_ == DYNAMIC || mode_ == DYNAMIC_GLOBAL);
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Variable* local_if_not_shadowed() const {
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(mode_ == DYNAMIC_LOCAL && local_if_not_shadowed_ != NULL);
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return local_if_not_shadowed_;
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_local_if_not_shadowed(Variable* local) {
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    local_if_not_shadowed_ = local;
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Expression* rewrite() const { return rewrite_; }
142b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void set_rewrite(Expression* expr) { rewrite_ = expr; }
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Scope* scope_;
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> name_;
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Mode mode_;
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Kind kind_;
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Variable* local_if_not_shadowed_;
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code generation.
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // rewrite_ is usually a Slot or a Property, but may be any expression.
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* rewrite_;
1551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Valid as a LHS? (const and this are not valid LHS, for example)
1571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool is_valid_LHS_;
1581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Usage info.
1601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool is_accessed_from_inner_scope_;  // set by variable resolver
1611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool is_used_;
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_VARIABLES_H_
168