OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2016, 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 VM_DIL_TO_IL_H_ | |
6 #define VM_DIL_TO_IL_H_ | |
7 | |
8 #include "vm/growable_array.h" | |
9 #include "vm/hash_map.h" | |
10 | |
11 #include "vm/dil.h" | |
12 #include "vm/flow_graph.h" | |
13 #include "vm/flow_graph_builder.h" | |
14 #include "vm/intermediate_language.h" | |
15 | |
16 namespace dart { | |
17 namespace dil { | |
18 | |
19 template <typename K, typename V> | |
20 class Map : public DirectChainedHashMap<RawPointerKeyValueTrait<K, V> > { | |
21 public: | |
22 typedef typename RawPointerKeyValueTrait<K, V>::Key Key; | |
23 typedef typename RawPointerKeyValueTrait<K, V>::Value Value; | |
24 typedef typename RawPointerKeyValueTrait<K, V>::Pair Pair; | |
25 | |
26 inline void Insert(const Key& key, const Value& value) { | |
27 Pair pair(key, value); | |
28 DirectChainedHashMap<RawPointerKeyValueTrait<K, V> >::Insert(pair); | |
29 } | |
30 | |
31 inline V Lookup(const Key& key) { | |
32 Pair* pair = | |
33 DirectChainedHashMap<RawPointerKeyValueTrait<K, V> >::Lookup(key); | |
34 if (pair == NULL) { | |
35 return V(); | |
36 } else { | |
37 return pair->value; | |
38 } | |
39 } | |
40 }; | |
41 | |
42 class BreakableBlock; | |
43 class CatchBlock; | |
44 class FlowGraphBuilder; | |
45 class SwitchBlock; | |
46 class TryCatchBlock; | |
47 class TryFinallyBlock; | |
48 | |
49 class Fragment { | |
50 public: | |
51 Instruction* entry; | |
52 Instruction* current; | |
53 | |
54 Fragment() : entry(NULL), current(NULL) {} | |
55 | |
56 explicit Fragment(Instruction* instruction) | |
57 : entry(instruction), current(instruction) {} | |
58 | |
59 Fragment(Instruction* entry, Instruction* current) | |
60 : entry(entry), current(current) {} | |
61 | |
62 bool is_open() { return entry == NULL || current != NULL; } | |
63 bool is_closed() { return !is_open(); } | |
64 | |
65 Fragment& operator+=(const Fragment& other); | |
66 Fragment& operator<<=(Instruction* next); | |
67 | |
68 Fragment closed(); | |
69 }; | |
70 | |
71 Fragment operator+(const Fragment& first, const Fragment& second); | |
72 Fragment operator<<(const Fragment& fragment, Instruction* next); | |
73 | |
74 typedef ZoneGrowableArray<PushArgumentInstr*>* ArgumentArray; | |
75 | |
76 | |
77 class ActiveClass { | |
78 public: | |
79 ActiveClass() | |
80 : dil_class(NULL), klass(NULL), member(NULL), dil_function(NULL) {} | |
81 | |
82 // The current enclosing dil class (if available, otherwise NULL). | |
83 Class* dil_class; | |
84 | |
85 // The current enclosing class (or the library top-level class). When this is | |
86 // a library's top-level class, the dil_class will be NULL. | |
87 const dart::Class* klass; | |
88 | |
89 // The enclosing member (e.g., Constructor, Procedure, or Field) if there | |
90 // is one. | |
91 Member* member; | |
92 | |
93 // The current function. | |
94 FunctionNode* dil_function; | |
95 }; | |
96 | |
97 | |
98 class ActiveClassScope { | |
99 public: | |
100 ActiveClassScope(ActiveClass* active_class, Class* dil_class, | |
101 const dart::Class* klass) | |
102 : active_class_(active_class), saved_(*active_class) { | |
103 active_class_->dil_class = dil_class; | |
104 active_class_->klass = klass; | |
105 active_class_->member = NULL; | |
106 active_class_->dil_function = NULL; | |
107 } | |
108 | |
109 ~ActiveClassScope() { *active_class_ = saved_; } | |
110 | |
111 private: | |
112 ActiveClass* active_class_; | |
113 ActiveClass saved_; | |
114 }; | |
115 | |
116 | |
117 class ActiveMemberScope { | |
118 public: | |
119 ActiveMemberScope(ActiveClass* active_class, Member* member) | |
120 : active_class_(active_class), saved_(*active_class) { | |
121 // The class and dil_class is inherited. | |
122 active_class_->member = member; | |
123 active_class_->dil_function = NULL; | |
124 } | |
125 | |
126 ~ActiveMemberScope() { *active_class_ = saved_; } | |
127 | |
128 private: | |
129 ActiveClass* active_class_; | |
130 ActiveClass saved_; | |
131 }; | |
132 | |
133 | |
134 class ActiveFunctionScope { | |
135 public: | |
136 ActiveFunctionScope(ActiveClass* active_class, FunctionNode* dil_function) | |
137 : active_class_(active_class), saved_(*active_class) { | |
138 // The class, dil_class, and member are inherited. | |
139 active_class_->dil_function = dil_function; | |
140 } | |
141 | |
142 ~ActiveFunctionScope() { *active_class_ = saved_; } | |
143 | |
144 private: | |
145 ActiveClass* active_class_; | |
146 ActiveClass saved_; | |
147 }; | |
148 | |
149 | |
150 class TranslationHelper { | |
151 public: | |
152 TranslationHelper(dart::Thread* thread, dart::Zone* zone, Isolate* isolate) | |
153 : thread_(thread), zone_(zone), isolate_(isolate) {} | |
154 virtual ~TranslationHelper() {} | |
155 | |
156 Thread* thread() { return thread_; } | |
157 | |
158 Zone* zone() { return zone_; } | |
159 | |
160 Isolate* isolate() { return isolate_; } | |
161 | |
162 // Set whether unfinalized classes should be finalized. The base class | |
163 // implementation used at flow graph construction time looks up classes in the | |
164 // VM's heap, all of which should already be finalized. | |
165 virtual void SetFinalize(bool finalize) {} | |
166 | |
167 RawInstance* Canonicalize(const Instance& instance); | |
168 | |
169 const dart::String& DartString(const char* content, | |
170 Heap::Space space = Heap::kNew); | |
171 dart::String& DartString(String* content, Heap::Space space = Heap::kNew); | |
172 const dart::String& DartSymbol(const char* content) const; | |
173 dart::String& DartSymbol(String* content) const; | |
174 | |
175 const dart::String& DartClassName(Class* dil_klass); | |
176 const dart::String& DartConstructorName(Constructor* node); | |
177 const dart::String& DartProcedureName(Procedure* procedure); | |
178 | |
179 const dart::String& DartSetterName(Name* dil_name); | |
180 const dart::String& DartGetterName(Name* dil_name); | |
181 const dart::String& DartFieldName(Name* dil_name); | |
182 const dart::String& DartInitializerName(Name* dil_name); | |
183 const dart::String& DartMethodName(Name* dil_name); | |
184 const dart::String& DartFactoryName(Class* klass, Name* dil_name); | |
185 | |
186 const Array& ArgumentNames(List<NamedExpression>* named); | |
187 | |
188 // A subclass overrides these when reading in the DIL program in order to | |
189 // support recursive type expressions (e.g. for "implements X" ... | |
190 // annotations). | |
191 virtual RawLibrary* LookupLibraryByDilLibrary(Library* library); | |
192 virtual RawClass* LookupClassByDilClass(Class* klass); | |
193 | |
194 RawField* LookupFieldByDilField(Field* field); | |
195 RawFunction* LookupStaticMethodByDilProcedure(Procedure* procedure); | |
196 RawFunction* LookupConstructorByDilConstructor(Constructor* constructor); | |
197 dart::RawFunction* LookupConstructorByDilConstructor( | |
198 const dart::Class& owner, Constructor* constructor); | |
199 | |
200 dart::Type& GetCanonicalType(const dart::Class& klass); | |
201 | |
202 void ReportError(const char* format, ...); | |
203 void ReportError(const Error& prev_error, const char* format, ...); | |
204 | |
205 private: | |
206 // This will mangle [dil_name] (if necessary) and make the result a symbol. | |
207 // The result will be avilable in [name_to_modify] and it is also returned. | |
208 dart::String& ManglePrivateName(Library* dil_library, | |
209 dart::String* name_to_modify, | |
210 bool symbolize = true); | |
211 | |
212 dart::Thread* thread_; | |
213 dart::Zone* zone_; | |
214 dart::Isolate* isolate_; | |
215 }; | |
216 | |
217 // Regarding malformed types: | |
218 // The spec says in section "19.1 Static Types" roughly: | |
219 // | |
220 // A type T is malformed iff: | |
221 // * T does not denote a type in scope | |
222 // * T refers to a type parameter in a static member | |
223 // * T is a parametrized Type G<T1, ...> and G is malformed | |
224 // * T denotes declarations from multiple imports | |
225 // | |
226 // Any use of a malformed type gives rise to a static warning. A malformed | |
227 // type is then interpreted as dynamic by the static type checker and the | |
228 // runtime unless explicitly specified otherwise. | |
229 class DartTypeTranslator : public DartTypeVisitor { | |
230 public: | |
231 DartTypeTranslator(TranslationHelper* helper, ActiveClass* active_class, | |
232 bool finalize = true) | |
233 : translation_helper_(*helper), | |
234 active_class_(active_class), | |
235 zone_(helper->zone()), | |
236 result_(AbstractType::Handle(helper->zone())), | |
237 finalize_(finalize) {} | |
238 | |
239 // Can return a malformed type. | |
240 AbstractType& TranslateType(DartType* node); | |
241 | |
242 // Can return a malformed type. | |
243 AbstractType& TranslateTypeWithoutFinalization(DartType* node); | |
244 | |
245 | |
246 virtual void VisitDefaultDartType(DartType* node) { UNREACHABLE(); } | |
rmacnak
2016/10/13 00:56:39
Don't implement virtual functions in headers. I be
Vyacheslav Egorov (Google)
2016/10/13 14:37:58
$ cd runtime/vm
$ git grep "virtual .* {" -- *.h |
| |
247 | |
248 virtual void VisitInvalidType(InvalidType* node); | |
249 | |
250 virtual void VisitFunctionType(FunctionType* node); | |
251 | |
252 virtual void VisitTypeParameterType(TypeParameterType* node); | |
253 | |
254 virtual void VisitInterfaceType(InterfaceType* node); | |
255 | |
256 virtual void VisitDynamicType(DynamicType* node); | |
257 | |
258 virtual void VisitVoidType(VoidType* node); | |
259 | |
260 // Will return `TypeArguments::null()` in case any of the arguments are | |
261 // malformed. | |
262 const TypeArguments& TranslateInstantiatedTypeArguments( | |
263 const dart::Class& receiver_class, DartType** receiver_type_arguments, | |
264 intptr_t length); | |
265 | |
266 // Will return `TypeArguments::null()` in case any of the arguments are | |
267 // malformed. | |
268 const TypeArguments& TranslateTypeArguments(DartType** dart_types, | |
269 intptr_t length); | |
270 | |
271 const Type& ReceiverType(const dart::Class& klass); | |
272 | |
273 private: | |
274 TranslationHelper& translation_helper_; | |
275 ActiveClass* active_class_; | |
276 Zone* zone_; | |
277 AbstractType& result_; | |
278 | |
279 bool finalize_; | |
280 }; | |
281 | |
282 | |
283 // There are several cases when we are compiling constant expressions: | |
284 // | |
285 // * constant field initializers: | |
286 // const FieldName = <expr>; | |
287 // | |
288 // * constant expressions: | |
289 // const [<expr>, ...] | |
290 // const {<expr> : <expr>, ...} | |
291 // const Constructor(<expr>, ...) | |
292 // | |
293 // * constant default parameters: | |
294 // f(a, [b = <expr>]) | |
295 // f(a, {b: <expr>}) | |
296 // | |
297 // * constant values to compare in a [SwitchCase] | |
298 // case <expr>: | |
299 // | |
300 // In all cases `<expr>` must be recursively evaluated and canonicalized at | |
301 // compile-time. | |
302 class ConstantEvaluator : public ExpressionVisitor { | |
303 public: | |
304 ConstantEvaluator(FlowGraphBuilder* builder, Zone* zone, TranslationHelper* h, | |
305 DartTypeTranslator* type_translator) | |
306 : builder_(builder), | |
307 isolate_(Isolate::Current()), | |
308 zone_(zone), | |
309 translation_helper_(*h), | |
310 type_translator_(*type_translator), | |
311 result_(dart::Instance::Handle(zone)) {} | |
312 virtual ~ConstantEvaluator() {} | |
313 | |
314 Instance& EvaluateExpression(Expression* node); | |
315 Object& EvaluateExpressionSafe(Expression* node); | |
316 Instance& EvaluateConstructorInvocation(ConstructorInvocation* node); | |
317 Instance& EvaluateListLiteral(ListLiteral* node); | |
318 Instance& EvaluateMapLiteral(MapLiteral* node); | |
319 | |
320 virtual void VisitDefaultExpression(Expression* node) { UNREACHABLE(); } | |
321 | |
322 virtual void VisitBigintLiteral(BigintLiteral* node); | |
323 virtual void VisitBoolLiteral(BoolLiteral* node); | |
324 virtual void VisitDoubleLiteral(DoubleLiteral* node); | |
325 virtual void VisitIntLiteral(IntLiteral* node); | |
326 virtual void VisitNullLiteral(NullLiteral* node); | |
327 virtual void VisitStringLiteral(StringLiteral* node); | |
328 virtual void VisitSymbolLiteral(SymbolLiteral* node); | |
329 virtual void VisitTypeLiteral(TypeLiteral* node); | |
330 | |
331 virtual void VisitListLiteral(ListLiteral* node); | |
332 virtual void VisitMapLiteral(MapLiteral* node); | |
333 | |
334 virtual void VisitConstructorInvocation(ConstructorInvocation* node); | |
335 virtual void VisitMethodInvocation(MethodInvocation* node); | |
336 virtual void VisitStaticGet(StaticGet* node); | |
337 virtual void VisitVariableGet(VariableGet* node); | |
338 virtual void VisitLet(Let* node); | |
339 virtual void VisitStaticInvocation(StaticInvocation* node); | |
340 virtual void VisitStringConcatenation(StringConcatenation* node); | |
341 virtual void VisitConditionalExpression(ConditionalExpression* node); | |
342 virtual void VisitLogicalExpression(LogicalExpression* node); | |
343 virtual void VisitNot(Not* node); | |
344 | |
345 private: | |
346 // This will translate type arguments form [dil_arguments]. If no type | |
347 // arguments are passed and the [target] is a factory then the null type | |
348 // argument array will be returned. | |
349 // | |
350 // If none of these cases apply, NULL will be returned. | |
351 const TypeArguments* TranslateTypeArguments(const Function& target, | |
352 dart::Class* target_klass, | |
353 Arguments* dil_arguments); | |
354 | |
355 const Object& RunFunction(const Function& function, Arguments* arguments, | |
356 const Instance* receiver = NULL, | |
357 const TypeArguments* type_args = NULL); | |
358 | |
359 const Object& RunFunction(const Function& function, const Array& arguments, | |
360 const Array& names); | |
361 | |
362 RawObject* EvaluateConstConstructorCall(const dart::Class& type_class, | |
363 const TypeArguments& type_arguments, | |
364 const Function& constructor, | |
365 const Object& argument); | |
366 | |
367 FlowGraphBuilder* builder_; | |
368 Isolate* isolate_; | |
369 Zone* zone_; | |
370 TranslationHelper& translation_helper_; | |
371 DartTypeTranslator& type_translator_; | |
372 | |
373 Instance& result_; | |
374 }; | |
375 | |
376 | |
377 struct FunctionScope { | |
378 FunctionNode* function; | |
379 LocalScope* scope; | |
380 }; | |
381 | |
382 | |
383 class ScopeBuildingResult : public ZoneAllocated { | |
384 public: | |
385 Map<VariableDeclaration, LocalVariable*> locals; | |
386 Map<TreeNode, LocalScope*> scopes; | |
387 GrowableArray<FunctionScope> function_scopes; | |
388 | |
389 // Only non-NULL for instance functions. | |
390 LocalVariable* this_variable = NULL; | |
391 | |
392 // Only non-NULL for factory constructor functions. | |
393 LocalVariable* type_arguments_variable = NULL; | |
394 | |
395 // Non-NULL when the function contains a switch statement. | |
396 LocalVariable* switch_variable = NULL; | |
397 | |
398 // Non-NULL when the function contains a return inside a finally block. | |
399 LocalVariable* finally_return_variable = NULL; | |
400 | |
401 // Non-NULL when the function is a setter. | |
402 LocalVariable* setter_value = NULL; | |
403 | |
404 // Non-NULL if the function contains yield statement. | |
405 // TODO(vegorov) actual variable is called :await_jump_var, we should rename | |
406 // it to reflect the fact that it is used for both await and yield. | |
407 LocalVariable* yield_jump_variable = NULL; | |
408 | |
409 // Non-NULL if the function contains yield statement. | |
410 // TODO(vegorov) actual variable is called :await_ctx_var, we should rename | |
411 // it to reflect the fact that it is used for both await and yield. | |
412 LocalVariable* yield_context_variable = NULL; | |
413 | |
414 // Variables used in exception handlers, one per exception handler nesting | |
415 // level. | |
416 GrowableArray<LocalVariable*> exception_variables; | |
417 GrowableArray<LocalVariable*> stack_trace_variables; | |
418 GrowableArray<LocalVariable*> catch_context_variables; | |
419 | |
420 // For-in iterators, one per for-in nesting level. | |
421 GrowableArray<LocalVariable*> iterator_variables; | |
422 }; | |
423 | |
424 | |
425 class ScopeBuilder : public RecursiveVisitor { | |
426 public: | |
427 ScopeBuilder(ParsedFunction* parsed_function, TreeNode* node) | |
428 : result_(NULL), | |
429 parsed_function_(parsed_function), | |
430 node_(node), | |
431 zone_(Thread::Current()->zone()), | |
432 translation_helper_(Thread::Current(), zone_, Isolate::Current()), | |
433 current_function_scope_(NULL), | |
434 scope_(NULL), | |
435 depth_(0), | |
436 name_index_(0) {} | |
437 | |
438 virtual ~ScopeBuilder() {} | |
439 | |
440 ScopeBuildingResult* BuildScopes(); | |
441 | |
442 virtual void VisitName(Name* node) { /* NOP */ | |
443 } | |
444 | |
445 virtual void VisitThisExpression(ThisExpression* node); | |
446 virtual void VisitTypeParameterType(TypeParameterType* node); | |
447 virtual void VisitVariableGet(VariableGet* node); | |
448 virtual void VisitVariableSet(VariableSet* node); | |
449 virtual void VisitFunctionExpression(FunctionExpression* node); | |
450 virtual void VisitLet(Let* node); | |
451 virtual void VisitBlock(Block* node); | |
452 virtual void VisitVariableDeclaration(VariableDeclaration* node); | |
453 virtual void VisitFunctionDeclaration(FunctionDeclaration* node); | |
454 virtual void VisitWhileStatement(WhileStatement* node); | |
455 virtual void VisitDoStatement(DoStatement* node); | |
456 virtual void VisitForStatement(ForStatement* node); | |
457 virtual void VisitForInStatement(ForInStatement* node); | |
458 virtual void VisitSwitchStatement(SwitchStatement* node); | |
459 virtual void VisitReturnStatement(ReturnStatement* node); | |
460 virtual void VisitTryCatch(TryCatch* node); | |
461 virtual void VisitTryFinally(TryFinally* node); | |
462 virtual void VisitYieldStatement(YieldStatement* node); | |
463 virtual void VisitAssertStatement(AssertStatement* node); | |
464 | |
465 virtual void VisitFunctionNode(FunctionNode* node); | |
466 | |
467 virtual void VisitConstructor(Constructor* node); | |
468 | |
469 private: | |
470 void EnterScope(TreeNode* node); | |
471 void ExitScope(); | |
472 | |
473 LocalVariable* MakeVariable(const dart::String& name); | |
474 LocalVariable* MakeVariable(const dart::String& name, const Type& type); | |
475 | |
476 void AddParameters(FunctionNode* function, intptr_t pos = 0); | |
477 void AddParameter(VariableDeclaration* declaration, intptr_t pos); | |
478 void AddVariable(VariableDeclaration* declaration); | |
479 void AddExceptionVariable(GrowableArray<LocalVariable*>* variables, | |
480 const char* prefix, intptr_t nesting_depth); | |
481 void AddTryVariables(); | |
482 void AddCatchVariables(); | |
483 void AddIteratorVariable(); | |
484 void AddSwitchVariable(); | |
485 | |
486 // Record an assignment or reference to a variable. If the occurrence is | |
487 // in a nested function, ensure that the variable is handled properly as a | |
488 // captured variable. | |
489 void LookupVariable(VariableDeclaration* declaration); | |
490 | |
491 const dart::String& GenerateName(const char* prefix, intptr_t suffix); | |
492 | |
493 void HandleLocalFunction(TreeNode* parent, FunctionNode* function); | |
494 void HandleSpecialLoad(LocalVariable** variable, const dart::String& symbol); | |
495 void LookupCapturedVariableByName(LocalVariable** variable, | |
496 const dart::String& name); | |
497 | |
498 | |
499 struct DepthState { | |
500 explicit DepthState(intptr_t function) | |
501 : loop_(0), | |
502 function_(function), | |
503 try_(0), | |
504 catch_(0), | |
505 finally_(0), | |
506 for_in_(0) {} | |
507 | |
508 intptr_t loop_; | |
509 intptr_t function_; | |
510 intptr_t try_; | |
511 intptr_t catch_; | |
512 intptr_t finally_; | |
513 intptr_t for_in_; | |
514 }; | |
515 | |
516 ScopeBuildingResult* result_; | |
517 ParsedFunction* parsed_function_; | |
518 TreeNode* node_; | |
519 | |
520 Zone* zone_; | |
521 TranslationHelper translation_helper_; | |
522 | |
523 | |
524 FunctionNode* current_function_node_; | |
525 LocalScope* current_function_scope_; | |
526 LocalScope* scope_; | |
527 DepthState depth_; | |
528 | |
529 intptr_t name_index_; | |
530 }; | |
531 | |
532 | |
533 class FlowGraphBuilder : public TreeVisitor { | |
534 public: | |
535 FlowGraphBuilder(TreeNode* node, ParsedFunction* parsed_function, | |
536 const ZoneGrowableArray<const ICData*>& ic_data_array, | |
537 InlineExitCollector* exit_collector, intptr_t osr_id, | |
538 intptr_t first_block_id = 1); | |
539 virtual ~FlowGraphBuilder(); | |
540 | |
541 FlowGraph* BuildGraph(); | |
542 | |
543 virtual void VisitDefaultTreeNode(TreeNode* node) { UNREACHABLE(); } | |
544 | |
545 virtual void VisitInvalidExpression(InvalidExpression* node); | |
546 virtual void VisitNullLiteral(NullLiteral* node); | |
547 virtual void VisitBoolLiteral(BoolLiteral* node); | |
548 virtual void VisitIntLiteral(IntLiteral* node); | |
549 virtual void VisitBigintLiteral(BigintLiteral* node); | |
550 virtual void VisitDoubleLiteral(DoubleLiteral* node); | |
551 virtual void VisitStringLiteral(StringLiteral* node); | |
552 virtual void VisitSymbolLiteral(SymbolLiteral* node); | |
553 virtual void VisitTypeLiteral(TypeLiteral* node); | |
554 virtual void VisitVariableGet(VariableGet* node); | |
555 virtual void VisitVariableSet(VariableSet* node); | |
556 virtual void VisitStaticGet(StaticGet* node); | |
557 virtual void VisitStaticSet(StaticSet* node); | |
558 virtual void VisitPropertyGet(PropertyGet* node); | |
559 virtual void VisitPropertySet(PropertySet* node); | |
560 virtual void VisitDirectPropertyGet(DirectPropertyGet* node); | |
561 virtual void VisitDirectPropertySet(DirectPropertySet* node); | |
562 virtual void VisitStaticInvocation(StaticInvocation* node); | |
563 virtual void VisitMethodInvocation(MethodInvocation* node); | |
564 virtual void VisitDirectMethodInvocation(DirectMethodInvocation* node); | |
565 virtual void VisitConstructorInvocation(ConstructorInvocation* node); | |
566 virtual void VisitIsExpression(IsExpression* node); | |
567 virtual void VisitAsExpression(AsExpression* node); | |
568 virtual void VisitConditionalExpression(ConditionalExpression* node); | |
569 virtual void VisitLogicalExpression(LogicalExpression* node); | |
570 virtual void VisitNot(Not* node); | |
571 virtual void VisitThisExpression(ThisExpression* node); | |
572 virtual void VisitStringConcatenation(StringConcatenation* node); | |
573 virtual void VisitListLiteral(ListLiteral* node); | |
574 virtual void VisitMapLiteral(MapLiteral* node); | |
575 virtual void VisitFunctionExpression(FunctionExpression* node); | |
576 virtual void VisitLet(Let* node); | |
577 virtual void VisitThrow(Throw* node); | |
578 virtual void VisitRethrow(Rethrow* node); | |
579 virtual void VisitBlockExpression(BlockExpression* node); | |
580 | |
581 virtual void VisitInvalidStatement(InvalidStatement* node); | |
582 virtual void VisitEmptyStatement(EmptyStatement* node); | |
583 virtual void VisitBlock(Block* node); | |
584 virtual void VisitReturnStatement(ReturnStatement* node); | |
585 virtual void VisitExpressionStatement(ExpressionStatement* node); | |
586 virtual void VisitVariableDeclaration(VariableDeclaration* node); | |
587 virtual void VisitFunctionDeclaration(FunctionDeclaration* node); | |
588 virtual void VisitIfStatement(IfStatement* node); | |
589 virtual void VisitWhileStatement(WhileStatement* node); | |
590 virtual void VisitDoStatement(DoStatement* node); | |
591 virtual void VisitForStatement(ForStatement* node); | |
592 virtual void VisitForInStatement(ForInStatement* node); | |
593 virtual void VisitLabeledStatement(LabeledStatement* node); | |
594 virtual void VisitBreakStatement(BreakStatement* node); | |
595 virtual void VisitSwitchStatement(SwitchStatement* node); | |
596 virtual void VisitContinueSwitchStatement(ContinueSwitchStatement* node); | |
597 virtual void VisitAssertStatement(AssertStatement* node); | |
598 virtual void VisitTryFinally(TryFinally* node); | |
599 virtual void VisitTryCatch(TryCatch* node); | |
600 virtual void VisitYieldStatement(YieldStatement* node); | |
601 | |
602 private: | |
603 FlowGraph* BuildGraphOfFunction(FunctionNode* node, | |
604 Constructor* constructor = NULL); | |
605 FlowGraph* BuildGraphOfFieldAccessor(Field* node, | |
606 LocalVariable* setter_value); | |
607 FlowGraph* BuildGraphOfStaticFieldInitializer(Field* node); | |
608 FlowGraph* BuildGraphOfMethodExtractor(const Function& method); | |
609 FlowGraph* BuildGraphOfImplicitClosureFunction(FunctionNode* dil_function, | |
610 const Function& function); | |
611 FlowGraph* BuildGraphOfNoSuchMethodDispatcher(const Function& function); | |
612 FlowGraph* BuildGraphOfInvokeFieldDispatcher(const Function& function); | |
613 | |
614 Fragment NativeFunctionBody(FunctionNode* dil_function, | |
615 const Function& function); | |
616 | |
617 void SetupDefaultParameterValues(FunctionNode* function); | |
618 | |
619 TargetEntryInstr* BuildTargetEntry(); | |
620 JoinEntryInstr* BuildJoinEntry(); | |
621 | |
622 Fragment TranslateArguments(Arguments* node, Array* argument_names); | |
623 ArgumentArray GetArguments(int count); | |
624 | |
625 Fragment TranslateInitializers(Class* dil_klass, | |
626 List<Initializer>* initialiers); | |
627 | |
628 Fragment TranslateStatement(Statement* statement); | |
629 Fragment TranslateCondition(Expression* expression, bool* negate); | |
630 Fragment TranslateExpression(Expression* expression); | |
631 | |
632 Fragment TranslateFinallyFinalizers(TryFinallyBlock* outer_finally, | |
633 intptr_t target_context_depth); | |
634 | |
635 Fragment TranslateFunctionNode(FunctionNode* node, TreeNode* parent); | |
636 | |
637 Fragment EnterScope(TreeNode* node, bool* new_context = NULL); | |
638 Fragment ExitScope(TreeNode* node); | |
639 | |
640 Fragment LoadContextAt(int depth); | |
641 Fragment AdjustContextTo(int depth); | |
642 | |
643 Fragment PushContext(int size); | |
644 Fragment PopContext(); | |
645 | |
646 Fragment LoadInstantiatorTypeArguments(); | |
647 Fragment InstantiateTypeArguments(const TypeArguments& type_arguments); | |
648 Fragment TranslateInstantiatedTypeArguments( | |
649 const TypeArguments& type_arguments); | |
650 | |
651 Fragment AllocateContext(int size); | |
652 Fragment AllocateObject(const dart::Class& klass, intptr_t argument_count); | |
653 Fragment AllocateObject(const dart::Class& klass, | |
654 const Function& closure_function); | |
655 Fragment BooleanNegate(); | |
656 Fragment StrictCompare(Token::Kind kind, bool number_check = false); | |
657 Fragment BranchIfTrue(TargetEntryInstr** then_entry, | |
658 TargetEntryInstr** otherwise_entry, | |
659 bool negate = false); | |
660 Fragment BranchIfNull(TargetEntryInstr** then_entry, | |
661 TargetEntryInstr** otherwise_entry, | |
662 bool negate = false); | |
663 Fragment BranchIfEqual(TargetEntryInstr** then_entry, | |
664 TargetEntryInstr** otherwise_entry, | |
665 bool negate = false); | |
666 Fragment BranchIfStrictEqual(TargetEntryInstr** then_entry, | |
667 TargetEntryInstr** otherwise_entry); | |
668 Fragment CatchBlockEntry(const Array& handler_types, intptr_t handler_index); | |
669 Fragment TryCatch(int try_handler_index); | |
670 Fragment CheckStackOverflowInPrologue(); | |
671 Fragment CheckStackOverflow(); | |
672 Fragment CloneContext(); | |
673 Fragment Constant(const Object& value); | |
674 Fragment CreateArray(); | |
675 Fragment Goto(JoinEntryInstr* destination); | |
676 Fragment IntConstant(int64_t value); | |
677 Fragment InstanceCall(const dart::String& name, Token::Kind kind, | |
678 intptr_t argument_count, intptr_t num_args_checked = 1); | |
679 Fragment InstanceCall(const dart::String& name, Token::Kind kind, | |
680 intptr_t argument_count, const Array& argument_names, | |
681 intptr_t num_args_checked = 1); | |
682 Fragment ClosureCall(int argument_count, const Array& argument_names); | |
683 Fragment ThrowException(); | |
684 Fragment RethrowException(int catch_try_index); | |
685 Fragment LoadClassId(); | |
686 Fragment LoadField(const dart::Field& field); | |
687 Fragment LoadField(intptr_t offset, intptr_t class_id = kDynamicCid); | |
688 Fragment LoadNativeField(MethodRecognizer::Kind kind, intptr_t offset, | |
689 const Type& type, intptr_t class_id, | |
690 bool is_immutable = false); | |
691 Fragment LoadLocal(LocalVariable* variable); | |
692 Fragment InitStaticField(const dart::Field& field); | |
693 Fragment LoadStaticField(); | |
694 Fragment NullConstant(); | |
695 Fragment NativeCall(const dart::String* name, const Function* function); | |
696 Fragment PushArgument(); | |
697 Fragment Return(); | |
698 Fragment StaticCall(const Function& target, intptr_t argument_count); | |
699 Fragment StaticCall(const Function& target, intptr_t argument_count, | |
700 const Array& argument_names); | |
701 Fragment StoreIndexed(intptr_t class_id); | |
702 Fragment StoreInstanceField(const dart::Field& field); | |
703 Fragment StoreInstanceField(intptr_t offset); | |
704 Fragment StoreLocal(LocalVariable* variable); | |
705 Fragment StoreStaticField(const dart::Field& field); | |
706 Fragment StringInterpolate(); | |
707 Fragment ThrowTypeError(); | |
708 Fragment ThrowNoSuchMethodError(); | |
709 Fragment BuildImplicitClosureCreation(const Function& target); | |
710 | |
711 dart::RawFunction* LookupMethodByMember(Member* target, | |
712 const dart::String& method_name); | |
713 | |
714 LocalVariable* MakeTemporary(); | |
715 LocalVariable* MakeNonTemporary(const dart::String& symbol); | |
716 | |
717 intptr_t CurrentTryIndex(); | |
718 intptr_t AllocateTryIndex() { return next_used_try_index_++; } | |
719 | |
720 void AddVariable(VariableDeclaration* declaration, LocalVariable* variable); | |
721 void AddParameter(VariableDeclaration* declaration, LocalVariable* variable, | |
722 intptr_t pos); | |
723 dart::LocalVariable* LookupVariable(VariableDeclaration* var); | |
724 | |
725 void SetTempIndex(Definition* definition); | |
726 | |
727 void Push(Definition* definition); | |
728 Value* Pop(); | |
729 Fragment Drop(); | |
730 | |
731 bool IsInlining() { return exit_collector_ != NULL; } | |
732 | |
733 Token::Kind MethodKind(const dart::String& name); | |
734 | |
735 void InlineBailout(const char* reason); | |
736 | |
737 Zone* zone_; | |
738 TranslationHelper translation_helper_; | |
739 | |
740 // The node we are currently compiling (e.g. FunctionNode, Constructor, | |
741 // Field) | |
742 TreeNode* node_; | |
743 | |
744 ParsedFunction* parsed_function_; | |
745 intptr_t osr_id_; | |
746 const ZoneGrowableArray<const ICData*>& ic_data_array_; | |
747 InlineExitCollector* exit_collector_; | |
748 | |
749 intptr_t next_block_id_; | |
750 intptr_t AllocateBlockId() { return next_block_id_++; } | |
751 | |
752 intptr_t next_function_id_; | |
753 intptr_t AllocateFunctionId() { return next_function_id_++; } | |
754 | |
755 intptr_t context_depth_; | |
756 intptr_t loop_depth_; | |
757 intptr_t try_depth_; | |
758 intptr_t catch_depth_; | |
759 intptr_t for_in_depth_; | |
760 Fragment fragment_; | |
761 Value* stack_; | |
762 intptr_t pending_argument_count_; | |
763 | |
764 GraphEntryInstr* graph_entry_; | |
765 | |
766 ScopeBuildingResult* scopes_; | |
767 | |
768 struct YieldContinuation { | |
769 Instruction* entry; | |
770 intptr_t try_index; | |
771 | |
772 YieldContinuation(Instruction* entry, intptr_t try_index) | |
773 : entry(entry), try_index(try_index) {} | |
774 | |
775 YieldContinuation() | |
776 : entry(NULL), try_index(CatchClauseNode::kInvalidTryIndex) {} | |
777 }; | |
778 | |
779 GrowableArray<YieldContinuation> yield_continuations_; | |
780 | |
781 LocalVariable* CurrentException() { | |
782 return scopes_->exception_variables[catch_depth_ - 1]; | |
783 } | |
784 LocalVariable* CurrentStackTrace() { | |
785 return scopes_->stack_trace_variables[catch_depth_ - 1]; | |
786 } | |
787 LocalVariable* CurrentCatchContext() { | |
788 return scopes_->catch_context_variables[try_depth_]; | |
789 } | |
790 | |
791 // A chained list of breakable blocks. Chaining and lookup is done by the | |
792 // [BreakableBlock] class. | |
793 BreakableBlock* breakable_block_; | |
794 | |
795 // A chained list of switch blocks. Chaining and lookup is done by the | |
796 // [SwitchBlock] class. | |
797 SwitchBlock* switch_block_; | |
798 | |
799 // A chained list of try-finally blocks. Chaining and lookup is done by the | |
800 // [TryFinallyBlock] class. | |
801 TryFinallyBlock* try_finally_block_; | |
802 | |
803 // A chained list of try-catch blocks. Chaining and lookup is done by the | |
804 // [TryCatchBlock] class. | |
805 TryCatchBlock* try_catch_block_; | |
806 intptr_t next_used_try_index_; | |
807 | |
808 // A chained list of catch blocks. Chaining and lookup is done by the | |
809 // [CatchBlock] class. | |
810 CatchBlock* catch_block_; | |
811 | |
812 ActiveClass active_class_; | |
813 DartTypeTranslator type_translator_; | |
814 ConstantEvaluator constant_evaluator_; | |
815 | |
816 friend class BreakableBlock; | |
817 friend class CatchBlock; | |
818 friend class ConstantEvaluator; | |
819 friend class DartTypeTranslator; | |
820 friend class ScopeBuilder; | |
821 friend class SwitchBlock; | |
822 friend class TryCatchBlock; | |
823 friend class TryFinallyBlock; | |
824 }; | |
825 | |
826 } // namespace dil | |
827 } // namespace dart | |
828 | |
829 | |
830 #endif // VM_DIL_TO_IL_H_ | |
OLD | NEW |