Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: runtime/vm/kernel_binary_flowgraph.h

Issue 3001093002: Remove some "namespace" classes from C++ Kernel (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/kernel.h ('k') | runtime/vm/kernel_binary_flowgraph.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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_KERNEL_BINARY_FLOWGRAPH_H_ 5 #ifndef RUNTIME_VM_KERNEL_BINARY_FLOWGRAPH_H_
6 #define RUNTIME_VM_KERNEL_BINARY_FLOWGRAPH_H_ 6 #define RUNTIME_VM_KERNEL_BINARY_FLOWGRAPH_H_
7 7
8 #if !defined(DART_PRECOMPILED_RUNTIME) 8 #if !defined(DART_PRECOMPILED_RUNTIME)
9 9
10 #include <map> 10 #include <map>
11 11
12 #include "vm/kernel.h" 12 #include "vm/kernel.h"
13 #include "vm/kernel_binary.h" 13 #include "vm/kernel_binary.h"
14 #include "vm/kernel_to_il.h" 14 #include "vm/kernel_to_il.h"
15 #include "vm/object.h" 15 #include "vm/object.h"
16 16
17 namespace dart { 17 namespace dart {
18 namespace kernel { 18 namespace kernel {
19 19
20 class StreamingDartTypeTranslator {
Kevin Millikin (Google) 2017/08/17 12:29:25 The ...Helper classes were just moved before this,
21 public:
22 StreamingDartTypeTranslator(StreamingFlowGraphBuilder* builder,
23 bool finalize = false);
24
25 // Can return a malformed type.
26 AbstractType& BuildType();
27 // Can return a malformed type.
28 AbstractType& BuildTypeWithoutFinalization();
29 // Is guaranteed to be not malformed.
30 AbstractType& BuildVariableType();
31
32 // Will return `TypeArguments::null()` in case any of the arguments are
33 // malformed.
34 const TypeArguments& BuildTypeArguments(intptr_t length);
35
36 // Will return `TypeArguments::null()` in case any of the arguments are
37 // malformed.
38 const TypeArguments& BuildInstantiatedTypeArguments(
39 const dart::Class& receiver_class,
40 intptr_t length);
41
42 const Type& ReceiverType(const dart::Class& klass);
43
44 private:
45 // Can build a malformed type.
46 void BuildTypeInternal();
47 void BuildInterfaceType(bool simple);
48 void BuildFunctionType(bool simple);
49 void BuildTypeParameterType();
50
51 class TypeParameterScope {
52 public:
53 TypeParameterScope(StreamingDartTypeTranslator* translator,
54 intptr_t parameter_count)
55 : parameter_count_(parameter_count),
56 outer_(translator->type_parameter_scope_),
57 translator_(translator) {
58 outer_parameter_count_ = 0;
59 if (outer_ != NULL) {
60 outer_parameter_count_ =
61 outer_->outer_parameter_count_ + outer_->parameter_count_;
62 }
63 translator_->type_parameter_scope_ = this;
64 }
65 ~TypeParameterScope() { translator_->type_parameter_scope_ = outer_; }
66
67 TypeParameterScope* outer() const { return outer_; }
68 intptr_t parameter_count() const { return parameter_count_; }
69 intptr_t outer_parameter_count() const { return outer_parameter_count_; }
70
71 private:
72 intptr_t parameter_count_;
73 intptr_t outer_parameter_count_;
74 TypeParameterScope* outer_;
75 StreamingDartTypeTranslator* translator_;
76 };
77
78 StreamingFlowGraphBuilder* builder_;
79 TranslationHelper& translation_helper_;
80 ActiveClass* active_class_;
81 TypeParameterScope* type_parameter_scope_;
82 Zone* zone_;
83 AbstractType& result_;
84 bool finalize_;
85
86 friend class StreamingScopeBuilder;
87 friend class KernelReader;
88 };
89
90 class StreamingScopeBuilder {
91 public:
92 StreamingScopeBuilder(ParsedFunction* parsed_function,
93 intptr_t relative_kernel_offset,
94 const TypedData& data);
95
96 virtual ~StreamingScopeBuilder();
97
98 ScopeBuildingResult* BuildScopes();
99
100 private:
101 void VisitField();
102
103 void VisitProcedure();
104
105 void VisitConstructor();
106
107 void VisitFunctionNode();
108 void VisitNode();
109 void VisitInitializer();
110 void VisitExpression();
111 void VisitStatement();
112 void VisitArguments();
113 void VisitVariableDeclaration();
114 void VisitDartType();
115 void VisitInterfaceType(bool simple);
116 void VisitFunctionType(bool simple);
117 void VisitTypeParameterType();
118 void VisitVectorType();
119 void HandleLocalFunction(intptr_t parent_kernel_offset);
120
121 void EnterScope(intptr_t kernel_offset);
122 void ExitScope(TokenPosition start_position, TokenPosition end_position);
123
124 /**
125 * This assumes that the reader is at a FunctionNode,
126 * about to read the positional parameters.
127 */
128 void AddPositionalAndNamedParameters(intptr_t pos = 0);
129 /**
130 * This assumes that the reader is at a FunctionNode,
131 * about to read a parameter (i.e. VariableDeclaration).
132 */
133 void AddVariableDeclarationParameter(intptr_t pos);
134
135 LocalVariable* MakeVariable(TokenPosition declaration_pos,
136 TokenPosition token_pos,
137 const dart::String& name,
138 const AbstractType& type);
139
140 void AddExceptionVariable(GrowableArray<LocalVariable*>* variables,
141 const char* prefix,
142 intptr_t nesting_depth);
143
144 void AddTryVariables();
145 void AddCatchVariables();
146 void AddIteratorVariable();
147 void AddSwitchVariable();
148
149 // Record an assignment or reference to a variable. If the occurrence is
150 // in a nested function, ensure that the variable is handled properly as a
151 // captured variable.
152 void LookupVariable(intptr_t declaration_binary_offset);
153
154 const dart::String& GenerateName(const char* prefix, intptr_t suffix);
155
156 void HandleSpecialLoad(LocalVariable** variable, const dart::String& symbol);
157 void LookupCapturedVariableByName(LocalVariable** variable,
158 const dart::String& name);
159
160 struct DepthState {
161 explicit DepthState(intptr_t function)
162 : loop_(0),
163 function_(function),
164 try_(0),
165 catch_(0),
166 finally_(0),
167 for_in_(0) {}
168
169 intptr_t loop_;
170 intptr_t function_;
171 intptr_t try_;
172 intptr_t catch_;
173 intptr_t finally_;
174 intptr_t for_in_;
175 };
176
177 ScopeBuildingResult* result_;
178 ParsedFunction* parsed_function_;
179 intptr_t relative_kernel_offset_;
180
181 ActiveClass active_class_;
182
183 TranslationHelper translation_helper_;
184 Zone* zone_;
185
186 FunctionNode::AsyncMarker current_function_async_marker_;
187 LocalScope* current_function_scope_;
188 LocalScope* scope_;
189 DepthState depth_;
190
191 intptr_t name_index_;
192
193 bool needs_expr_temp_;
194 TokenPosition first_body_token_position_;
195
196 StreamingFlowGraphBuilder* builder_;
197 StreamingDartTypeTranslator type_translator_;
198 };
199
200 // There are several cases when we are compiling constant expressions:
201 //
202 // * constant field initializers:
203 // const FieldName = <expr>;
204 //
205 // * constant expressions:
206 // const [<expr>, ...]
207 // const {<expr> : <expr>, ...}
208 // const Constructor(<expr>, ...)
209 //
210 // * constant default parameters:
211 // f(a, [b = <expr>])
212 // f(a, {b: <expr>})
213 //
214 // * constant values to compare in a [SwitchCase]
215 // case <expr>:
216 //
217 // In all cases `<expr>` must be recursively evaluated and canonicalized at
218 // compile-time.
219 class StreamingConstantEvaluator {
220 public:
221 explicit StreamingConstantEvaluator(StreamingFlowGraphBuilder* builder);
222
223 virtual ~StreamingConstantEvaluator() {}
224
225 Instance& EvaluateExpression(intptr_t offset, bool reset_position = true);
226 Instance& EvaluateListLiteral(intptr_t offset, bool reset_position = true);
227 Instance& EvaluateMapLiteral(intptr_t offset, bool reset_position = true);
228 Instance& EvaluateConstructorInvocation(intptr_t offset,
229 bool reset_position = true);
230 Object& EvaluateExpressionSafe(intptr_t offset);
231
232 private:
233 void EvaluateVariableGet();
234 void EvaluateVariableGet(uint8_t payload);
235 void EvaluatePropertyGet();
236 void EvaluateStaticGet();
237 void EvaluateMethodInvocation();
238 void EvaluateStaticInvocation();
239 void EvaluateConstructorInvocationInternal();
240 void EvaluateNot();
241 void EvaluateLogicalExpression();
242 void EvaluateConditionalExpression();
243 void EvaluateStringConcatenation();
244 void EvaluateSymbolLiteral();
245 void EvaluateTypeLiteral();
246 void EvaluateListLiteralInternal();
247 void EvaluateMapLiteralInternal();
248 void EvaluateLet();
249 void EvaluateBigIntLiteral();
250 void EvaluateStringLiteral();
251 void EvaluateIntLiteral(uint8_t payload);
252 void EvaluateIntLiteral(bool is_negative);
253 void EvaluateDoubleLiteral();
254 void EvaluateBoolLiteral(bool value);
255 void EvaluateNullLiteral();
256
257 const Object& RunFunction(const Function& function,
258 intptr_t argument_count,
259 const Instance* receiver,
260 const TypeArguments* type_args);
261
262 const Object& RunFunction(const Function& function,
263 const Array& arguments,
264 const Array& names);
265
266 RawObject* EvaluateConstConstructorCall(const dart::Class& type_class,
267 const TypeArguments& type_arguments,
268 const Function& constructor,
269 const Object& argument);
270
271 const TypeArguments* TranslateTypeArguments(const Function& target,
272 dart::Class* target_klass);
273
274 void AssertBool() {
275 if (!result_.IsBool()) {
276 translation_helper_.ReportError("Expected boolean expression.");
277 }
278 }
279
280 bool EvaluateBooleanExpressionHere();
281
282 bool GetCachedConstant(intptr_t kernel_offset, Instance* value);
283 void CacheConstantValue(intptr_t kernel_offset, const Instance& value);
284
285 StreamingFlowGraphBuilder* builder_;
286 Isolate* isolate_;
287 Zone* zone_;
288 TranslationHelper& translation_helper_;
289 StreamingDartTypeTranslator& type_translator_;
290
291 Script& script_;
292 Instance& result_;
293 };
294
295 class FunctionNodeHelper;
296
297 class StreamingFlowGraphBuilder {
298 public:
299 StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder,
300 intptr_t relative_kernel_offset,
301 const TypedData& data)
302 : flow_graph_builder_(flow_graph_builder),
303 translation_helper_(flow_graph_builder->translation_helper_),
304 zone_(flow_graph_builder->zone_),
305 reader_(new Reader(data)),
306 constant_evaluator_(this),
307 type_translator_(this, /* finalize= */ true),
308 relative_kernel_offset_(relative_kernel_offset),
309 current_script_id_(-1),
310 record_for_script_id_(-1),
311 record_token_positions_into_(NULL),
312 record_yield_positions_into_(NULL) {}
313
314 StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
315 Zone* zone,
316 const uint8_t* buffer,
317 intptr_t buffer_length)
318 : flow_graph_builder_(NULL),
319 translation_helper_(*translation_helper),
320 zone_(zone),
321 reader_(new Reader(buffer, buffer_length)),
322 constant_evaluator_(this),
323 type_translator_(this, /* finalize= */ true),
324 relative_kernel_offset_(0),
325 current_script_id_(-1),
326 record_for_script_id_(-1),
327 record_token_positions_into_(NULL),
328 record_yield_positions_into_(NULL) {}
329
330 StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
331 Zone* zone,
332 intptr_t relative_kernel_offset,
333 const TypedData& data)
334 : flow_graph_builder_(NULL),
335 translation_helper_(*translation_helper),
336 zone_(zone),
337 reader_(new Reader(data)),
338 constant_evaluator_(this),
339 type_translator_(this, /* finalize= */ true),
340 relative_kernel_offset_(relative_kernel_offset),
341 current_script_id_(-1),
342 record_for_script_id_(-1),
343 record_token_positions_into_(NULL),
344 record_yield_positions_into_(NULL) {}
345
346 ~StreamingFlowGraphBuilder() { delete reader_; }
347
348 FlowGraph* BuildGraph(intptr_t kernel_offset);
349
350 Fragment BuildStatementAt(intptr_t kernel_offset);
351 RawObject* BuildParameterDescriptor(intptr_t kernel_offset);
352 RawObject* EvaluateMetadata(intptr_t kernel_offset);
353 void CollectTokenPositionsFor(
354 intptr_t script_index,
355 intptr_t initial_script_index,
356 GrowableArray<intptr_t>* record_token_positions_in,
357 GrowableArray<intptr_t>* record_yield_positions_in);
358 intptr_t SourceTableSize();
359 String& SourceTableUriFor(intptr_t index);
360 String& GetSourceFor(intptr_t index);
361 Array& GetLineStartsFor(intptr_t index);
362
363 private:
364 void DiscoverEnclosingElements(Zone* zone,
365 const Function& function,
366 Function* outermost_function);
367
368 void ReadUntilFunctionNode();
369 StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset,
370 const Function& function);
371
372 FlowGraph* BuildGraphOfStaticFieldInitializer();
373 FlowGraph* BuildGraphOfFieldAccessor(LocalVariable* setter_value);
374 void SetupDefaultParameterValues();
375 Fragment BuildFieldInitializer(NameIndex canonical_name);
376 Fragment BuildInitializers(const Class& parent_class);
377 FlowGraph* BuildGraphOfImplicitClosureFunction(const Function& function);
378 FlowGraph* BuildGraphOfConvertedClosureFunction(const Function& function);
379 FlowGraph* BuildGraphOfFunction(bool constructor);
380
381 Fragment BuildExpression(TokenPosition* position = NULL);
382 Fragment BuildStatement();
383
384 intptr_t ReaderOffset();
385 void SetOffset(intptr_t offset);
386 void SkipBytes(intptr_t skip);
387 bool ReadBool();
388 uint8_t ReadByte();
389 uint32_t ReadUInt();
390 uint32_t PeekUInt();
391 intptr_t ReadListLength();
392 StringIndex ReadStringReference();
393 NameIndex ReadCanonicalNameReference();
394 StringIndex ReadNameAsStringIndex();
395 const dart::String& ReadNameAsMethodName();
396 const dart::String& ReadNameAsGetterName();
397 const dart::String& ReadNameAsSetterName();
398 const dart::String& ReadNameAsFieldName();
399 void SkipStringReference();
400 void SkipCanonicalNameReference();
401 void SkipDartType();
402 void SkipOptionalDartType();
403 void SkipInterfaceType(bool simple);
404 void SkipFunctionType(bool simple);
405 void SkipListOfExpressions();
406 void SkipListOfDartTypes();
407 void SkipListOfStrings();
408 void SkipListOfVariableDeclarations();
409 void SkipTypeParametersList();
410 void SkipInitializer();
411 void SkipExpression();
412 void SkipStatement();
413 void SkipFunctionNode();
414 void SkipName();
415 void SkipArguments();
416 void SkipVariableDeclaration();
417 void SkipLibraryCombinator();
418 void SkipLibraryDependency();
419 void SkipLibraryPart();
420 void SkipLibraryTypedef();
421 TokenPosition ReadPosition(bool record = true);
422 void record_token_position(TokenPosition position);
423 void record_yield_position(TokenPosition position);
424 Tag ReadTag(uint8_t* payload = NULL);
425 Tag PeekTag(uint8_t* payload = NULL);
426 word ReadFlags();
427
428 void loop_depth_inc();
429 void loop_depth_dec();
430 intptr_t for_in_depth();
431 void for_in_depth_inc();
432 void for_in_depth_dec();
433 void catch_depth_inc();
434 void catch_depth_dec();
435 void try_depth_inc();
436 void try_depth_dec();
437 intptr_t CurrentTryIndex();
438 intptr_t AllocateTryIndex();
439 LocalVariable* CurrentException();
440 LocalVariable* CurrentStackTrace();
441 CatchBlock* catch_block();
442 ActiveClass* active_class();
443 ScopeBuildingResult* scopes();
444 void set_scopes(ScopeBuildingResult* scope);
445 ParsedFunction* parsed_function();
446 TryFinallyBlock* try_finally_block();
447 SwitchBlock* switch_block();
448 BreakableBlock* breakable_block();
449 GrowableArray<YieldContinuation>& yield_continuations();
450 Value* stack();
451 void Push(Definition* definition);
452 Value* Pop();
453
454 Tag PeekArgumentsFirstPositionalTag();
455 const TypeArguments& PeekArgumentsInstantiatedType(const dart::Class& klass);
456 intptr_t PeekArgumentsCount();
457 intptr_t PeekArgumentsTypeCount();
458 void SkipArgumentsBeforeActualArguments();
459
460 LocalVariable* LookupVariable(intptr_t kernel_offset);
461 LocalVariable* MakeTemporary();
462 Token::Kind MethodKind(const dart::String& name);
463 dart::RawFunction* LookupMethodByMember(NameIndex target,
464 const dart::String& method_name);
465
466 bool NeedsDebugStepCheck(const Function& function, TokenPosition position);
467 bool NeedsDebugStepCheck(Value* value, TokenPosition position);
468
469 void InlineBailout(const char* reason);
470 Fragment DebugStepCheck(TokenPosition position);
471 Fragment LoadLocal(LocalVariable* variable);
472 Fragment Return(TokenPosition position);
473 Fragment PushArgument();
474 Fragment EvaluateAssertion();
475 Fragment RethrowException(TokenPosition position, int catch_try_index);
476 Fragment ThrowNoSuchMethodError();
477 Fragment Constant(const Object& value);
478 Fragment IntConstant(int64_t value);
479 Fragment LoadStaticField();
480 Fragment StaticCall(TokenPosition position,
481 const Function& target,
482 intptr_t argument_count);
483 Fragment StaticCall(TokenPosition position,
484 const Function& target,
485 intptr_t argument_count,
486 const Array& argument_names,
487 intptr_t type_args_len = 0);
488 Fragment InstanceCall(TokenPosition position,
489 const dart::String& name,
490 Token::Kind kind,
491 intptr_t argument_count,
492 intptr_t checked_argument_count = 1);
493 Fragment InstanceCall(TokenPosition position,
494 const dart::String& name,
495 Token::Kind kind,
496 intptr_t type_args_len,
497 intptr_t argument_count,
498 const Array& argument_names,
499 intptr_t checked_argument_count);
500 Fragment ThrowException(TokenPosition position);
501 Fragment BooleanNegate();
502 Fragment TranslateInstantiatedTypeArguments(
503 const TypeArguments& type_arguments);
504 Fragment StrictCompare(Token::Kind kind, bool number_check = false);
505 Fragment AllocateObject(TokenPosition position,
506 const dart::Class& klass,
507 intptr_t argument_count);
508 Fragment AllocateObject(const dart::Class& klass,
509 const Function& closure_function);
510 Fragment AllocateContext(intptr_t size);
511 Fragment LoadField(intptr_t offset);
512 Fragment StoreLocal(TokenPosition position, LocalVariable* variable);
513 Fragment StoreStaticField(TokenPosition position, const dart::Field& field);
514 Fragment StoreInstanceField(TokenPosition position, intptr_t offset);
515 Fragment StringInterpolate(TokenPosition position);
516 Fragment StringInterpolateSingle(TokenPosition position);
517 Fragment ThrowTypeError();
518 Fragment LoadInstantiatorTypeArguments();
519 Fragment LoadFunctionTypeArguments();
520 Fragment InstantiateType(const AbstractType& type);
521 Fragment CreateArray();
522 Fragment StoreIndexed(intptr_t class_id);
523 Fragment CheckStackOverflow();
524 Fragment CloneContext();
525 Fragment TranslateFinallyFinalizers(TryFinallyBlock* outer_finally,
526 intptr_t target_context_depth);
527 Fragment BranchIfTrue(TargetEntryInstr** then_entry,
528 TargetEntryInstr** otherwise_entry,
529 bool negate);
530 Fragment BranchIfEqual(TargetEntryInstr** then_entry,
531 TargetEntryInstr** otherwise_entry,
532 bool negate);
533 Fragment BranchIfNull(TargetEntryInstr** then_entry,
534 TargetEntryInstr** otherwise_entry,
535 bool negate = false);
536 Fragment CatchBlockEntry(const Array& handler_types,
537 intptr_t handler_index,
538 bool needs_stacktrace);
539 Fragment TryCatch(int try_handler_index);
540 Fragment Drop();
541 Fragment NullConstant();
542 JoinEntryInstr* BuildJoinEntry();
543 JoinEntryInstr* BuildJoinEntry(intptr_t try_index);
544 Fragment Goto(JoinEntryInstr* destination);
545 Fragment BuildImplicitClosureCreation(const Function& target);
546 Fragment CheckBooleanInCheckedMode();
547 Fragment CheckAssignableInCheckedMode(const dart::AbstractType& dst_type,
548 const dart::String& dst_name);
549 Fragment CheckVariableTypeInCheckedMode(intptr_t variable_kernel_position);
550 Fragment CheckVariableTypeInCheckedMode(const AbstractType& dst_type,
551 const dart::String& name_symbol);
552 Fragment EnterScope(intptr_t kernel_offset, bool* new_context = NULL);
553 Fragment ExitScope(intptr_t kernel_offset);
554
555 Fragment TranslateCondition(bool* negate);
556 const TypeArguments& BuildTypeArguments();
557 Fragment BuildArguments(Array* argument_names,
558 intptr_t* argument_count,
559 bool skip_push_arguments = false,
560 bool do_drop = false);
561 Fragment BuildArgumentsFromActualArguments(Array* argument_names,
562 bool skip_push_arguments = false,
563 bool do_drop = false);
564
565 Fragment BuildInvalidExpression(TokenPosition* position);
566 Fragment BuildVariableGet(TokenPosition* position);
567 Fragment BuildVariableGet(uint8_t payload, TokenPosition* position);
568 Fragment BuildVariableSet(TokenPosition* position);
569 Fragment BuildVariableSet(uint8_t payload, TokenPosition* position);
570 Fragment BuildPropertyGet(TokenPosition* position);
571 Fragment BuildPropertySet(TokenPosition* position);
572 Fragment BuildDirectPropertyGet(TokenPosition* position);
573 Fragment BuildDirectPropertySet(TokenPosition* position);
574 Fragment BuildStaticGet(TokenPosition* position);
575 Fragment BuildStaticSet(TokenPosition* position);
576 Fragment BuildMethodInvocation(TokenPosition* position);
577 Fragment BuildDirectMethodInvocation(TokenPosition* position);
578 Fragment BuildStaticInvocation(bool is_const, TokenPosition* position);
579 Fragment BuildConstructorInvocation(bool is_const, TokenPosition* position);
580 Fragment BuildNot(TokenPosition* position);
581 Fragment BuildLogicalExpression(TokenPosition* position);
582 Fragment BuildConditionalExpression(TokenPosition* position);
583 Fragment BuildStringConcatenation(TokenPosition* position);
584 Fragment BuildIsExpression(TokenPosition* position);
585 Fragment BuildAsExpression(TokenPosition* position);
586 Fragment BuildSymbolLiteral(TokenPosition* position);
587 Fragment BuildTypeLiteral(TokenPosition* position);
588 Fragment BuildThisExpression(TokenPosition* position);
589 Fragment BuildRethrow(TokenPosition* position);
590 Fragment BuildThrow(TokenPosition* position);
591 Fragment BuildListLiteral(bool is_const, TokenPosition* position);
592 Fragment BuildMapLiteral(bool is_const, TokenPosition* position);
593 Fragment BuildFunctionExpression();
594 Fragment BuildLet(TokenPosition* position);
595 Fragment BuildBigIntLiteral(TokenPosition* position);
596 Fragment BuildStringLiteral(TokenPosition* position);
597 Fragment BuildIntLiteral(uint8_t payload, TokenPosition* position);
598 Fragment BuildIntLiteral(bool is_negative, TokenPosition* position);
599 Fragment BuildDoubleLiteral(TokenPosition* position);
600 Fragment BuildBoolLiteral(bool value, TokenPosition* position);
601 Fragment BuildNullLiteral(TokenPosition* position);
602 Fragment BuildVectorCreation(TokenPosition* position);
603 Fragment BuildVectorGet(TokenPosition* position);
604 Fragment BuildVectorSet(TokenPosition* position);
605 Fragment BuildVectorCopy(TokenPosition* position);
606 Fragment BuildClosureCreation(TokenPosition* position);
607
608 Fragment BuildInvalidStatement();
609 Fragment BuildExpressionStatement();
610 Fragment BuildBlock();
611 Fragment BuildEmptyStatement();
612 Fragment BuildAssertStatement();
613 Fragment BuildLabeledStatement();
614 Fragment BuildBreakStatement();
615 Fragment BuildWhileStatement();
616 Fragment BuildDoStatement();
617 Fragment BuildForStatement();
618 Fragment BuildForInStatement(bool async);
619 Fragment BuildSwitchStatement();
620 Fragment BuildContinueSwitchStatement();
621 Fragment BuildIfStatement();
622 Fragment BuildReturnStatement();
623 Fragment BuildTryCatch();
624 Fragment BuildTryFinally();
625 Fragment BuildYieldStatement();
626 Fragment BuildVariableDeclaration();
627 Fragment BuildFunctionDeclaration();
628 Fragment BuildFunctionNode(TokenPosition parent_position,
629 StringIndex name_index);
630 void SetupFunctionParameters(const dart::Class& klass,
631 const dart::Function& function,
632 bool is_method,
633 bool is_closure,
634 FunctionNodeHelper* function_node_helper);
635
636 FlowGraphBuilder* flow_graph_builder_;
637 TranslationHelper& translation_helper_;
638 Zone* zone_;
639 Reader* reader_;
640 StreamingConstantEvaluator constant_evaluator_;
641 StreamingDartTypeTranslator type_translator_;
642 intptr_t relative_kernel_offset_;
643 intptr_t current_script_id_;
644 intptr_t record_for_script_id_;
645 GrowableArray<intptr_t>* record_token_positions_into_;
646 GrowableArray<intptr_t>* record_yield_positions_into_;
647
648 friend class StreamingConstantEvaluator;
649 friend class StreamingDartTypeTranslator;
650 friend class StreamingScopeBuilder;
651 friend class FunctionNodeHelper;
652 friend class VariableDeclarationHelper;
653 friend class FieldHelper;
654 friend class ProcedureHelper;
655 friend class ClassHelper;
656 friend class LibraryHelper;
657 friend class ConstructorHelper;
658 friend class SimpleExpressionConverter;
659 friend class KernelReader;
660 };
661
662 // A helper class that saves the current reader position, goes to another reader
663 // position, and upon destruction, resets to the original reader position.
664 class AlternativeReadingScope {
665 public:
666 AlternativeReadingScope(Reader* reader, intptr_t new_position)
667 : reader_(reader),
668 saved_size_(reader_->size()),
669 saved_raw_buffer_(reader_->raw_buffer()),
670 saved_typed_data_(reader_->typed_data()),
671 saved_offset_(reader_->offset()) {
672 reader_->set_offset(new_position);
673 }
674
675 AlternativeReadingScope(Reader* reader,
676 const TypedData* new_typed_data,
677 intptr_t new_position)
678 : reader_(reader),
679 saved_size_(reader_->size()),
680 saved_raw_buffer_(reader_->raw_buffer()),
681 saved_typed_data_(reader_->typed_data()),
682 saved_offset_(reader_->offset()) {
683 reader_->set_raw_buffer(NULL);
684 reader_->set_typed_data(new_typed_data);
685 reader_->set_size(new_typed_data->Length());
686 reader_->set_offset(new_position);
687 }
688
689 explicit AlternativeReadingScope(Reader* reader)
690 : reader_(reader),
691 saved_size_(reader_->size()),
692 saved_raw_buffer_(reader_->raw_buffer()),
693 saved_typed_data_(reader_->typed_data()),
694 saved_offset_(reader_->offset()) {}
695
696 ~AlternativeReadingScope() {
697 reader_->set_raw_buffer(saved_raw_buffer_);
698 reader_->set_typed_data(saved_typed_data_);
699 reader_->set_size(saved_size_);
700 reader_->set_offset(saved_offset_);
701 }
702
703 intptr_t saved_offset() { return saved_offset_; }
704
705 private:
706 Reader* reader_;
707 intptr_t saved_size_;
708 const uint8_t* saved_raw_buffer_;
709 const TypedData* saved_typed_data_;
710 intptr_t saved_offset_;
711 };
712
713 // Helper class that reads a kernel FunctionNode from binary. 20 // Helper class that reads a kernel FunctionNode from binary.
714 // 21 //
715 // Use ReadUntilExcluding to read up to but not including a field. 22 // Use ReadUntilExcluding to read up to but not including a field.
716 // One can then for instance read the field from the call-site (and remember to 23 // One can then for instance read the field from the call-site (and remember to
717 // call SetAt to inform this helper class), and then use this to read more. 24 // call SetAt to inform this helper class), and then use this to read more.
718 // Simple fields are stored (e.g. integers) and can be fetched from this class. 25 // Simple fields are stored (e.g. integers) and can be fetched from this class.
719 // If asked to read a compound field (e.g. an expression) it will be skipped. 26 // If asked to read a compound field (e.g. an expression) it will be skipped.
720 class FunctionNodeHelper { 27 class FunctionNodeHelper {
721 public: 28 public:
722 enum Field { 29 enum Field {
723 kStart, // tag. 30 kStart, // tag.
724 kPosition, 31 kPosition,
725 kEndPosition, 32 kEndPosition,
726 kAsyncMarker, 33 kAsyncMarker,
727 kDartAsyncMarker, 34 kDartAsyncMarker,
728 kTypeParameters, 35 kTypeParameters,
729 kTotalParameterCount, 36 kTotalParameterCount,
730 kRequiredParameterCount, 37 kRequiredParameterCount,
731 kPositionalParameters, 38 kPositionalParameters,
732 kNamedParameters, 39 kNamedParameters,
733 kReturnType, 40 kReturnType,
734 kBody, 41 kBody,
735 kEnd 42 kEnd,
43 };
44
45 enum AsyncMarker {
46 kSync = 0,
47 kSyncStar = 1,
48 kAsync = 2,
49 kAsyncStar = 3,
50 kSyncYielding = 4,
736 }; 51 };
737 52
738 explicit FunctionNodeHelper(StreamingFlowGraphBuilder* builder) { 53 explicit FunctionNodeHelper(StreamingFlowGraphBuilder* builder) {
739 builder_ = builder; 54 builder_ = builder;
740 next_read_ = kStart; 55 next_read_ = kStart;
741 } 56 }
742 57
743 void ReadUntilIncluding(Field field) { 58 void ReadUntilIncluding(Field field) {
59 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
60 }
61
62 void ReadUntilExcluding(Field field);
63
64 void SetNext(Field field) { next_read_ = field; }
65 void SetJustRead(Field field) { next_read_ = field + 1; }
66
67 TokenPosition position_;
68 TokenPosition end_position_;
69 AsyncMarker async_marker_;
70 AsyncMarker dart_async_marker_;
71 intptr_t total_parameter_count_;
72 intptr_t required_parameter_count_;
73
74 private:
75 StreamingFlowGraphBuilder* builder_;
76 intptr_t next_read_;
77 };
78
79 // Helper class that reads a kernel VariableDeclaration from binary.
80 //
81 // Use ReadUntilExcluding to read up to but not including a field.
82 // One can then for instance read the field from the call-site (and remember to
83 // call SetAt to inform this helper class), and then use this to read more.
84 // Simple fields are stored (e.g. integers) and can be fetched from this class.
85 // If asked to read a compound field (e.g. an expression) it will be skipped.
86 class VariableDeclarationHelper {
87 public:
88 enum Field {
89 kPosition,
90 kEqualPosition,
91 kFlags,
92 kNameIndex,
93 kType,
94 kInitializer,
95 kEnd,
96 };
97
98 enum Flag {
99 kFinal = 1 << 0,
100 kConst = 1 << 1,
101 };
102
103 explicit VariableDeclarationHelper(StreamingFlowGraphBuilder* builder) {
104 builder_ = builder;
105 next_read_ = kPosition;
106 }
107
108 void ReadUntilIncluding(Field field) {
109 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
110 }
111
112 void ReadUntilExcluding(Field field);
113
114 void SetNext(Field field) { next_read_ = field; }
115 void SetJustRead(Field field) { next_read_ = field + 1; }
116
117 bool IsConst() { return (flags_ & kConst) != 0; }
118 bool IsFinal() { return (flags_ & kFinal) != 0; }
119
120 TokenPosition position_;
121 TokenPosition equals_position_;
122 word flags_;
123 StringIndex name_index_;
124
125 private:
126 StreamingFlowGraphBuilder* builder_;
127 intptr_t next_read_;
128 };
129
130 // Helper class that reads a kernel Field from binary.
131 //
132 // Use ReadUntilExcluding to read up to but not including a field.
133 // One can then for instance read the field from the call-site (and remember to
134 // call SetAt to inform this helper class), and then use this to read more.
135 // Simple fields are stored (e.g. integers) and can be fetched from this class.
136 // If asked to read a compound field (e.g. an expression) it will be skipped.
137 class FieldHelper {
138 public:
139 enum Field {
140 kStart, // tag.
141 kCanonicalName,
142 kPosition,
143 kEndPosition,
144 kFlags,
145 kName,
146 kSourceUriIndex,
147 kDocumentationCommentIndex,
148 kAnnotations,
149 kType,
150 kInitializer,
151 kEnd,
152 };
153
154 enum Flag {
155 kFinal = 1 << 0,
156 kConst = 1 << 1,
157 kStatic = 1 << 2,
158 };
159
160 explicit FieldHelper(StreamingFlowGraphBuilder* builder)
161 : builder_(builder),
162 next_read_(kStart),
163 has_function_literal_initializer_(false) {}
164
165 FieldHelper(StreamingFlowGraphBuilder* builder, intptr_t offset);
166
167 void ReadUntilIncluding(Field field) {
168 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
169 }
170
171 void ReadUntilExcluding(Field field,
172 bool detect_function_literal_initializer = false);
173
174 void SetNext(Field field) { next_read_ = field; }
175 void SetJustRead(Field field) { next_read_ = field + 1; }
176
177 bool IsConst() { return (flags_ & kConst) != 0; }
178 bool IsFinal() { return (flags_ & kFinal) != 0; }
179 bool IsStatic() { return (flags_ & kStatic) != 0; }
180
181 bool FieldHasFunctionLiteralInitializer(TokenPosition* start,
182 TokenPosition* end) {
183 if (has_function_literal_initializer_) {
184 *start = function_literal_start_;
185 *end = function_literal_end_;
186 }
187 return has_function_literal_initializer_;
188 }
189
190 NameIndex canonical_name_;
191 TokenPosition position_;
192 TokenPosition end_position_;
193 word flags_;
194 intptr_t source_uri_index_;
195 intptr_t annotation_count_;
196
197 private:
198 StreamingFlowGraphBuilder* builder_;
199 intptr_t next_read_;
200
201 bool has_function_literal_initializer_;
202 TokenPosition function_literal_start_;
203 TokenPosition function_literal_end_;
204 };
205
206 // Helper class that reads a kernel Procedure from binary.
207 //
208 // Use ReadUntilExcluding to read up to but not including a field.
209 // One can then for instance read the field from the call-site (and remember to
210 // call SetAt to inform this helper class), and then use this to read more.
211 // Simple fields are stored (e.g. integers) and can be fetched from this class.
212 // If asked to read a compound field (e.g. an expression) it will be skipped.
213 class ProcedureHelper {
214 public:
215 enum Field {
216 kStart, // tag.
217 kCanonicalName,
218 kPosition,
219 kEndPosition,
220 kKind,
221 kFlags,
222 kName,
223 kSourceUriIndex,
224 kDocumentationCommentIndex,
225 kAnnotations,
226 kFunction,
227 kEnd,
228 };
229
230 enum Kind {
231 kMethod,
232 kGetter,
233 kSetter,
234 kOperator,
235 kFactory,
236 };
237
238 enum Flag {
239 kStatic = 1 << 0,
240 kAbstract = 1 << 1,
241 kExternal = 1 << 2,
242 kConst = 1 << 3, // Only for external const factories.
243 };
244
245 explicit ProcedureHelper(StreamingFlowGraphBuilder* builder) {
246 builder_ = builder;
247 next_read_ = kStart;
248 }
249
250 void ReadUntilIncluding(Field field) {
251 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
252 }
253
254 void ReadUntilExcluding(Field field);
255
256 void SetNext(Field field) { next_read_ = field; }
257 void SetJustRead(Field field) { next_read_ = field + 1; }
258
259 bool IsStatic() { return (flags_ & kStatic) != 0; }
260 bool IsAbstract() { return (flags_ & kAbstract) != 0; }
261 bool IsExternal() { return (flags_ & kExternal) != 0; }
262 bool IsConst() { return (flags_ & kConst) != 0; }
263
264 NameIndex canonical_name_;
265 TokenPosition position_;
266 TokenPosition end_position_;
267 Kind kind_;
268 word flags_;
269 intptr_t source_uri_index_;
270 intptr_t annotation_count_;
271
272 private:
273 StreamingFlowGraphBuilder* builder_;
274 intptr_t next_read_;
275 };
276
277 // Helper class that reads a kernel Constructor from binary.
278 //
279 // Use ReadUntilExcluding to read up to but not including a field.
280 // One can then for instance read the field from the call-site (and remember to
281 // call SetAt to inform this helper class), and then use this to read more.
282 // Simple fields are stored (e.g. integers) and can be fetched from this class.
283 // If asked to read a compound field (e.g. an expression) it will be skipped.
284 class ConstructorHelper {
285 public:
286 enum Field {
287 kStart, // tag.
288 kCanonicalName,
289 kPosition,
290 kEndPosition,
291 kFlags,
292 kName,
293 kDocumentationCommentIndex,
294 kAnnotations,
295 kFunction,
296 kInitializers,
297 kEnd,
298 };
299
300 enum Flag {
301 kConst = 1 << 0,
302 kExternal = 1 << 1,
303 };
304
305 explicit ConstructorHelper(StreamingFlowGraphBuilder* builder) {
306 builder_ = builder;
307 next_read_ = kStart;
308 }
309
310 void ReadUntilIncluding(Field field) {
311 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
312 }
313
314 void ReadUntilExcluding(Field field);
315
316 void SetNext(Field field) { next_read_ = field; }
317 void SetJustRead(Field field) { next_read_ = field + 1; }
318
319 bool IsExternal() { return (flags_ & kExternal) != 0; }
320 bool IsConst() { return (flags_ & kConst) != 0; }
321
322 NameIndex canonical_name_;
323 TokenPosition position_;
324 TokenPosition end_position_;
325 word flags_;
326 intptr_t annotation_count_;
327
328 private:
329 StreamingFlowGraphBuilder* builder_;
330 intptr_t next_read_;
331 };
332
333 // Helper class that reads a kernel Class from binary.
334 //
335 // Use ReadUntilExcluding to read up to but not including a field.
336 // One can then for instance read the field from the call-site (and remember to
337 // call SetAt to inform this helper class), and then use this to read more.
338 // Simple fields are stored (e.g. integers) and can be fetched from this class.
339 // If asked to read a compound field (e.g. an expression) it will be skipped.
340 class ClassHelper {
341 public:
342 enum Field {
343 kStart, // tag.
344 kCanonicalName,
345 kPosition,
346 kEndPosition,
347 kIsAbstract,
348 kNameIndex,
349 kSourceUriIndex,
350 kDocumentationCommentIndex,
351 kAnnotations,
352 kTypeParameters,
353 kSuperClass,
354 kMixinType,
355 kImplementedClasses,
356 kFields,
357 kConstructors,
358 kProcedures,
359 kEnd,
360 };
361
362 explicit ClassHelper(StreamingFlowGraphBuilder* builder) {
363 builder_ = builder;
364 next_read_ = kStart;
365 }
366
367 void ReadUntilIncluding(Field field) {
368 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
369 }
370
371 void ReadUntilExcluding(Field field);
372
373 void SetNext(Field field) { next_read_ = field; }
374 void SetJustRead(Field field) { next_read_ = field + 1; }
375
376 NameIndex canonical_name_;
377 TokenPosition position_;
378 TokenPosition end_position_;
379 bool is_abstract_;
380 StringIndex name_index_;
381 intptr_t source_uri_index_;
382 intptr_t annotation_count_;
383
384 private:
385 StreamingFlowGraphBuilder* builder_;
386 intptr_t next_read_;
387 };
388
389 // Helper class that reads a kernel Library from binary.
390 //
391 // Use ReadUntilExcluding to read up to but not including a field.
392 // One can then for instance read the field from the call-site (and remember to
393 // call SetAt to inform this helper class), and then use this to read more.
394 // Simple fields are stored (e.g. integers) and can be fetched from this class.
395 // If asked to read a compound field (e.g. an expression) it will be skipped.
396 class LibraryHelper {
397 public:
398 enum Field {
399 kFlags,
400 kCanonicalName,
401 kName,
402 kSourceUriIndex,
403 kAnnotations,
404 kDependencies,
405 kParts,
406 kTypedefs,
407 kClasses,
408 kToplevelField,
409 kToplevelProcedures,
410 kEnd,
411 };
412
413 explicit LibraryHelper(StreamingFlowGraphBuilder* builder) {
414 builder_ = builder;
415 next_read_ = kFlags;
416 }
417
418 void ReadUntilIncluding(Field field) {
744 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1)); 419 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
745 } 420 }
746 421
747 void ReadUntilExcluding(Field field); 422 void ReadUntilExcluding(Field field);
748 423
749 void SetNext(Field field) { next_read_ = field; } 424 void SetNext(Field field) { next_read_ = field; }
750 void SetJustRead(Field field) { next_read_ = field + 1; } 425 void SetJustRead(Field field) { next_read_ = field + 1; }
751 426
752 TokenPosition position_; 427 NameIndex canonical_name_;
753 TokenPosition end_position_; 428 StringIndex name_index_;
754 FunctionNode::AsyncMarker async_marker_; 429 intptr_t source_uri_index_;
755 FunctionNode::AsyncMarker dart_async_marker_;
756 intptr_t total_parameter_count_;
757 intptr_t required_parameter_count_;
758 430
759 private: 431 private:
760 StreamingFlowGraphBuilder* builder_; 432 StreamingFlowGraphBuilder* builder_;
761 intptr_t next_read_; 433 intptr_t next_read_;
762 }; 434 };
763 435
764 // Helper class that reads a kernel VariableDeclaration from binary. 436 class StreamingDartTypeTranslator {
437 public:
438 StreamingDartTypeTranslator(StreamingFlowGraphBuilder* builder,
439 bool finalize = false);
440
441 // Can return a malformed type.
442 AbstractType& BuildType();
443 // Can return a malformed type.
444 AbstractType& BuildTypeWithoutFinalization();
445 // Is guaranteed to be not malformed.
446 AbstractType& BuildVariableType();
447
448 // Will return `TypeArguments::null()` in case any of the arguments are
449 // malformed.
450 const TypeArguments& BuildTypeArguments(intptr_t length);
451
452 // Will return `TypeArguments::null()` in case any of the arguments are
453 // malformed.
454 const TypeArguments& BuildInstantiatedTypeArguments(
455 const dart::Class& receiver_class,
456 intptr_t length);
457
458 const Type& ReceiverType(const dart::Class& klass);
459
460 private:
461 // Can build a malformed type.
462 void BuildTypeInternal();
463 void BuildInterfaceType(bool simple);
464 void BuildFunctionType(bool simple);
465 void BuildTypeParameterType();
466
467 class TypeParameterScope {
468 public:
469 TypeParameterScope(StreamingDartTypeTranslator* translator,
470 intptr_t parameter_count)
471 : parameter_count_(parameter_count),
472 outer_(translator->type_parameter_scope_),
473 translator_(translator) {
474 outer_parameter_count_ = 0;
475 if (outer_ != NULL) {
476 outer_parameter_count_ =
477 outer_->outer_parameter_count_ + outer_->parameter_count_;
478 }
479 translator_->type_parameter_scope_ = this;
480 }
481 ~TypeParameterScope() { translator_->type_parameter_scope_ = outer_; }
482
483 TypeParameterScope* outer() const { return outer_; }
484 intptr_t parameter_count() const { return parameter_count_; }
485 intptr_t outer_parameter_count() const { return outer_parameter_count_; }
486
487 private:
488 intptr_t parameter_count_;
489 intptr_t outer_parameter_count_;
490 TypeParameterScope* outer_;
491 StreamingDartTypeTranslator* translator_;
492 };
493
494 StreamingFlowGraphBuilder* builder_;
495 TranslationHelper& translation_helper_;
496 ActiveClass* active_class_;
497 TypeParameterScope* type_parameter_scope_;
498 Zone* zone_;
499 AbstractType& result_;
500 bool finalize_;
501
502 friend class StreamingScopeBuilder;
503 friend class KernelReader;
504 };
505
506 class StreamingScopeBuilder {
507 public:
508 StreamingScopeBuilder(ParsedFunction* parsed_function,
509 intptr_t relative_kernel_offset,
510 const TypedData& data);
511
512 virtual ~StreamingScopeBuilder();
513
514 ScopeBuildingResult* BuildScopes();
515
516 private:
517 void VisitField();
518
519 void VisitProcedure();
520
521 void VisitConstructor();
522
523 void VisitFunctionNode();
524 void VisitNode();
525 void VisitInitializer();
526 void VisitExpression();
527 void VisitStatement();
528 void VisitArguments();
529 void VisitVariableDeclaration();
530 void VisitDartType();
531 void VisitInterfaceType(bool simple);
532 void VisitFunctionType(bool simple);
533 void VisitTypeParameterType();
534 void VisitVectorType();
535 void HandleLocalFunction(intptr_t parent_kernel_offset);
536
537 void EnterScope(intptr_t kernel_offset);
538 void ExitScope(TokenPosition start_position, TokenPosition end_position);
539
540 /**
541 * This assumes that the reader is at a FunctionNode,
542 * about to read the positional parameters.
543 */
544 void AddPositionalAndNamedParameters(intptr_t pos = 0);
545 /**
546 * This assumes that the reader is at a FunctionNode,
547 * about to read a parameter (i.e. VariableDeclaration).
548 */
549 void AddVariableDeclarationParameter(intptr_t pos);
550
551 LocalVariable* MakeVariable(TokenPosition declaration_pos,
552 TokenPosition token_pos,
553 const dart::String& name,
554 const AbstractType& type);
555
556 void AddExceptionVariable(GrowableArray<LocalVariable*>* variables,
557 const char* prefix,
558 intptr_t nesting_depth);
559
560 void AddTryVariables();
561 void AddCatchVariables();
562 void AddIteratorVariable();
563 void AddSwitchVariable();
564
565 // Record an assignment or reference to a variable. If the occurrence is
566 // in a nested function, ensure that the variable is handled properly as a
567 // captured variable.
568 void LookupVariable(intptr_t declaration_binary_offset);
569
570 const dart::String& GenerateName(const char* prefix, intptr_t suffix);
571
572 void HandleSpecialLoad(LocalVariable** variable, const dart::String& symbol);
573 void LookupCapturedVariableByName(LocalVariable** variable,
574 const dart::String& name);
575
576 struct DepthState {
577 explicit DepthState(intptr_t function)
578 : loop_(0),
579 function_(function),
580 try_(0),
581 catch_(0),
582 finally_(0),
583 for_in_(0) {}
584
585 intptr_t loop_;
586 intptr_t function_;
587 intptr_t try_;
588 intptr_t catch_;
589 intptr_t finally_;
590 intptr_t for_in_;
591 };
592
593 ScopeBuildingResult* result_;
594 ParsedFunction* parsed_function_;
595 intptr_t relative_kernel_offset_;
596
597 ActiveClass active_class_;
598
599 TranslationHelper translation_helper_;
600 Zone* zone_;
601
602 FunctionNodeHelper::AsyncMarker current_function_async_marker_;
603 LocalScope* current_function_scope_;
604 LocalScope* scope_;
605 DepthState depth_;
606
607 intptr_t name_index_;
608
609 bool needs_expr_temp_;
610 TokenPosition first_body_token_position_;
611
612 StreamingFlowGraphBuilder* builder_;
613 StreamingDartTypeTranslator type_translator_;
614 };
615
616 // There are several cases when we are compiling constant expressions:
765 // 617 //
766 // Use ReadUntilExcluding to read up to but not including a field. 618 // * constant field initializers:
767 // One can then for instance read the field from the call-site (and remember to 619 // const FieldName = <expr>;
768 // call SetAt to inform this helper class), and then use this to read more. 620 //
769 // Simple fields are stored (e.g. integers) and can be fetched from this class. 621 // * constant expressions:
770 // If asked to read a compound field (e.g. an expression) it will be skipped. 622 // const [<expr>, ...]
771 class VariableDeclarationHelper { 623 // const {<expr> : <expr>, ...}
624 // const Constructor(<expr>, ...)
625 //
626 // * constant default parameters:
627 // f(a, [b = <expr>])
628 // f(a, {b: <expr>})
629 //
630 // * constant values to compare in a [SwitchCase]
631 // case <expr>:
632 //
633 // In all cases `<expr>` must be recursively evaluated and canonicalized at
634 // compile-time.
635 class StreamingConstantEvaluator {
772 public: 636 public:
773 enum Field { 637 explicit StreamingConstantEvaluator(StreamingFlowGraphBuilder* builder);
774 kPosition, 638
775 kEqualPosition, 639 virtual ~StreamingConstantEvaluator() {}
776 kFlags, 640
777 kNameIndex, 641 Instance& EvaluateExpression(intptr_t offset, bool reset_position = true);
778 kType, 642 Instance& EvaluateListLiteral(intptr_t offset, bool reset_position = true);
779 kInitializer, 643 Instance& EvaluateMapLiteral(intptr_t offset, bool reset_position = true);
780 kEnd 644 Instance& EvaluateConstructorInvocation(intptr_t offset,
781 }; 645 bool reset_position = true);
782 646 Object& EvaluateExpressionSafe(intptr_t offset);
783 explicit VariableDeclarationHelper(StreamingFlowGraphBuilder* builder) { 647
784 builder_ = builder; 648 private:
785 next_read_ = kPosition; 649 void EvaluateVariableGet();
650 void EvaluateVariableGet(uint8_t payload);
651 void EvaluatePropertyGet();
652 void EvaluateStaticGet();
653 void EvaluateMethodInvocation();
654 void EvaluateStaticInvocation();
655 void EvaluateConstructorInvocationInternal();
656 void EvaluateNot();
657 void EvaluateLogicalExpression();
658 void EvaluateConditionalExpression();
659 void EvaluateStringConcatenation();
660 void EvaluateSymbolLiteral();
661 void EvaluateTypeLiteral();
662 void EvaluateListLiteralInternal();
663 void EvaluateMapLiteralInternal();
664 void EvaluateLet();
665 void EvaluateBigIntLiteral();
666 void EvaluateStringLiteral();
667 void EvaluateIntLiteral(uint8_t payload);
668 void EvaluateIntLiteral(bool is_negative);
669 void EvaluateDoubleLiteral();
670 void EvaluateBoolLiteral(bool value);
671 void EvaluateNullLiteral();
672
673 const Object& RunFunction(const Function& function,
674 intptr_t argument_count,
675 const Instance* receiver,
676 const TypeArguments* type_args);
677
678 const Object& RunFunction(const Function& function,
679 const Array& arguments,
680 const Array& names);
681
682 RawObject* EvaluateConstConstructorCall(const dart::Class& type_class,
683 const TypeArguments& type_arguments,
684 const Function& constructor,
685 const Object& argument);
686
687 const TypeArguments* TranslateTypeArguments(const Function& target,
688 dart::Class* target_klass);
689
690 void AssertBool() {
691 if (!result_.IsBool()) {
692 translation_helper_.ReportError("Expected boolean expression.");
693 }
786 } 694 }
787 695
788 void ReadUntilIncluding(Field field) { 696 bool EvaluateBooleanExpressionHere();
789 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1)); 697
698 bool GetCachedConstant(intptr_t kernel_offset, Instance* value);
699 void CacheConstantValue(intptr_t kernel_offset, const Instance& value);
700
701 StreamingFlowGraphBuilder* builder_;
702 Isolate* isolate_;
703 Zone* zone_;
704 TranslationHelper& translation_helper_;
705 StreamingDartTypeTranslator& type_translator_;
706
707 Script& script_;
708 Instance& result_;
709 };
710
711 class StreamingFlowGraphBuilder {
712 public:
713 StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder,
714 intptr_t relative_kernel_offset,
715 const TypedData& data)
716 : flow_graph_builder_(flow_graph_builder),
717 translation_helper_(flow_graph_builder->translation_helper_),
718 zone_(flow_graph_builder->zone_),
719 reader_(new Reader(data)),
720 constant_evaluator_(this),
721 type_translator_(this, /* finalize= */ true),
722 relative_kernel_offset_(relative_kernel_offset),
723 current_script_id_(-1),
724 record_for_script_id_(-1),
725 record_token_positions_into_(NULL),
726 record_yield_positions_into_(NULL) {}
727
728 StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
729 Zone* zone,
730 const uint8_t* buffer,
731 intptr_t buffer_length)
732 : flow_graph_builder_(NULL),
733 translation_helper_(*translation_helper),
734 zone_(zone),
735 reader_(new Reader(buffer, buffer_length)),
736 constant_evaluator_(this),
737 type_translator_(this, /* finalize= */ true),
738 relative_kernel_offset_(0),
739 current_script_id_(-1),
740 record_for_script_id_(-1),
741 record_token_positions_into_(NULL),
742 record_yield_positions_into_(NULL) {}
743
744 StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
745 Zone* zone,
746 intptr_t relative_kernel_offset,
747 const TypedData& data)
748 : flow_graph_builder_(NULL),
749 translation_helper_(*translation_helper),
750 zone_(zone),
751 reader_(new Reader(data)),
752 constant_evaluator_(this),
753 type_translator_(this, /* finalize= */ true),
754 relative_kernel_offset_(relative_kernel_offset),
755 current_script_id_(-1),
756 record_for_script_id_(-1),
757 record_token_positions_into_(NULL),
758 record_yield_positions_into_(NULL) {}
759
760 ~StreamingFlowGraphBuilder() { delete reader_; }
761
762 FlowGraph* BuildGraph(intptr_t kernel_offset);
763
764 Fragment BuildStatementAt(intptr_t kernel_offset);
765 RawObject* BuildParameterDescriptor(intptr_t kernel_offset);
766 RawObject* EvaluateMetadata(intptr_t kernel_offset);
767 void CollectTokenPositionsFor(
768 intptr_t script_index,
769 intptr_t initial_script_index,
770 GrowableArray<intptr_t>* record_token_positions_in,
771 GrowableArray<intptr_t>* record_yield_positions_in);
772 intptr_t SourceTableSize();
773 String& SourceTableUriFor(intptr_t index);
774 String& GetSourceFor(intptr_t index);
775 Array& GetLineStartsFor(intptr_t index);
776
777 private:
778 void DiscoverEnclosingElements(Zone* zone,
779 const Function& function,
780 Function* outermost_function);
781
782 void ReadUntilFunctionNode();
783 StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset,
784 const Function& function);
785
786 FlowGraph* BuildGraphOfStaticFieldInitializer();
787 FlowGraph* BuildGraphOfFieldAccessor(LocalVariable* setter_value);
788 void SetupDefaultParameterValues();
789 Fragment BuildFieldInitializer(NameIndex canonical_name);
790 Fragment BuildInitializers(const Class& parent_class);
791 FlowGraph* BuildGraphOfImplicitClosureFunction(const Function& function);
792 FlowGraph* BuildGraphOfConvertedClosureFunction(const Function& function);
793 FlowGraph* BuildGraphOfFunction(bool constructor);
794
795 Fragment BuildExpression(TokenPosition* position = NULL);
796 Fragment BuildStatement();
797
798 intptr_t ReaderOffset();
799 void SetOffset(intptr_t offset);
800 void SkipBytes(intptr_t skip);
801 bool ReadBool();
802 uint8_t ReadByte();
803 uint32_t ReadUInt();
804 uint32_t PeekUInt();
805 intptr_t ReadListLength();
806 StringIndex ReadStringReference();
807 NameIndex ReadCanonicalNameReference();
808 StringIndex ReadNameAsStringIndex();
809 const dart::String& ReadNameAsMethodName();
810 const dart::String& ReadNameAsGetterName();
811 const dart::String& ReadNameAsSetterName();
812 const dart::String& ReadNameAsFieldName();
813 void SkipStringReference();
814 void SkipCanonicalNameReference();
815 void SkipDartType();
816 void SkipOptionalDartType();
817 void SkipInterfaceType(bool simple);
818 void SkipFunctionType(bool simple);
819 void SkipListOfExpressions();
820 void SkipListOfDartTypes();
821 void SkipListOfStrings();
822 void SkipListOfVariableDeclarations();
823 void SkipTypeParametersList();
824 void SkipInitializer();
825 void SkipExpression();
826 void SkipStatement();
827 void SkipFunctionNode();
828 void SkipName();
829 void SkipArguments();
830 void SkipVariableDeclaration();
831 void SkipLibraryCombinator();
832 void SkipLibraryDependency();
833 void SkipLibraryPart();
834 void SkipLibraryTypedef();
835 TokenPosition ReadPosition(bool record = true);
836 void record_token_position(TokenPosition position);
837 void record_yield_position(TokenPosition position);
838 Tag ReadTag(uint8_t* payload = NULL);
839 Tag PeekTag(uint8_t* payload = NULL);
840 word ReadFlags();
841
842 void loop_depth_inc();
843 void loop_depth_dec();
844 intptr_t for_in_depth();
845 void for_in_depth_inc();
846 void for_in_depth_dec();
847 void catch_depth_inc();
848 void catch_depth_dec();
849 void try_depth_inc();
850 void try_depth_dec();
851 intptr_t CurrentTryIndex();
852 intptr_t AllocateTryIndex();
853 LocalVariable* CurrentException();
854 LocalVariable* CurrentStackTrace();
855 CatchBlock* catch_block();
856 ActiveClass* active_class();
857 ScopeBuildingResult* scopes();
858 void set_scopes(ScopeBuildingResult* scope);
859 ParsedFunction* parsed_function();
860 TryFinallyBlock* try_finally_block();
861 SwitchBlock* switch_block();
862 BreakableBlock* breakable_block();
863 GrowableArray<YieldContinuation>& yield_continuations();
864 Value* stack();
865 void Push(Definition* definition);
866 Value* Pop();
867
868 Tag PeekArgumentsFirstPositionalTag();
869 const TypeArguments& PeekArgumentsInstantiatedType(const dart::Class& klass);
870 intptr_t PeekArgumentsCount();
871 intptr_t PeekArgumentsTypeCount();
872 void SkipArgumentsBeforeActualArguments();
873
874 LocalVariable* LookupVariable(intptr_t kernel_offset);
875 LocalVariable* MakeTemporary();
876 Token::Kind MethodKind(const dart::String& name);
877 dart::RawFunction* LookupMethodByMember(NameIndex target,
878 const dart::String& method_name);
879
880 bool NeedsDebugStepCheck(const Function& function, TokenPosition position);
881 bool NeedsDebugStepCheck(Value* value, TokenPosition position);
882
883 void InlineBailout(const char* reason);
884 Fragment DebugStepCheck(TokenPosition position);
885 Fragment LoadLocal(LocalVariable* variable);
886 Fragment Return(TokenPosition position);
887 Fragment PushArgument();
888 Fragment EvaluateAssertion();
889 Fragment RethrowException(TokenPosition position, int catch_try_index);
890 Fragment ThrowNoSuchMethodError();
891 Fragment Constant(const Object& value);
892 Fragment IntConstant(int64_t value);
893 Fragment LoadStaticField();
894 Fragment StaticCall(TokenPosition position,
895 const Function& target,
896 intptr_t argument_count);
897 Fragment StaticCall(TokenPosition position,
898 const Function& target,
899 intptr_t argument_count,
900 const Array& argument_names,
901 intptr_t type_args_len = 0);
902 Fragment InstanceCall(TokenPosition position,
903 const dart::String& name,
904 Token::Kind kind,
905 intptr_t argument_count,
906 intptr_t checked_argument_count = 1);
907 Fragment InstanceCall(TokenPosition position,
908 const dart::String& name,
909 Token::Kind kind,
910 intptr_t type_args_len,
911 intptr_t argument_count,
912 const Array& argument_names,
913 intptr_t checked_argument_count);
914 Fragment ThrowException(TokenPosition position);
915 Fragment BooleanNegate();
916 Fragment TranslateInstantiatedTypeArguments(
917 const TypeArguments& type_arguments);
918 Fragment StrictCompare(Token::Kind kind, bool number_check = false);
919 Fragment AllocateObject(TokenPosition position,
920 const dart::Class& klass,
921 intptr_t argument_count);
922 Fragment AllocateObject(const dart::Class& klass,
923 const Function& closure_function);
924 Fragment AllocateContext(intptr_t size);
925 Fragment LoadField(intptr_t offset);
926 Fragment StoreLocal(TokenPosition position, LocalVariable* variable);
927 Fragment StoreStaticField(TokenPosition position, const dart::Field& field);
928 Fragment StoreInstanceField(TokenPosition position, intptr_t offset);
929 Fragment StringInterpolate(TokenPosition position);
930 Fragment StringInterpolateSingle(TokenPosition position);
931 Fragment ThrowTypeError();
932 Fragment LoadInstantiatorTypeArguments();
933 Fragment LoadFunctionTypeArguments();
934 Fragment InstantiateType(const AbstractType& type);
935 Fragment CreateArray();
936 Fragment StoreIndexed(intptr_t class_id);
937 Fragment CheckStackOverflow();
938 Fragment CloneContext();
939 Fragment TranslateFinallyFinalizers(TryFinallyBlock* outer_finally,
940 intptr_t target_context_depth);
941 Fragment BranchIfTrue(TargetEntryInstr** then_entry,
942 TargetEntryInstr** otherwise_entry,
943 bool negate);
944 Fragment BranchIfEqual(TargetEntryInstr** then_entry,
945 TargetEntryInstr** otherwise_entry,
946 bool negate);
947 Fragment BranchIfNull(TargetEntryInstr** then_entry,
948 TargetEntryInstr** otherwise_entry,
949 bool negate = false);
950 Fragment CatchBlockEntry(const Array& handler_types,
951 intptr_t handler_index,
952 bool needs_stacktrace);
953 Fragment TryCatch(int try_handler_index);
954 Fragment Drop();
955 Fragment NullConstant();
956 JoinEntryInstr* BuildJoinEntry();
957 JoinEntryInstr* BuildJoinEntry(intptr_t try_index);
958 Fragment Goto(JoinEntryInstr* destination);
959 Fragment BuildImplicitClosureCreation(const Function& target);
960 Fragment CheckBooleanInCheckedMode();
961 Fragment CheckAssignableInCheckedMode(const dart::AbstractType& dst_type,
962 const dart::String& dst_name);
963 Fragment CheckVariableTypeInCheckedMode(intptr_t variable_kernel_position);
964 Fragment CheckVariableTypeInCheckedMode(const AbstractType& dst_type,
965 const dart::String& name_symbol);
966 Fragment EnterScope(intptr_t kernel_offset, bool* new_context = NULL);
967 Fragment ExitScope(intptr_t kernel_offset);
968
969 Fragment TranslateCondition(bool* negate);
970 const TypeArguments& BuildTypeArguments();
971 Fragment BuildArguments(Array* argument_names,
972 intptr_t* argument_count,
973 bool skip_push_arguments = false,
974 bool do_drop = false);
975 Fragment BuildArgumentsFromActualArguments(Array* argument_names,
976 bool skip_push_arguments = false,
977 bool do_drop = false);
978
979 Fragment BuildInvalidExpression(TokenPosition* position);
980 Fragment BuildVariableGet(TokenPosition* position);
981 Fragment BuildVariableGet(uint8_t payload, TokenPosition* position);
982 Fragment BuildVariableSet(TokenPosition* position);
983 Fragment BuildVariableSet(uint8_t payload, TokenPosition* position);
984 Fragment BuildPropertyGet(TokenPosition* position);
985 Fragment BuildPropertySet(TokenPosition* position);
986 Fragment BuildDirectPropertyGet(TokenPosition* position);
987 Fragment BuildDirectPropertySet(TokenPosition* position);
988 Fragment BuildStaticGet(TokenPosition* position);
989 Fragment BuildStaticSet(TokenPosition* position);
990 Fragment BuildMethodInvocation(TokenPosition* position);
991 Fragment BuildDirectMethodInvocation(TokenPosition* position);
992 Fragment BuildStaticInvocation(bool is_const, TokenPosition* position);
993 Fragment BuildConstructorInvocation(bool is_const, TokenPosition* position);
994 Fragment BuildNot(TokenPosition* position);
995 Fragment BuildLogicalExpression(TokenPosition* position);
996 Fragment BuildConditionalExpression(TokenPosition* position);
997 Fragment BuildStringConcatenation(TokenPosition* position);
998 Fragment BuildIsExpression(TokenPosition* position);
999 Fragment BuildAsExpression(TokenPosition* position);
1000 Fragment BuildSymbolLiteral(TokenPosition* position);
1001 Fragment BuildTypeLiteral(TokenPosition* position);
1002 Fragment BuildThisExpression(TokenPosition* position);
1003 Fragment BuildRethrow(TokenPosition* position);
1004 Fragment BuildThrow(TokenPosition* position);
1005 Fragment BuildListLiteral(bool is_const, TokenPosition* position);
1006 Fragment BuildMapLiteral(bool is_const, TokenPosition* position);
1007 Fragment BuildFunctionExpression();
1008 Fragment BuildLet(TokenPosition* position);
1009 Fragment BuildBigIntLiteral(TokenPosition* position);
1010 Fragment BuildStringLiteral(TokenPosition* position);
1011 Fragment BuildIntLiteral(uint8_t payload, TokenPosition* position);
1012 Fragment BuildIntLiteral(bool is_negative, TokenPosition* position);
1013 Fragment BuildDoubleLiteral(TokenPosition* position);
1014 Fragment BuildBoolLiteral(bool value, TokenPosition* position);
1015 Fragment BuildNullLiteral(TokenPosition* position);
1016 Fragment BuildVectorCreation(TokenPosition* position);
1017 Fragment BuildVectorGet(TokenPosition* position);
1018 Fragment BuildVectorSet(TokenPosition* position);
1019 Fragment BuildVectorCopy(TokenPosition* position);
1020 Fragment BuildClosureCreation(TokenPosition* position);
1021
1022 Fragment BuildInvalidStatement();
1023 Fragment BuildExpressionStatement();
1024 Fragment BuildBlock();
1025 Fragment BuildEmptyStatement();
1026 Fragment BuildAssertStatement();
1027 Fragment BuildLabeledStatement();
1028 Fragment BuildBreakStatement();
1029 Fragment BuildWhileStatement();
1030 Fragment BuildDoStatement();
1031 Fragment BuildForStatement();
1032 Fragment BuildForInStatement(bool async);
1033 Fragment BuildSwitchStatement();
1034 Fragment BuildContinueSwitchStatement();
1035 Fragment BuildIfStatement();
1036 Fragment BuildReturnStatement();
1037 Fragment BuildTryCatch();
1038 Fragment BuildTryFinally();
1039 Fragment BuildYieldStatement();
1040 Fragment BuildVariableDeclaration();
1041 Fragment BuildFunctionDeclaration();
1042 Fragment BuildFunctionNode(TokenPosition parent_position,
1043 StringIndex name_index);
1044 void SetupFunctionParameters(const dart::Class& klass,
1045 const dart::Function& function,
1046 bool is_method,
1047 bool is_closure,
1048 FunctionNodeHelper* function_node_helper);
1049
1050 FlowGraphBuilder* flow_graph_builder_;
1051 TranslationHelper& translation_helper_;
1052 Zone* zone_;
1053 Reader* reader_;
1054 StreamingConstantEvaluator constant_evaluator_;
1055 StreamingDartTypeTranslator type_translator_;
1056 intptr_t relative_kernel_offset_;
1057 intptr_t current_script_id_;
1058 intptr_t record_for_script_id_;
1059 GrowableArray<intptr_t>* record_token_positions_into_;
1060 GrowableArray<intptr_t>* record_yield_positions_into_;
1061
1062 friend class StreamingConstantEvaluator;
1063 friend class StreamingDartTypeTranslator;
1064 friend class StreamingScopeBuilder;
1065 friend class FunctionNodeHelper;
1066 friend class VariableDeclarationHelper;
1067 friend class FieldHelper;
1068 friend class ProcedureHelper;
1069 friend class ClassHelper;
1070 friend class LibraryHelper;
1071 friend class ConstructorHelper;
1072 friend class SimpleExpressionConverter;
1073 friend class KernelReader;
1074 };
1075
1076 // A helper class that saves the current reader position, goes to another reader
1077 // position, and upon destruction, resets to the original reader position.
1078 class AlternativeReadingScope {
1079 public:
1080 AlternativeReadingScope(Reader* reader, intptr_t new_position)
1081 : reader_(reader),
1082 saved_size_(reader_->size()),
1083 saved_raw_buffer_(reader_->raw_buffer()),
1084 saved_typed_data_(reader_->typed_data()),
1085 saved_offset_(reader_->offset()) {
1086 reader_->set_offset(new_position);
790 } 1087 }
791 1088
792 void ReadUntilExcluding(Field field); 1089 AlternativeReadingScope(Reader* reader,
793 1090 const TypedData* new_typed_data,
794 void SetNext(Field field) { next_read_ = field; } 1091 intptr_t new_position)
795 void SetJustRead(Field field) { next_read_ = field + 1; } 1092 : reader_(reader),
796 1093 saved_size_(reader_->size()),
797 bool IsConst() { 1094 saved_raw_buffer_(reader_->raw_buffer()),
798 return (flags_ & VariableDeclaration::kFlagConst) == 1095 saved_typed_data_(reader_->typed_data()),
799 VariableDeclaration::kFlagConst; 1096 saved_offset_(reader_->offset()) {
1097 reader_->set_raw_buffer(NULL);
1098 reader_->set_typed_data(new_typed_data);
1099 reader_->set_size(new_typed_data->Length());
1100 reader_->set_offset(new_position);
800 } 1101 }
801 bool IsFinal() { 1102
802 return (flags_ & VariableDeclaration::kFlagFinal) == 1103 explicit AlternativeReadingScope(Reader* reader)
803 VariableDeclaration::kFlagFinal; 1104 : reader_(reader),
1105 saved_size_(reader_->size()),
1106 saved_raw_buffer_(reader_->raw_buffer()),
1107 saved_typed_data_(reader_->typed_data()),
1108 saved_offset_(reader_->offset()) {}
1109
1110 ~AlternativeReadingScope() {
1111 reader_->set_raw_buffer(saved_raw_buffer_);
1112 reader_->set_typed_data(saved_typed_data_);
1113 reader_->set_size(saved_size_);
1114 reader_->set_offset(saved_offset_);
804 } 1115 }
805 1116
806 TokenPosition position_; 1117 intptr_t saved_offset() { return saved_offset_; }
807 TokenPosition equals_position_;
808 word flags_;
809 StringIndex name_index_;
810 1118
811 private: 1119 private:
812 StreamingFlowGraphBuilder* builder_; 1120 Reader* reader_;
813 intptr_t next_read_; 1121 intptr_t saved_size_;
1122 const uint8_t* saved_raw_buffer_;
1123 const TypedData* saved_typed_data_;
1124 intptr_t saved_offset_;
814 }; 1125 };
815 1126
816 // Helper class that reads a kernel Field from binary.
817 //
818 // Use ReadUntilExcluding to read up to but not including a field.
819 // One can then for instance read the field from the call-site (and remember to
820 // call SetAt to inform this helper class), and then use this to read more.
821 // Simple fields are stored (e.g. integers) and can be fetched from this class.
822 // If asked to read a compound field (e.g. an expression) it will be skipped.
823 class FieldHelper {
824 public:
825 enum Field {
826 kStart, // tag.
827 kCanonicalName,
828 kPosition,
829 kEndPosition,
830 kFlags,
831 kName,
832 kSourceUriIndex,
833 kDocumentationCommentIndex,
834 kAnnotations,
835 kType,
836 kInitializer,
837 kEnd
838 };
839
840 explicit FieldHelper(StreamingFlowGraphBuilder* builder)
841 : builder_(builder),
842 next_read_(kStart),
843 has_function_literal_initializer_(false) {}
844
845 FieldHelper(StreamingFlowGraphBuilder* builder, intptr_t offset)
846 : builder_(builder),
847 next_read_(kStart),
848 has_function_literal_initializer_(false) {
849 builder_->SetOffset(offset);
850 }
851
852 void ReadUntilIncluding(Field field) {
853 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
854 }
855
856 void ReadUntilExcluding(Field field,
857 bool detect_function_literal_initializer = false);
858
859 void SetNext(Field field) { next_read_ = field; }
860 void SetJustRead(Field field) { next_read_ = field + 1; }
861
862 bool IsConst() {
863 return (flags_ & kernel::Field::kFlagConst) == kernel::Field::kFlagConst;
864 }
865 bool IsFinal() {
866 return (flags_ & kernel::Field::kFlagFinal) == kernel::Field::kFlagFinal;
867 }
868 bool IsStatic() {
869 return (flags_ & kernel::Field::kFlagStatic) == kernel::Field::kFlagStatic;
870 }
871
872 bool FieldHasFunctionLiteralInitializer(TokenPosition* start,
873 TokenPosition* end) {
874 if (has_function_literal_initializer_) {
875 *start = function_literal_start_;
876 *end = function_literal_end_;
877 }
878 return has_function_literal_initializer_;
879 }
880
881 NameIndex canonical_name_;
882 TokenPosition position_;
883 TokenPosition end_position_;
884 word flags_;
885 intptr_t source_uri_index_;
886 intptr_t annotation_count_;
887
888 private:
889 StreamingFlowGraphBuilder* builder_;
890 intptr_t next_read_;
891
892 bool has_function_literal_initializer_;
893 TokenPosition function_literal_start_;
894 TokenPosition function_literal_end_;
895 };
896
897 // Helper class that reads a kernel Procedure from binary.
898 //
899 // Use ReadUntilExcluding to read up to but not including a field.
900 // One can then for instance read the field from the call-site (and remember to
901 // call SetAt to inform this helper class), and then use this to read more.
902 // Simple fields are stored (e.g. integers) and can be fetched from this class.
903 // If asked to read a compound field (e.g. an expression) it will be skipped.
904 class ProcedureHelper {
905 public:
906 enum Field {
907 kStart, // tag.
908 kCanonicalName,
909 kPosition,
910 kEndPosition,
911 kKind,
912 kFlags,
913 kName,
914 kSourceUriIndex,
915 kDocumentationCommentIndex,
916 kAnnotations,
917 kFunction,
918 kEnd
919 };
920
921 explicit ProcedureHelper(StreamingFlowGraphBuilder* builder) {
922 builder_ = builder;
923 next_read_ = kStart;
924 }
925
926 void ReadUntilIncluding(Field field) {
927 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
928 }
929
930 void ReadUntilExcluding(Field field);
931
932 void SetNext(Field field) { next_read_ = field; }
933 void SetJustRead(Field field) { next_read_ = field + 1; }
934
935 bool IsStatic() {
936 return (flags_ & Procedure::kFlagStatic) == Procedure::kFlagStatic;
937 }
938 bool IsAbstract() {
939 return (flags_ & Procedure::kFlagAbstract) == Procedure::kFlagAbstract;
940 }
941 bool IsExternal() {
942 return (flags_ & Procedure::kFlagExternal) == Procedure::kFlagExternal;
943 }
944 bool IsConst() {
945 return (flags_ & Procedure::kFlagConst) == Procedure::kFlagConst;
946 }
947
948 NameIndex canonical_name_;
949 TokenPosition position_;
950 TokenPosition end_position_;
951 Procedure::ProcedureKind kind_;
952 word flags_;
953 intptr_t source_uri_index_;
954 intptr_t annotation_count_;
955
956 private:
957 StreamingFlowGraphBuilder* builder_;
958 intptr_t next_read_;
959 };
960
961 // Helper class that reads a kernel Constructor from binary.
962 //
963 // Use ReadUntilExcluding to read up to but not including a field.
964 // One can then for instance read the field from the call-site (and remember to
965 // call SetAt to inform this helper class), and then use this to read more.
966 // Simple fields are stored (e.g. integers) and can be fetched from this class.
967 // If asked to read a compound field (e.g. an expression) it will be skipped.
968 class ConstructorHelper {
969 public:
970 enum Field {
971 kStart, // tag.
972 kCanonicalName,
973 kPosition,
974 kEndPosition,
975 kFlags,
976 kName,
977 kDocumentationCommentIndex,
978 kAnnotations,
979 kFunction,
980 kInitializers,
981 kEnd
982 };
983
984 explicit ConstructorHelper(StreamingFlowGraphBuilder* builder) {
985 builder_ = builder;
986 next_read_ = kStart;
987 }
988
989 void ReadUntilIncluding(Field field) {
990 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
991 }
992
993 void ReadUntilExcluding(Field field);
994
995 void SetNext(Field field) { next_read_ = field; }
996 void SetJustRead(Field field) { next_read_ = field + 1; }
997
998 bool IsExternal() {
999 return (flags_ & Constructor::kFlagExternal) == Constructor::kFlagExternal;
1000 }
1001 bool IsConst() {
1002 return (flags_ & Constructor::kFlagConst) == Constructor::kFlagConst;
1003 }
1004
1005 NameIndex canonical_name_;
1006 TokenPosition position_;
1007 TokenPosition end_position_;
1008 word flags_;
1009 intptr_t annotation_count_;
1010
1011 private:
1012 StreamingFlowGraphBuilder* builder_;
1013 intptr_t next_read_;
1014 };
1015
1016 // Helper class that reads a kernel Class from binary.
1017 //
1018 // Use ReadUntilExcluding to read up to but not including a field.
1019 // One can then for instance read the field from the call-site (and remember to
1020 // call SetAt to inform this helper class), and then use this to read more.
1021 // Simple fields are stored (e.g. integers) and can be fetched from this class.
1022 // If asked to read a compound field (e.g. an expression) it will be skipped.
1023 class ClassHelper {
1024 public:
1025 enum Field {
1026 kStart, // tag.
1027 kCanonicalName,
1028 kPosition,
1029 kEndPosition,
1030 kIsAbstract,
1031 kNameIndex,
1032 kSourceUriIndex,
1033 kDocumentationCommentIndex,
1034 kAnnotations,
1035 kTypeParameters,
1036 kSuperClass,
1037 kMixinType,
1038 kImplementedClasses,
1039 kFields,
1040 kConstructors,
1041 kProcedures,
1042 kEnd
1043 };
1044
1045 explicit ClassHelper(StreamingFlowGraphBuilder* builder) {
1046 builder_ = builder;
1047 next_read_ = kStart;
1048 }
1049
1050 void ReadUntilIncluding(Field field) {
1051 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
1052 }
1053
1054 void ReadUntilExcluding(Field field);
1055
1056 void SetNext(Field field) { next_read_ = field; }
1057 void SetJustRead(Field field) { next_read_ = field + 1; }
1058
1059 NameIndex canonical_name_;
1060 TokenPosition position_;
1061 TokenPosition end_position_;
1062 bool is_abstract_;
1063 StringIndex name_index_;
1064 intptr_t source_uri_index_;
1065 intptr_t annotation_count_;
1066
1067 private:
1068 StreamingFlowGraphBuilder* builder_;
1069 intptr_t next_read_;
1070 };
1071
1072 // Helper class that reads a kernel Library from binary.
1073 //
1074 // Use ReadUntilExcluding to read up to but not including a field.
1075 // One can then for instance read the field from the call-site (and remember to
1076 // call SetAt to inform this helper class), and then use this to read more.
1077 // Simple fields are stored (e.g. integers) and can be fetched from this class.
1078 // If asked to read a compound field (e.g. an expression) it will be skipped.
1079 class LibraryHelper {
1080 public:
1081 enum Field {
1082 kFlags,
1083 kCanonicalName,
1084 kName,
1085 kSourceUriIndex,
1086 kAnnotations,
1087 kDependencies,
1088 kParts,
1089 kTypedefs,
1090 kClasses,
1091 kToplevelField,
1092 kToplevelProcedures,
1093 kEnd
1094 };
1095
1096 explicit LibraryHelper(StreamingFlowGraphBuilder* builder) {
1097 builder_ = builder;
1098 next_read_ = kFlags;
1099 }
1100
1101 void ReadUntilIncluding(Field field) {
1102 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
1103 }
1104
1105 void ReadUntilExcluding(Field field);
1106
1107 void SetNext(Field field) { next_read_ = field; }
1108 void SetJustRead(Field field) { next_read_ = field + 1; }
1109
1110 NameIndex canonical_name_;
1111 StringIndex name_index_;
1112 intptr_t source_uri_index_;
1113
1114 private:
1115 StreamingFlowGraphBuilder* builder_;
1116 intptr_t next_read_;
1117 };
1118
1119 } // namespace kernel 1127 } // namespace kernel
1120 } // namespace dart 1128 } // namespace dart
1121 1129
1122 #endif // !defined(DART_PRECOMPILED_RUNTIME) 1130 #endif // !defined(DART_PRECOMPILED_RUNTIME)
1123 #endif // RUNTIME_VM_KERNEL_BINARY_FLOWGRAPH_H_ 1131 #endif // RUNTIME_VM_KERNEL_BINARY_FLOWGRAPH_H_
OLDNEW
« no previous file with comments | « runtime/vm/kernel.h ('k') | runtime/vm/kernel_binary_flowgraph.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698