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 |
3 | // BSD-style license that can be found in the LICENSE file. |
4 | |
5 | #ifndef RUNTIME_VM_PARSER_H_ |
6 | #define RUNTIME_VM_PARSER_H_ |
7 | |
8 | #include "include/dart_api.h" |
9 | |
10 | #include "lib/invocation_mirror.h" |
11 | #include "platform/assert.h" |
12 | #include "platform/globals.h" |
13 | #include "vm/allocation.h" |
14 | #include "vm/class_finalizer.h" |
15 | #include "vm/hash_table.h" |
16 | #include "vm/kernel.h" |
17 | #include "vm/object.h" |
18 | #include "vm/raw_object.h" |
19 | #include "vm/scopes.h" |
20 | #include "vm/token.h" |
21 | |
22 | namespace dart { |
23 | |
24 | // Forward declarations. |
25 | |
26 | namespace kernel { |
27 | |
28 | class ScopeBuildingResult; |
29 | |
30 | } // namespace kernel |
31 | |
32 | class ArgumentsDescriptor; |
33 | class BitVector; |
34 | class Isolate; |
35 | class LocalScope; |
36 | class LocalVariable; |
37 | struct RegExpCompileData; |
38 | class SourceLabel; |
39 | template <typename T> |
40 | class GrowableArray; |
41 | class Parser; |
42 | |
43 | struct CatchParamDesc; |
44 | class ClassDesc; |
45 | struct MemberDesc; |
46 | struct ParamList; |
47 | struct QualIdent; |
48 | class TopLevel; |
49 | class RecursionChecker; |
50 | |
51 | // The class ParsedFunction holds the result of parsing a function. |
52 | class ParsedFunction : public ZoneAllocated { |
53 | public: |
54 | ParsedFunction(Thread* thread, const Function& function); |
55 | |
56 | const Function& function() const { return function_; } |
57 | const Code& code() const { return code_; } |
58 | |
59 | LocalScope* scope() const { return scope_; } |
60 | void set_scope(LocalScope* scope) { |
61 | ASSERT(scope_ == nullptr); |
62 | ASSERT(scope != nullptr); |
63 | scope_ = scope; |
64 | } |
65 | |
66 | RegExpCompileData* regexp_compile_data() const { |
67 | return regexp_compile_data_; |
68 | } |
69 | void SetRegExpCompileData(RegExpCompileData* regexp_compile_data); |
70 | |
71 | LocalVariable* function_type_arguments() const { |
72 | return function_type_arguments_; |
73 | } |
74 | void set_function_type_arguments(LocalVariable* function_type_arguments) { |
75 | ASSERT(function_type_arguments != NULL); |
76 | function_type_arguments_ = function_type_arguments; |
77 | } |
78 | LocalVariable* parent_type_arguments() const { |
79 | return parent_type_arguments_; |
80 | } |
81 | void set_parent_type_arguments(LocalVariable* parent_type_arguments) { |
82 | ASSERT(parent_type_arguments != NULL); |
83 | parent_type_arguments_ = parent_type_arguments; |
84 | } |
85 | |
86 | void set_default_parameter_values(ZoneGrowableArray<const Instance*>* list) { |
87 | default_parameter_values_ = list; |
88 | #if defined(DEBUG) |
89 | if (list == NULL) return; |
90 | for (intptr_t i = 0; i < list->length(); i++) { |
91 | ASSERT(list->At(i)->IsZoneHandle() || list->At(i)->InVMIsolateHeap()); |
92 | } |
93 | #endif |
94 | } |
95 | |
96 | const Instance& DefaultParameterValueAt(intptr_t i) const { |
97 | ASSERT(default_parameter_values_ != NULL); |
98 | return *default_parameter_values_->At(i); |
99 | } |
100 | |
101 | ZoneGrowableArray<const Instance*>* default_parameter_values() const { |
102 | return default_parameter_values_; |
103 | } |
104 | |
105 | LocalVariable* current_context_var() const { return current_context_var_; } |
106 | |
107 | bool has_arg_desc_var() const { return arg_desc_var_ != NULL; } |
108 | LocalVariable* arg_desc_var() const { return arg_desc_var_; } |
109 | |
110 | LocalVariable* receiver_var() const { |
111 | ASSERT(receiver_var_ != nullptr); |
112 | return receiver_var_; |
113 | } |
114 | void set_receiver_var(LocalVariable* value) { |
115 | ASSERT(receiver_var_ == nullptr); |
116 | ASSERT(value != nullptr); |
117 | receiver_var_ = value; |
118 | } |
119 | bool has_receiver_var() const { return receiver_var_ != nullptr; } |
120 | |
121 | LocalVariable* expression_temp_var() const { |
122 | ASSERT(has_expression_temp_var()); |
123 | return expression_temp_var_; |
124 | } |
125 | void set_expression_temp_var(LocalVariable* value) { |
126 | ASSERT(!has_expression_temp_var()); |
127 | expression_temp_var_ = value; |
128 | } |
129 | bool has_expression_temp_var() const { return expression_temp_var_ != NULL; } |
130 | |
131 | LocalVariable* entry_points_temp_var() const { |
132 | ASSERT(has_entry_points_temp_var()); |
133 | return entry_points_temp_var_; |
134 | } |
135 | void set_entry_points_temp_var(LocalVariable* value) { |
136 | ASSERT(!has_entry_points_temp_var()); |
137 | entry_points_temp_var_ = value; |
138 | } |
139 | bool has_entry_points_temp_var() const { |
140 | return entry_points_temp_var_ != NULL; |
141 | } |
142 | |
143 | LocalVariable* finally_return_temp_var() const { |
144 | ASSERT(has_finally_return_temp_var()); |
145 | return finally_return_temp_var_; |
146 | } |
147 | void set_finally_return_temp_var(LocalVariable* value) { |
148 | ASSERT(!has_finally_return_temp_var()); |
149 | finally_return_temp_var_ = value; |
150 | } |
151 | bool has_finally_return_temp_var() const { |
152 | return finally_return_temp_var_ != NULL; |
153 | } |
154 | void EnsureFinallyReturnTemp(bool is_async); |
155 | |
156 | LocalVariable* EnsureExpressionTemp(); |
157 | LocalVariable* EnsureEntryPointsTemp(); |
158 | |
159 | ZoneGrowableArray<const Field*>* guarded_fields() const { |
160 | return guarded_fields_; |
161 | } |
162 | |
163 | VariableIndex first_parameter_index() const { return first_parameter_index_; } |
164 | int num_stack_locals() const { return num_stack_locals_; } |
165 | |
166 | void AllocateVariables(); |
167 | void AllocateIrregexpVariables(intptr_t num_stack_locals); |
168 | void AllocateBytecodeVariables(intptr_t num_stack_locals); |
169 | |
170 | void record_await() { have_seen_await_expr_ = true; } |
171 | bool have_seen_await() const { return have_seen_await_expr_; } |
172 | bool is_forwarding_stub() const { |
173 | return forwarding_stub_super_target_ != nullptr; |
174 | } |
175 | const Function* forwarding_stub_super_target() const { |
176 | return forwarding_stub_super_target_; |
177 | } |
178 | void MarkForwardingStub(const Function* forwarding_target) { |
179 | forwarding_stub_super_target_ = forwarding_target; |
180 | } |
181 | |
182 | Thread* thread() const { return thread_; } |
183 | Isolate* isolate() const { return thread_->isolate(); } |
184 | Zone* zone() const { return thread_->zone(); } |
185 | |
186 | // Adds only relevant fields: field must be unique and its guarded_cid() |
187 | // relevant. |
188 | void AddToGuardedFields(const Field* field) const; |
189 | |
190 | void Bailout(const char* origin, const char* reason) const; |
191 | |
192 | kernel::ScopeBuildingResult* EnsureKernelScopes(); |
193 | |
194 | LocalVariable* RawTypeArgumentsVariable() const { |
195 | return raw_type_arguments_var_; |
196 | } |
197 | |
198 | void SetRawTypeArgumentsVariable(LocalVariable* raw_type_arguments_var) { |
199 | raw_type_arguments_var_ = raw_type_arguments_var; |
200 | } |
201 | |
202 | void SetRawParameters(ZoneGrowableArray<LocalVariable*>* raw_parameters) { |
203 | raw_parameters_ = raw_parameters; |
204 | } |
205 | |
206 | LocalVariable* RawParameterVariable(intptr_t i) const { |
207 | return raw_parameters_->At(i); |
208 | } |
209 | |
210 | LocalVariable* ParameterVariable(intptr_t i) const { |
211 | ASSERT((i >= 0) && (i < function_.NumParameters())); |
212 | ASSERT(scope() != nullptr); |
213 | return scope()->VariableAt(i); |
214 | } |
215 | |
216 | void SetDefaultFunctionTypeArguments(const TypeArguments& value) { |
217 | default_function_type_arguments_ = value.raw(); |
218 | } |
219 | |
220 | const TypeArguments& DefaultFunctionTypeArguments() const { |
221 | return default_function_type_arguments_; |
222 | } |
223 | |
224 | // Remembers the set of covariant parameters. |
225 | // [covariant_parameters] is a bitvector of function.NumParameters() length. |
226 | void SetCovariantParameters(const BitVector* covariant_parameters); |
227 | |
228 | // Remembers the set of generic-covariant-impl parameters. |
229 | // [covariant_parameters] is a bitvector of function.NumParameters() length. |
230 | void SetGenericCovariantImplParameters( |
231 | const BitVector* generic_covariant_impl_parameters); |
232 | |
233 | bool HasCovariantParametersInfo() const { |
234 | return covariant_parameters_ != nullptr; |
235 | } |
236 | |
237 | // Returns true if i-th parameter is covariant. |
238 | // SetCovariantParameters should be called before using this method. |
239 | bool IsCovariantParameter(intptr_t i) const; |
240 | |
241 | // Returns true if i-th parameter is generic-covariant-impl. |
242 | // SetGenericCovariantImplParameters should be called before using this |
243 | // method. |
244 | bool IsGenericCovariantImplParameter(intptr_t i) const; |
245 | |
246 | private: |
247 | Thread* thread_; |
248 | const Function& function_; |
249 | Code& code_; |
250 | LocalScope* scope_; |
251 | RegExpCompileData* regexp_compile_data_; |
252 | LocalVariable* function_type_arguments_; |
253 | LocalVariable* parent_type_arguments_; |
254 | LocalVariable* current_context_var_; |
255 | LocalVariable* arg_desc_var_; |
256 | LocalVariable* receiver_var_ = nullptr; |
257 | LocalVariable* expression_temp_var_; |
258 | LocalVariable* entry_points_temp_var_; |
259 | LocalVariable* finally_return_temp_var_; |
260 | ZoneGrowableArray<const Field*>* guarded_fields_; |
261 | ZoneGrowableArray<const Instance*>* default_parameter_values_; |
262 | |
263 | LocalVariable* raw_type_arguments_var_; |
264 | ZoneGrowableArray<LocalVariable*>* raw_parameters_ = nullptr; |
265 | |
266 | VariableIndex first_parameter_index_; |
267 | int num_stack_locals_; |
268 | bool have_seen_await_expr_; |
269 | |
270 | const Function* forwarding_stub_super_target_ = nullptr; |
271 | kernel::ScopeBuildingResult* kernel_scopes_; |
272 | |
273 | TypeArguments& default_function_type_arguments_; |
274 | |
275 | const BitVector* covariant_parameters_ = nullptr; |
276 | const BitVector* generic_covariant_impl_parameters_ = nullptr; |
277 | |
278 | friend class Parser; |
279 | DISALLOW_COPY_AND_ASSIGN(ParsedFunction); |
280 | }; |
281 | |
282 | class Parser : public ValueObject { |
283 | public: |
284 | // Parse a function to retrieve parameter information that is not retained in |
285 | // the Function object. Returns either an error if the parse fails (which |
286 | // could be the case for local functions), or a flat array of entries for each |
287 | // parameter. Each parameter entry contains: * a Dart bool indicating whether |
288 | // the parameter was declared final * its default value (or null if none was |
289 | // declared) * an array of metadata (or null if no metadata was declared). |
290 | enum { |
291 | kParameterIsFinalOffset, |
292 | kParameterDefaultValueOffset, |
293 | kParameterMetadataOffset, |
294 | kParameterEntrySize, |
295 | }; |
296 | |
297 | private: |
298 | DISALLOW_COPY_AND_ASSIGN(Parser); |
299 | }; |
300 | |
301 | } // namespace dart |
302 | |
303 | #endif // RUNTIME_VM_PARSER_H_ |
304 |