144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef V8_VARIABLES_H_ 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define V8_VARIABLES_H_ 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org#include "src/ast-value-factory.h" 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/interface.h" 104b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/zone.h" 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The AST refers to variables via VariableProxies - placeholders for the actual 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// variables. Variables themselves are never directly referred to from the AST, 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// they are maintained by scopes, and referred to from VariableProxies and Slots 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// after binding and variable allocation. 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Variable: public ZoneObject { 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 223e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org enum Kind { 233e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org NORMAL, 243e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org THIS, 253e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org ARGUMENTS 263e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org }; 273e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 28486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org enum Location { 29486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Before and during variable allocation, a variable whose location is 30486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // not yet determined. After allocation, a variable looked up as a 31486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // property on the global object (and possibly absent). name() is the 32486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // variable name, index() is invalid. 33486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org UNALLOCATED, 34486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 35486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // A slot in the parameter section on the stack. index() is the 3646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // parameter index, counting left-to-right. The receiver is index -1; 37486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // the first parameter is index 0. 38486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org PARAMETER, 39486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 40486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // A slot in the local section on the stack. index() is the variable 41486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // index in the stack frame, starting at 0. 42486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org LOCAL, 43486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 44486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // An indexed slot in a heap context. index() is the variable index in 45486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // the context object on the heap, starting at 0. scope() is the 46486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // corresponding scope. 47486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org CONTEXT, 48486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 49486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // A named slot in a heap context. name() is the variable name in the 50486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // context object on the heap, with lookup starting at the current 51486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // context. index() is invalid. 52486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org LOOKUP 53486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org }; 54486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Variable(Scope* scope, const AstRawString* name, VariableMode mode, 567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool is_valid_ref, Kind kind, InitializationFlag initialization_flag, 577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, 58bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Interface* interface = Interface::NewValue()); 5968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Printing support 61b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org static const char* Mode2String(VariableMode mode); 6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 634edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org bool IsValidReference() { return is_valid_ref_; } 6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The source code for an eval() call may refer to a variable that is 6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // in an outer scope about which we don't know anything (it may not 6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // be the global scope). scope() is NULL in that case. Currently the 6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // scope is only used to follow the context chain length. 694a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Scope* scope() const { return scope_; } 70b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org 7108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org Handle<String> name() const { return name_->string(); } 7208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* raw_name() const { return name_; } 73b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org VariableMode mode() const { return mode_; } 74c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org bool has_forced_context_allocation() const { 75c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return force_context_allocation_; 7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 77c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void ForceContextAllocation() { 78e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(mode_ != TEMPORARY); 79c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org force_context_allocation_ = true; 80c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } 81ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org bool is_used() { return is_used_; } 82248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org void set_is_used() { is_used_ = true; } 837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org MaybeAssignedFlag maybe_assigned() const { return maybe_assigned_; } 847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void set_maybe_assigned() { maybe_assigned_ = kMaybeAssigned; } 8543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 86c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org int initializer_position() { return initializer_position_; } 87c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org void set_initializer_position(int pos) { initializer_position_ = pos; } 88c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 89c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org bool IsVariable(Handle<String> n) const { 9043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return !is_this() && name().is_identical_to(n); 9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 93486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org bool IsUnallocated() const { return location_ == UNALLOCATED; } 94486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org bool IsParameter() const { return location_ == PARAMETER; } 95486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org bool IsStackLocal() const { return location_ == LOCAL; } 96486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org bool IsStackAllocated() const { return IsParameter() || IsStackLocal(); } 97486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org bool IsContextSlot() const { return location_ == CONTEXT; } 98486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org bool IsLookupSlot() const { return location_ == LOOKUP; } 99355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bool IsGlobalObjectProperty() const; 100ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 101355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bool is_dynamic() const { return IsDynamicVariableMode(mode_); } 102355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bool is_const_mode() const { return IsImmutableVariableMode(mode_); } 103394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool binding_needs_init() const { 104c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return initialization_flag_ == kNeedsInitialization; 105394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 106381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1073e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org bool is_this() const { return kind_ == THIS; } 1083e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org bool is_arguments() const { return kind_ == ARGUMENTS; } 10943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 110c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // True if the variable is named eval and not known to be shadowed. 111fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org bool is_possibly_eval(Isolate* isolate) const { 1124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return IsVariable(isolate->factory()->eval_string()); 113c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org } 114c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 115381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org Variable* local_if_not_shadowed() const { 116e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(mode_ == DYNAMIC_LOCAL && local_if_not_shadowed_ != NULL); 117381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return local_if_not_shadowed_; 118381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 119381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 120381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org void set_local_if_not_shadowed(Variable* local) { 121381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org local_if_not_shadowed_ = local; 122381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 123381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 124486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Location location() const { return location_; } 125486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org int index() const { return index_; } 126c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org InitializationFlag initialization_flag() const { 127c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return initialization_flag_; 128c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 129bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Interface* interface() const { return interface_; } 130486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 131486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org void AllocateTo(Location location, int index) { 132486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org location_ = location; 133486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org index_ = index; 134486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 13543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 136c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org static int CompareIndex(Variable* const* v, Variable* const* w); 137c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 13843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 13943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Scope* scope_; 14008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org const AstRawString* name_; 141b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org VariableMode mode_; 1423e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org Kind kind_; 143486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Location location_; 144486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org int index_; 145c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org int initializer_position_; 14643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 147394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // If this field is set, this variable references the stored locally bound 148394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // variable, but it might be shadowed by variable bindings introduced by 149486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // sloppy 'eval' calls between the reference scope (inclusive) and the 150394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // binding scope (exclusive). 151381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org Variable* local_if_not_shadowed_; 152381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1534edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org // Valid as a reference? (const and this are not valid, for example) 1544edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org bool is_valid_ref_; 155378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 156378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Usage info. 157c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org bool force_context_allocation_; // set by variable resolver 158378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org bool is_used_; 159c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org InitializationFlag initialization_flag_; 1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org MaybeAssignedFlag maybe_assigned_; 161bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com 162bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Module type info. 163bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com Interface* interface_; 16443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 16543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 16843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif // V8_VARIABLES_H_ 170