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
22namespace dart {
23
24// Forward declarations.
25
26namespace kernel {
27
28class ScopeBuildingResult;
29
30} // namespace kernel
31
32class ArgumentsDescriptor;
33class BitVector;
34class Isolate;
35class LocalScope;
36class LocalVariable;
37struct RegExpCompileData;
38class SourceLabel;
39template <typename T>
40class GrowableArray;
41class Parser;
42
43struct CatchParamDesc;
44class ClassDesc;
45struct MemberDesc;
46struct ParamList;
47struct QualIdent;
48class TopLevel;
49class RecursionChecker;
50
51// The class ParsedFunction holds the result of parsing a function.
52class 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
282class 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