OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_AST_VARIABLES_H_ | 5 #ifndef V8_AST_VARIABLES_H_ |
6 #define V8_AST_VARIABLES_H_ | 6 #define V8_AST_VARIABLES_H_ |
7 | 7 |
8 #include "src/ast/ast-value-factory.h" | 8 #include "src/ast/ast-value-factory.h" |
9 #include "src/zone.h" | 9 #include "src/zone.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 | 13 |
14 // The AST refers to variables via VariableProxies - placeholders for the actual | 14 // The AST refers to variables via VariableProxies - placeholders for the actual |
15 // variables. Variables themselves are never directly referred to from the AST, | 15 // variables. Variables themselves are never directly referred to from the AST, |
16 // they are maintained by scopes, and referred to from VariableProxies and Slots | 16 // they are maintained by scopes, and referred to from VariableProxies and Slots |
17 // after binding and variable allocation. | 17 // after binding and variable allocation. |
18 class Variable final : public ZoneObject { | 18 class Variable final : public ZoneObject { |
19 public: | 19 public: |
20 enum Kind { NORMAL, FUNCTION, THIS, ARGUMENTS }; | 20 enum Kind : uint8_t { |
21 NORMAL, | |
22 FUNCTION, | |
23 THIS, | |
24 ARGUMENTS, | |
25 kLastKind = ARGUMENTS | |
26 }; | |
21 | 27 |
22 Variable(Scope* scope, const AstRawString* name, VariableMode mode, Kind kind, | 28 Variable(Scope* scope, const AstRawString* name, VariableMode mode, Kind kind, |
23 InitializationFlag initialization_flag, | 29 InitializationFlag initialization_flag, |
24 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned); | 30 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned); |
25 | 31 |
26 // Printing support | 32 // Printing support |
27 static const char* Mode2String(VariableMode mode); | 33 static const char* Mode2String(VariableMode mode); |
28 | 34 |
29 // The source code for an eval() call may refer to a variable that is | 35 // The source code for an eval() call may refer to a variable that is |
30 // in an outer scope about which we don't know anything (it may not | 36 // in an outer scope about which we don't know anything (it may not |
31 // be the script scope). scope() is NULL in that case. Currently the | 37 // be the script scope). scope() is NULL in that case. Currently the |
32 // scope is only used to follow the context chain length. | 38 // scope is only used to follow the context chain length. |
33 Scope* scope() const { return scope_; } | 39 Scope* scope() const { return scope_; } |
34 | 40 |
35 // This is for adjusting the scope of temporaries used when desugaring | 41 // This is for adjusting the scope of temporaries used when desugaring |
36 // parameter initializers. | 42 // parameter initializers. |
37 void set_scope(Scope* scope) { scope_ = scope; } | 43 void set_scope(Scope* scope) { scope_ = scope; } |
38 | 44 |
39 Handle<String> name() const { return name_->string(); } | 45 Handle<String> name() const { return name_->string(); } |
40 const AstRawString* raw_name() const { return name_; } | 46 const AstRawString* raw_name() const { return name_; } |
41 VariableMode mode() const { return mode_; } | 47 VariableMode mode() const { return VariableModeField::decode(bit_field_); } |
42 bool has_forced_context_allocation() const { | 48 bool has_forced_context_allocation() const { |
43 return force_context_allocation_; | 49 return ForceContextAllocationField::decode(bit_field_); |
44 } | 50 } |
45 void ForceContextAllocation() { | 51 void ForceContextAllocation() { |
46 DCHECK(IsUnallocated() || IsContextSlot()); | 52 bit_field_ = ForceContextAllocationField::update(bit_field_, true); |
neis
2016/08/25 08:57:20
Was the DCHECK removed by accident?
| |
47 force_context_allocation_ = true; | |
48 } | 53 } |
49 bool is_used() { return is_used_; } | 54 bool is_used() { return IsUsedField::decode(bit_field_); } |
50 void set_is_used() { is_used_ = true; } | 55 void set_is_used() { bit_field_ = IsUsedField::update(bit_field_, true); } |
51 MaybeAssignedFlag maybe_assigned() const { return maybe_assigned_; } | 56 MaybeAssignedFlag maybe_assigned() const { |
52 void set_maybe_assigned() { maybe_assigned_ = kMaybeAssigned; } | 57 return MaybeAssignedFlagField::decode(bit_field_); |
58 } | |
59 void set_maybe_assigned() { | |
60 bit_field_ = MaybeAssignedFlagField::update(bit_field_, kMaybeAssigned); | |
61 } | |
53 | 62 |
54 int initializer_position() { return initializer_position_; } | 63 int initializer_position() { return initializer_position_; } |
55 void set_initializer_position(int pos) { initializer_position_ = pos; } | 64 void set_initializer_position(int pos) { initializer_position_ = pos; } |
56 | 65 |
57 bool IsUnallocated() const { | 66 bool IsUnallocated() const { |
58 return location_ == VariableLocation::UNALLOCATED; | 67 return location() == VariableLocation::UNALLOCATED; |
59 } | 68 } |
60 bool IsParameter() const { return location_ == VariableLocation::PARAMETER; } | 69 bool IsParameter() const { return location() == VariableLocation::PARAMETER; } |
61 bool IsStackLocal() const { return location_ == VariableLocation::LOCAL; } | 70 bool IsStackLocal() const { return location() == VariableLocation::LOCAL; } |
62 bool IsStackAllocated() const { return IsParameter() || IsStackLocal(); } | 71 bool IsStackAllocated() const { return IsParameter() || IsStackLocal(); } |
63 bool IsContextSlot() const { return location_ == VariableLocation::CONTEXT; } | 72 bool IsContextSlot() const { return location() == VariableLocation::CONTEXT; } |
64 bool IsGlobalSlot() const { return location_ == VariableLocation::GLOBAL; } | 73 bool IsGlobalSlot() const { return location() == VariableLocation::GLOBAL; } |
65 bool IsUnallocatedOrGlobalSlot() const { | 74 bool IsUnallocatedOrGlobalSlot() const { |
66 return IsUnallocated() || IsGlobalSlot(); | 75 return IsUnallocated() || IsGlobalSlot(); |
67 } | 76 } |
68 bool IsLookupSlot() const { return location_ == VariableLocation::LOOKUP; } | 77 bool IsLookupSlot() const { return location() == VariableLocation::LOOKUP; } |
69 bool IsGlobalObjectProperty() const; | 78 bool IsGlobalObjectProperty() const; |
70 bool IsStaticGlobalObjectProperty() const; | 79 bool IsStaticGlobalObjectProperty() const; |
71 | 80 |
72 bool is_dynamic() const { return IsDynamicVariableMode(mode_); } | 81 bool is_dynamic() const { return IsDynamicVariableMode(mode()); } |
73 bool is_const_mode() const { return IsImmutableVariableMode(mode_); } | 82 bool is_const_mode() const { return IsImmutableVariableMode(mode()); } |
74 bool binding_needs_init() const { | 83 bool binding_needs_init() const { |
75 DCHECK(initialization_flag_ != kNeedsInitialization || | 84 DCHECK(initialization_flag() != kNeedsInitialization || |
76 IsLexicalVariableMode(mode_)); | 85 IsLexicalVariableMode(mode())); |
77 return initialization_flag_ == kNeedsInitialization; | 86 return initialization_flag() == kNeedsInitialization; |
78 } | 87 } |
79 | 88 |
80 bool is_function() const { return kind_ == FUNCTION; } | 89 bool is_function() const { return kind() == FUNCTION; } |
81 bool is_this() const { return kind_ == THIS; } | 90 bool is_this() const { return kind() == THIS; } |
82 bool is_arguments() const { return kind_ == ARGUMENTS; } | 91 bool is_arguments() const { return kind() == ARGUMENTS; } |
83 | 92 |
84 Variable* local_if_not_shadowed() const { | 93 Variable* local_if_not_shadowed() const { |
85 DCHECK(mode_ == DYNAMIC_LOCAL && local_if_not_shadowed_ != NULL); | 94 DCHECK(mode() == DYNAMIC_LOCAL && local_if_not_shadowed_ != NULL); |
86 return local_if_not_shadowed_; | 95 return local_if_not_shadowed_; |
87 } | 96 } |
88 | 97 |
89 void set_local_if_not_shadowed(Variable* local) { | 98 void set_local_if_not_shadowed(Variable* local) { |
90 local_if_not_shadowed_ = local; | 99 local_if_not_shadowed_ = local; |
91 } | 100 } |
92 | 101 |
93 VariableLocation location() const { return location_; } | 102 VariableLocation location() const { |
94 int index() const { return index_; } | 103 return LocationField::decode(bit_field_); |
104 } | |
105 Kind kind() const { return KindField::decode(bit_field_); } | |
95 InitializationFlag initialization_flag() const { | 106 InitializationFlag initialization_flag() const { |
96 return initialization_flag_; | 107 return InitializationFlagField::decode(bit_field_); |
97 } | 108 } |
98 | 109 |
110 int index() const { return index_; } | |
111 | |
99 void AllocateTo(VariableLocation location, int index) { | 112 void AllocateTo(VariableLocation location, int index) { |
100 DCHECK(IsUnallocated() || (location_ == location && index_ == index)); | 113 DCHECK(IsUnallocated() || |
101 location_ = location; | 114 (this->location() == location && this->index() == index)); |
115 bit_field_ = LocationField::update(bit_field_, location); | |
116 DCHECK_EQ(location, this->location()); | |
102 index_ = index; | 117 index_ = index; |
103 } | 118 } |
104 | 119 |
105 static int CompareIndex(Variable* const* v, Variable* const* w); | 120 static int CompareIndex(Variable* const* v, Variable* const* w); |
106 | 121 |
107 private: | 122 private: |
108 Scope* scope_; | 123 Scope* scope_; |
109 const AstRawString* name_; | 124 const AstRawString* name_; |
110 VariableMode mode_; | |
111 Kind kind_; | |
112 VariableLocation location_; | |
113 int index_; | |
114 int initializer_position_; | |
115 | 125 |
116 // If this field is set, this variable references the stored locally bound | 126 // If this field is set, this variable references the stored locally bound |
117 // variable, but it might be shadowed by variable bindings introduced by | 127 // variable, but it might be shadowed by variable bindings introduced by |
118 // sloppy 'eval' calls between the reference scope (inclusive) and the | 128 // sloppy 'eval' calls between the reference scope (inclusive) and the |
119 // binding scope (exclusive). | 129 // binding scope (exclusive). |
120 Variable* local_if_not_shadowed_; | 130 Variable* local_if_not_shadowed_; |
131 int index_; | |
132 int initializer_position_; | |
133 uint16_t bit_field_; | |
121 | 134 |
122 // Usage info. | 135 class VariableModeField : public BitField16<VariableMode, 0, 3> {}; |
123 bool force_context_allocation_; // set by variable resolver | 136 class KindField : public BitField16<Kind, VariableModeField::kNext, 2> {}; |
124 bool is_used_; | 137 class LocationField |
125 InitializationFlag initialization_flag_; | 138 : public BitField16<VariableLocation, KindField::kNext, 3> {}; |
126 MaybeAssignedFlag maybe_assigned_; | 139 class ForceContextAllocationField |
140 : public BitField16<bool, LocationField::kNext, 1> {}; | |
141 class IsUsedField | |
142 : public BitField16<bool, ForceContextAllocationField::kNext, 1> {}; | |
143 class InitializationFlagField | |
144 : public BitField16<InitializationFlag, IsUsedField::kNext, 2> {}; | |
145 class MaybeAssignedFlagField | |
146 : public BitField16<MaybeAssignedFlag, InitializationFlagField::kNext, | |
147 2> {}; | |
127 }; | 148 }; |
128 } // namespace internal | 149 } // namespace internal |
129 } // namespace v8 | 150 } // namespace v8 |
130 | 151 |
131 #endif // V8_AST_VARIABLES_H_ | 152 #endif // V8_AST_VARIABLES_H_ |
OLD | NEW |