OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef RUNTIME_VM_SCOPES_H_ | 5 #ifndef RUNTIME_VM_SCOPES_H_ |
6 #define RUNTIME_VM_SCOPES_H_ | 6 #define RUNTIME_VM_SCOPES_H_ |
7 | 7 |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "platform/globals.h" | 9 #include "platform/globals.h" |
10 #include "vm/allocation.h" | 10 #include "vm/allocation.h" |
11 #include "vm/growable_array.h" | 11 #include "vm/growable_array.h" |
12 #include "vm/object.h" | 12 #include "vm/object.h" |
13 #include "vm/raw_object.h" | 13 #include "vm/raw_object.h" |
14 #include "vm/symbols.h" | 14 #include "vm/symbols.h" |
15 #include "vm/token.h" | 15 #include "vm/token.h" |
16 | 16 |
17 namespace dart { | 17 namespace dart { |
18 | 18 |
19 class LocalScope; | 19 class LocalScope; |
20 | 20 |
21 | 21 |
22 class LocalVariable : public ZoneAllocated { | 22 class LocalVariable : public ZoneAllocated { |
23 public: | 23 public: |
24 LocalVariable(TokenPosition declaration_pos, | 24 LocalVariable(TokenPosition declaration_pos, |
25 TokenPosition token_pos, | 25 TokenPosition token_pos, |
26 const String& name, | 26 const String& name, |
27 const AbstractType& type) | 27 const AbstractType& type) |
28 : declaration_pos_(declaration_pos), | 28 : declaration_pos_(declaration_pos), |
29 token_pos_(token_pos), | 29 token_pos_(token_pos), |
30 name_(name), | 30 name_(name), |
31 owner_(NULL), | 31 owner_(NULL), |
32 type_(type), | 32 type_(type), |
33 const_value_(NULL), | 33 const_value_(NULL), |
34 is_final_(false), | 34 is_final_(false), |
35 is_captured_(false), | 35 is_captured_(false), |
36 is_invisible_(false), | 36 is_invisible_(false), |
37 is_captured_parameter_(false), | 37 is_captured_parameter_(false), |
38 is_forced_stack_(false), | 38 is_forced_stack_(false), |
39 index_(LocalVariable::kUninitializedIndex) { | 39 index_(LocalVariable::kUninitializedIndex) { |
40 ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle()); | 40 ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle()); |
41 ASSERT(type.IsFinalized()); | 41 ASSERT(type.IsFinalized()); |
42 ASSERT(name.IsSymbol()); | 42 ASSERT(name.IsSymbol()); |
43 } | 43 } |
44 | 44 |
45 TokenPosition token_pos() const { return token_pos_; } | 45 TokenPosition token_pos() const { return token_pos_; } |
46 TokenPosition declaration_token_pos() const { return declaration_pos_; } | 46 TokenPosition declaration_token_pos() const { return declaration_pos_; } |
47 const String& name() const { return name_; } | 47 const String& name() const { return name_; } |
48 LocalScope* owner() const { return owner_; } | 48 LocalScope* owner() const { return owner_; } |
49 void set_owner(LocalScope* owner) { | 49 void set_owner(LocalScope* owner) { |
50 ASSERT(owner_ == NULL); | 50 ASSERT(owner_ == NULL); |
51 owner_ = owner; | 51 owner_ = owner; |
52 } | 52 } |
53 | 53 |
54 const AbstractType& type() const { return type_; } | 54 const AbstractType& type() const { return type_; } |
55 | 55 |
56 bool is_final() const { return is_final_; } | 56 bool is_final() const { return is_final_; } |
57 void set_is_final() { is_final_ = true; } | 57 void set_is_final() { is_final_ = true; } |
58 | 58 |
59 bool is_captured() const { return is_captured_; } | 59 bool is_captured() const { return is_captured_; } |
60 void set_is_captured() { is_captured_ = true; } | 60 void set_is_captured() { is_captured_ = true; } |
61 | 61 |
62 // Variables marked as forced to stack are skipped and not captured by | 62 // Variables marked as forced to stack are skipped and not captured by |
63 // CaptureLocalVariables - which iterates scope chain between two scopes | 63 // CaptureLocalVariables - which iterates scope chain between two scopes |
64 // and indiscriminately marks all variables as captured. | 64 // and indiscriminately marks all variables as captured. |
65 // TODO(27590) remove the hardcoded blacklist from CaptureLocalVariables | 65 // TODO(27590) remove the hardcoded blacklist from CaptureLocalVariables |
66 bool is_forced_stack() const { return is_forced_stack_; } | 66 bool is_forced_stack() const { return is_forced_stack_; } |
67 void set_is_forced_stack() { is_forced_stack_ = true; } | 67 void set_is_forced_stack() { is_forced_stack_ = true; } |
68 | 68 |
69 bool HasIndex() const { | 69 bool HasIndex() const { return index_ != kUninitializedIndex; } |
70 return index_ != kUninitializedIndex; | |
71 } | |
72 int index() const { | 70 int index() const { |
73 ASSERT(HasIndex()); | 71 ASSERT(HasIndex()); |
74 return index_; | 72 return index_; |
75 } | 73 } |
76 | 74 |
77 // Assign an index to a local. | 75 // Assign an index to a local. |
78 void set_index(int index) { | 76 void set_index(int index) { |
79 ASSERT(index != kUninitializedIndex); | 77 ASSERT(index != kUninitializedIndex); |
80 index_ = index; | 78 index_ = index; |
81 } | 79 } |
82 | 80 |
83 void set_invisible(bool value) { | 81 void set_invisible(bool value) { is_invisible_ = value; } |
84 is_invisible_ = value; | |
85 } | |
86 bool is_invisible() const { return is_invisible_; } | 82 bool is_invisible() const { return is_invisible_; } |
87 | 83 |
88 bool is_captured_parameter() const { return is_captured_parameter_; } | 84 bool is_captured_parameter() const { return is_captured_parameter_; } |
89 void set_is_captured_parameter(bool value) { | 85 void set_is_captured_parameter(bool value) { is_captured_parameter_ = value; } |
90 is_captured_parameter_ = value; | |
91 } | |
92 | 86 |
93 // By convention, internal variables start with a colon. | 87 // By convention, internal variables start with a colon. |
94 bool IsInternal() const { | 88 bool IsInternal() const { return name_.CharAt(0) == ':'; } |
95 return name_.CharAt(0) == ':'; | |
96 } | |
97 | 89 |
98 bool IsConst() const { | 90 bool IsConst() const { return const_value_ != NULL; } |
99 return const_value_ != NULL; | |
100 } | |
101 | 91 |
102 void SetConstValue(const Instance& value) { | 92 void SetConstValue(const Instance& value) { |
103 ASSERT(value.IsZoneHandle() || value.IsReadOnlyHandle()); | 93 ASSERT(value.IsZoneHandle() || value.IsReadOnlyHandle()); |
104 const_value_ = &value; | 94 const_value_ = &value; |
105 } | 95 } |
106 | 96 |
107 const Instance* ConstValue() const { | 97 const Instance* ConstValue() const { |
108 ASSERT(IsConst()); | 98 ASSERT(IsConst()); |
109 return const_value_; | 99 return const_value_; |
110 } | 100 } |
111 | 101 |
112 bool Equals(const LocalVariable& other) const; | 102 bool Equals(const LocalVariable& other) const; |
113 | 103 |
114 // Map the frame index to a bit-vector index. Assumes the variable is | 104 // Map the frame index to a bit-vector index. Assumes the variable is |
115 // allocated to the frame. | 105 // allocated to the frame. |
116 // var_count is the total number of stack-allocated variables including | 106 // var_count is the total number of stack-allocated variables including |
117 // all parameters. | 107 // all parameters. |
118 int BitIndexIn(intptr_t var_count) const; | 108 int BitIndexIn(intptr_t var_count) const; |
119 | 109 |
120 private: | 110 private: |
121 static const int kUninitializedIndex = INT_MIN; | 111 static const int kUninitializedIndex = INT_MIN; |
122 | 112 |
123 const TokenPosition declaration_pos_; | 113 const TokenPosition declaration_pos_; |
124 const TokenPosition token_pos_; | 114 const TokenPosition token_pos_; |
125 const String& name_; | 115 const String& name_; |
126 LocalScope* owner_; // Local scope declaring this variable. | 116 LocalScope* owner_; // Local scope declaring this variable. |
127 | 117 |
128 const AbstractType& type_; // Declaration type of local variable. | 118 const AbstractType& type_; // Declaration type of local variable. |
129 | 119 |
130 const Instance* const_value_; // NULL or compile-time const value. | 120 const Instance* const_value_; // NULL or compile-time const value. |
131 | 121 |
132 bool is_final_; // If true, this variable is readonly. | 122 bool is_final_; // If true, this variable is readonly. |
133 bool is_captured_; // If true, this variable lives in the context, otherwise | 123 bool is_captured_; // If true, this variable lives in the context, otherwise |
134 // in the stack frame. | 124 // in the stack frame. |
135 bool is_invisible_; | 125 bool is_invisible_; |
136 bool is_captured_parameter_; | 126 bool is_captured_parameter_; |
137 bool is_forced_stack_; | 127 bool is_forced_stack_; |
138 int index_; // Allocation index in words relative to frame pointer (if not | 128 int index_; // Allocation index in words relative to frame pointer (if not |
139 // captured), or relative to the context pointer (if captured). | 129 // captured), or relative to the context pointer (if captured). |
140 | 130 |
141 friend class LocalScope; | 131 friend class LocalScope; |
142 DISALLOW_COPY_AND_ASSIGN(LocalVariable); | 132 DISALLOW_COPY_AND_ASSIGN(LocalVariable); |
143 }; | 133 }; |
144 | 134 |
145 | 135 |
146 class NameReference : public ZoneAllocated { | 136 class NameReference : public ZoneAllocated { |
147 public: | 137 public: |
148 NameReference(TokenPosition token_pos, const String& name) | 138 NameReference(TokenPosition token_pos, const String& name) |
149 : token_pos_(token_pos), | 139 : token_pos_(token_pos), name_(name) { |
150 name_(name) { | |
151 ASSERT(name.IsSymbol()); | 140 ASSERT(name.IsSymbol()); |
152 } | 141 } |
153 const String& name() const { return name_; } | 142 const String& name() const { return name_; } |
154 TokenPosition token_pos() const { return token_pos_; } | 143 TokenPosition token_pos() const { return token_pos_; } |
155 void set_token_pos(TokenPosition value) { token_pos_ = value; } | 144 void set_token_pos(TokenPosition value) { token_pos_ = value; } |
| 145 |
156 private: | 146 private: |
157 TokenPosition token_pos_; | 147 TokenPosition token_pos_; |
158 const String& name_; | 148 const String& name_; |
159 }; | 149 }; |
160 | 150 |
161 | 151 |
162 class SourceLabel : public ZoneAllocated { | 152 class SourceLabel : public ZoneAllocated { |
163 public: | 153 public: |
164 enum Kind { | 154 enum Kind { |
165 kFor, | 155 kFor, |
166 kWhile, | 156 kWhile, |
167 kDoWhile, | 157 kDoWhile, |
168 kSwitch, | 158 kSwitch, |
169 kCase, | 159 kCase, |
170 kTry, | 160 kTry, |
171 kCatch, | 161 kCatch, |
172 kForward, | 162 kForward, |
173 kStatement // Any statement other than the above | 163 kStatement // Any statement other than the above |
174 }; | 164 }; |
175 | 165 |
176 SourceLabel(TokenPosition token_pos, const String& name, Kind kind) | 166 SourceLabel(TokenPosition token_pos, const String& name, Kind kind) |
177 : token_pos_(token_pos), | 167 : token_pos_(token_pos), name_(name), owner_(NULL), kind_(kind) { |
178 name_(name), | |
179 owner_(NULL), | |
180 kind_(kind) { | |
181 ASSERT(name.IsSymbol()); | 168 ASSERT(name.IsSymbol()); |
182 } | 169 } |
183 | 170 |
184 static SourceLabel* New(TokenPosition token_pos, String* name, Kind kind) { | 171 static SourceLabel* New(TokenPosition token_pos, String* name, Kind kind) { |
185 if (name != NULL) { | 172 if (name != NULL) { |
186 return new SourceLabel(token_pos, *name, kind); | 173 return new SourceLabel(token_pos, *name, kind); |
187 } else { | 174 } else { |
188 return new SourceLabel(token_pos, | 175 return new SourceLabel(token_pos, Symbols::DefaultLabel(), kind); |
189 Symbols::DefaultLabel(), | |
190 kind); | |
191 } | 176 } |
192 } | 177 } |
193 | 178 |
194 TokenPosition token_pos() const { return token_pos_; } | 179 TokenPosition token_pos() const { return token_pos_; } |
195 const String& name() const { return name_; } | 180 const String& name() const { return name_; } |
196 LocalScope* owner() const { return owner_; } | 181 LocalScope* owner() const { return owner_; } |
197 void set_owner(LocalScope* owner) { | 182 void set_owner(LocalScope* owner) { owner_ = owner; } |
198 owner_ = owner; | |
199 } | |
200 | 183 |
201 Kind kind() const { return kind_; } | 184 Kind kind() const { return kind_; } |
202 | 185 |
203 // Returns the function level of the scope in which the label is defined. | 186 // Returns the function level of the scope in which the label is defined. |
204 int FunctionLevel() const; | 187 int FunctionLevel() const; |
205 | 188 |
206 bool IsUnresolved() { return kind_ == kForward; } | 189 bool IsUnresolved() { return kind_ == kForward; } |
207 void ResolveForwardReference() { kind_ = kCase; } | 190 void ResolveForwardReference() { kind_ = kCase; } |
208 | 191 |
209 private: | 192 private: |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 LocalScope** context_owner); | 355 LocalScope** context_owner); |
373 | 356 |
374 void CollectLocalVariables(GrowableArray<VarDesc>* vars, int16_t* scope_id); | 357 void CollectLocalVariables(GrowableArray<VarDesc>* vars, int16_t* scope_id); |
375 | 358 |
376 NameReference* FindReference(const String& name) const; | 359 NameReference* FindReference(const String& name) const; |
377 | 360 |
378 static const int kUnitializedContextLevel = INT_MIN; | 361 static const int kUnitializedContextLevel = INT_MIN; |
379 LocalScope* parent_; | 362 LocalScope* parent_; |
380 LocalScope* child_; | 363 LocalScope* child_; |
381 LocalScope* sibling_; | 364 LocalScope* sibling_; |
382 int function_level_; // Reflects the nesting level of local functions. | 365 int function_level_; // Reflects the nesting level of local functions. |
383 int loop_level_; // Reflects the loop nesting level. | 366 int loop_level_; // Reflects the loop nesting level. |
384 int context_level_; // Reflects the level of the runtime context. | 367 int context_level_; // Reflects the level of the runtime context. |
385 int num_context_variables_; // Only set if this scope is a context owner. | 368 int num_context_variables_; // Only set if this scope is a context owner. |
386 TokenPosition begin_token_pos_; // Token index of beginning of scope. | 369 TokenPosition begin_token_pos_; // Token index of beginning of scope. |
387 TokenPosition end_token_pos_; // Token index of end of scope. | 370 TokenPosition end_token_pos_; // Token index of end of scope. |
388 GrowableArray<LocalVariable*> variables_; | 371 GrowableArray<LocalVariable*> variables_; |
389 GrowableArray<SourceLabel*> labels_; | 372 GrowableArray<SourceLabel*> labels_; |
390 | 373 |
391 // List of names referenced in this scope and its children that | 374 // List of names referenced in this scope and its children that |
392 // are not resolved to local variables. | 375 // are not resolved to local variables. |
393 GrowableArray<NameReference*> referenced_; | 376 GrowableArray<NameReference*> referenced_; |
394 | 377 |
395 DISALLOW_COPY_AND_ASSIGN(LocalScope); | 378 DISALLOW_COPY_AND_ASSIGN(LocalScope); |
396 }; | 379 }; |
397 | 380 |
398 } // namespace dart | 381 } // namespace dart |
399 | 382 |
400 #endif // RUNTIME_VM_SCOPES_H_ | 383 #endif // RUNTIME_VM_SCOPES_H_ |
OLD | NEW |