OLD | NEW |
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 { | 20 class StreamingDartTypeTranslator { |
21 public: | 21 public: |
22 StreamingDartTypeTranslator(StreamingFlowGraphBuilder* builder, | 22 StreamingDartTypeTranslator(StreamingFlowGraphBuilder* builder, |
23 bool finalize = false); | 23 bool finalize = false); |
24 | 24 |
25 // Can return a malformed type. | 25 // Can return a malformed type. |
26 AbstractType& BuildType(); | 26 AbstractType& BuildType(); |
| 27 // Is guaranteed to be not malformed. |
| 28 AbstractType& BuildVariableType(); |
| 29 |
27 // Will return `TypeArguments::null()` in case any of the arguments are | 30 // Will return `TypeArguments::null()` in case any of the arguments are |
28 // malformed. | 31 // malformed. |
29 const TypeArguments& BuildTypeArguments(intptr_t length); | 32 const TypeArguments& BuildTypeArguments(intptr_t length); |
30 | 33 |
31 // Will return `TypeArguments::null()` in case any of the arguments are | 34 // Will return `TypeArguments::null()` in case any of the arguments are |
32 // malformed. | 35 // malformed. |
33 const TypeArguments& BuildInstantiatedTypeArguments( | 36 const TypeArguments& BuildInstantiatedTypeArguments( |
34 const dart::Class& receiver_class, | 37 const dart::Class& receiver_class, |
35 intptr_t length); | 38 intptr_t length); |
36 | 39 |
37 const Type& ReceiverType(const dart::Class& klass); | 40 const Type& ReceiverType(const dart::Class& klass); |
38 | 41 |
39 private: | 42 private: |
40 // Can build a malformed type. | 43 // Can build a malformed type. |
41 void BuildTypeInternal(); | 44 void BuildTypeInternal(); |
42 void BuildInterfaceType(bool simple); | 45 void BuildInterfaceType(bool simple); |
43 void BuildFunctionType(bool simple); | 46 void BuildFunctionType(bool simple); |
44 void BuildTypeParameterType(); | 47 void BuildTypeParameterType(); |
45 | 48 |
46 class TypeParameterScope { | 49 class TypeParameterScope { |
47 public: | 50 public: |
48 TypeParameterScope(StreamingDartTypeTranslator* translator, | 51 TypeParameterScope(StreamingDartTypeTranslator* translator, |
49 intptr_t* parameters, | 52 intptr_t parameters_offset, |
50 intptr_t parameters_count) | 53 intptr_t parameters_count) |
51 : parameters_(parameters), | 54 : parameters_offset_(parameters_offset), |
52 parameters_count_(parameters_count), | 55 parameters_count_(parameters_count), |
53 outer_(translator->type_parameter_scope_), | 56 outer_(translator->type_parameter_scope_), |
54 translator_(translator) { | 57 translator_(translator) { |
55 translator_->type_parameter_scope_ = this; | 58 translator_->type_parameter_scope_ = this; |
56 } | 59 } |
57 ~TypeParameterScope() { | 60 ~TypeParameterScope() { |
58 delete[] parameters_; | |
59 translator_->type_parameter_scope_ = outer_; | 61 translator_->type_parameter_scope_ = outer_; |
60 } | 62 } |
61 | 63 |
62 TypeParameterScope* outer() const { return outer_; } | 64 TypeParameterScope* outer() const { return outer_; } |
63 intptr_t* parameters() const { return parameters_; } | 65 intptr_t parameters_offset() const { return parameters_offset_; } |
64 intptr_t parameters_count() const { return parameters_count_; } | 66 intptr_t parameters_count() const { return parameters_count_; } |
65 | 67 |
66 private: | 68 private: |
67 intptr_t* parameters_; | 69 intptr_t parameters_offset_; |
68 intptr_t parameters_count_; | 70 intptr_t parameters_count_; |
69 TypeParameterScope* outer_; | 71 TypeParameterScope* outer_; |
70 StreamingDartTypeTranslator* translator_; | 72 StreamingDartTypeTranslator* translator_; |
71 }; | 73 }; |
72 | 74 |
| 75 intptr_t FindTypeParameterIndex(intptr_t parameters_offset, |
| 76 intptr_t parameters_count, |
| 77 intptr_t look_for); |
| 78 |
73 StreamingFlowGraphBuilder* builder_; | 79 StreamingFlowGraphBuilder* builder_; |
74 TranslationHelper& translation_helper_; | 80 TranslationHelper& translation_helper_; |
75 ActiveClass* active_class_; | 81 ActiveClass* active_class_; |
76 TypeParameterScope* type_parameter_scope_; | 82 TypeParameterScope* type_parameter_scope_; |
77 Zone* zone_; | 83 Zone* zone_; |
78 AbstractType& result_; | 84 AbstractType& result_; |
79 bool finalize_; | 85 bool finalize_; |
| 86 |
| 87 friend class StreamingScopeBuilder; |
80 }; | 88 }; |
81 | 89 |
82 | 90 |
| 91 class StreamingScopeBuilder { |
| 92 public: |
| 93 StreamingScopeBuilder(ParsedFunction* parsed_function, |
| 94 intptr_t kernel_offset, |
| 95 const uint8_t* buffer, |
| 96 intptr_t buffer_length); |
| 97 |
| 98 virtual ~StreamingScopeBuilder(); |
| 99 |
| 100 ScopeBuildingResult* BuildScopes(); |
| 101 |
| 102 private: |
| 103 void VisitField(); |
| 104 void ReadFieldUntilAnnotation(TokenPosition* position, |
| 105 TokenPosition* end_position, |
| 106 word* flags, |
| 107 intptr_t* parent_offset); |
| 108 |
| 109 /** |
| 110 * Will read until the function node; as this is optional, will return the tag |
| 111 * (i.e. either kSomething or kNothing). |
| 112 */ |
| 113 Tag ReadProcedureUntilFunctionNode(word* kind, intptr_t* parent_offset); |
| 114 void GetTypeParameterInfoForPossibleProcedure( |
| 115 intptr_t outermost_kernel_offset, |
| 116 bool* member_is_procedure, |
| 117 bool* is_factory_procedure, |
| 118 intptr_t* member_type_parameters, |
| 119 intptr_t* member_type_parameters_offset_start); |
| 120 void VisitProcedure(); |
| 121 |
| 122 /** |
| 123 * Will return binary offset of parent class. |
| 124 */ |
| 125 intptr_t ReadConstructorUntilFunctionNode(); |
| 126 void VisitConstructor(); |
| 127 |
| 128 void ReadClassUntilTypeParameters(); |
| 129 void ReadClassUntilFields(); |
| 130 |
| 131 void ReadFunctionNodeUntilTypeParameters(word* async_marker, |
| 132 word* dart_async_marker); |
| 133 void VisitFunctionNode(); |
| 134 |
| 135 void DiscoverEnclosingElements(Zone* zone, |
| 136 const Function& function, |
| 137 Function* outermost_function, |
| 138 intptr_t* outermost_kernel_offset, |
| 139 intptr_t* parent_class_offset); |
| 140 intptr_t GetParentOffset(intptr_t offset); |
| 141 void GetTypeParameterInfoForClass(intptr_t class_offset, |
| 142 intptr_t* type_paremeter_counts, |
| 143 intptr_t* type_paremeter_offset); |
| 144 void VisitNode(); |
| 145 void VisitInitializer(); |
| 146 void VisitExpression(); |
| 147 void VisitStatement(); |
| 148 void VisitArguments(); |
| 149 void VisitVariableDeclaration(); |
| 150 void VisitDartType(); |
| 151 void VisitInterfaceType(bool simple); |
| 152 void VisitFunctionType(bool simple); |
| 153 void VisitTypeParameterType(); |
| 154 void HandleLocalFunction(intptr_t parent_kernel_offset); |
| 155 |
| 156 void EnterScope(intptr_t kernel_offset); |
| 157 void ExitScope(TokenPosition start_position, TokenPosition end_position); |
| 158 |
| 159 /** |
| 160 * This assumes that the reader is at a FunctionNode, |
| 161 * about to read the positional parameters. |
| 162 */ |
| 163 void AddPositionalAndNamedParameters(intptr_t pos = 0); |
| 164 /** |
| 165 * This assumes that the reader is at a FunctionNode, |
| 166 * about to read a parameter (i.e. VariableDeclaration). |
| 167 */ |
| 168 void AddVariableDeclarationParameter(intptr_t pos); |
| 169 |
| 170 LocalVariable* MakeVariable(TokenPosition declaration_pos, |
| 171 TokenPosition token_pos, |
| 172 const dart::String& name, |
| 173 const AbstractType& type); |
| 174 |
| 175 void AddExceptionVariable(GrowableArray<LocalVariable*>* variables, |
| 176 const char* prefix, |
| 177 intptr_t nesting_depth); |
| 178 |
| 179 void AddTryVariables(); |
| 180 void AddCatchVariables(); |
| 181 void AddIteratorVariable(); |
| 182 void AddSwitchVariable(); |
| 183 |
| 184 StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset); |
| 185 |
| 186 // Record an assignment or reference to a variable. If the occurrence is |
| 187 // in a nested function, ensure that the variable is handled properly as a |
| 188 // captured variable. |
| 189 void LookupVariable(intptr_t declaration_binary_offest); |
| 190 |
| 191 const dart::String& GenerateName(const char* prefix, intptr_t suffix); |
| 192 |
| 193 void HandleSpecialLoad(LocalVariable** variable, const dart::String& symbol); |
| 194 void LookupCapturedVariableByName(LocalVariable** variable, |
| 195 const dart::String& name); |
| 196 |
| 197 struct DepthState { |
| 198 explicit DepthState(intptr_t function) |
| 199 : loop_(0), |
| 200 function_(function), |
| 201 try_(0), |
| 202 catch_(0), |
| 203 finally_(0), |
| 204 for_in_(0) {} |
| 205 |
| 206 intptr_t loop_; |
| 207 intptr_t function_; |
| 208 intptr_t try_; |
| 209 intptr_t catch_; |
| 210 intptr_t finally_; |
| 211 intptr_t for_in_; |
| 212 }; |
| 213 |
| 214 ScopeBuildingResult* result_; |
| 215 ParsedFunction* parsed_function_; |
| 216 intptr_t kernel_offset_; |
| 217 |
| 218 ActiveClass active_class_; |
| 219 |
| 220 TranslationHelper translation_helper_; |
| 221 Zone* zone_; |
| 222 |
| 223 FunctionNode::AsyncMarker current_function_async_marker_; |
| 224 LocalScope* current_function_scope_; |
| 225 LocalScope* scope_; |
| 226 DepthState depth_; |
| 227 |
| 228 intptr_t name_index_; |
| 229 |
| 230 bool needs_expr_temp_; |
| 231 TokenPosition first_body_token_position_; |
| 232 |
| 233 StreamingFlowGraphBuilder* builder_; |
| 234 StreamingDartTypeTranslator type_translator_; |
| 235 |
| 236 word unused_word; |
| 237 intptr_t unused_intptr; |
| 238 TokenPosition unused_tokenposition; |
| 239 }; |
| 240 |
| 241 |
83 class StreamingConstantEvaluator { | 242 class StreamingConstantEvaluator { |
84 public: | 243 public: |
85 explicit StreamingConstantEvaluator(StreamingFlowGraphBuilder* builder); | 244 explicit StreamingConstantEvaluator(StreamingFlowGraphBuilder* builder); |
86 | 245 |
87 virtual ~StreamingConstantEvaluator() {} | 246 virtual ~StreamingConstantEvaluator() {} |
88 | 247 |
89 Instance& EvaluateExpression(intptr_t offset, bool reset_position = true); | 248 Instance& EvaluateExpression(intptr_t offset, bool reset_position = true); |
90 Instance& EvaluateListLiteral(intptr_t offset, bool reset_position = true); | 249 Instance& EvaluateListLiteral(intptr_t offset, bool reset_position = true); |
91 Instance& EvaluateMapLiteral(intptr_t offset, bool reset_position = true); | 250 Instance& EvaluateMapLiteral(intptr_t offset, bool reset_position = true); |
92 Instance& EvaluateConstructorInvocation(intptr_t offset, | 251 Instance& EvaluateConstructorInvocation(intptr_t offset, |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder, | 321 StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder, |
163 const uint8_t* buffer, | 322 const uint8_t* buffer, |
164 intptr_t buffer_length) | 323 intptr_t buffer_length) |
165 : flow_graph_builder_(flow_graph_builder), | 324 : flow_graph_builder_(flow_graph_builder), |
166 translation_helper_(flow_graph_builder->translation_helper_), | 325 translation_helper_(flow_graph_builder->translation_helper_), |
167 zone_(flow_graph_builder->zone_), | 326 zone_(flow_graph_builder->zone_), |
168 reader_(new Reader(buffer, buffer_length)), | 327 reader_(new Reader(buffer, buffer_length)), |
169 constant_evaluator_(this), | 328 constant_evaluator_(this), |
170 type_translator_(this, /* finalize= */ true) {} | 329 type_translator_(this, /* finalize= */ true) {} |
171 | 330 |
| 331 ~StreamingFlowGraphBuilder() { delete reader_; } |
| 332 |
172 Fragment BuildExpressionAt(intptr_t kernel_offset); | 333 Fragment BuildExpressionAt(intptr_t kernel_offset); |
173 Fragment BuildStatementAt(intptr_t kernel_offset); | 334 Fragment BuildStatementAt(intptr_t kernel_offset); |
174 | 335 |
175 private: | 336 private: |
| 337 StreamingFlowGraphBuilder(TranslationHelper* translation_helper, |
| 338 Zone* zone, |
| 339 const uint8_t* buffer, |
| 340 intptr_t buffer_length) |
| 341 : flow_graph_builder_(NULL), |
| 342 translation_helper_(*translation_helper), |
| 343 zone_(zone), |
| 344 reader_(new Reader(buffer, buffer_length)), |
| 345 constant_evaluator_(this), |
| 346 type_translator_(this, /* finalize= */ true) {} |
| 347 |
176 Fragment BuildExpression(TokenPosition* position = NULL); | 348 Fragment BuildExpression(TokenPosition* position = NULL); |
177 Fragment BuildStatement(); | 349 Fragment BuildStatement(); |
178 | 350 |
179 intptr_t ReaderOffset(); | 351 intptr_t ReaderOffset(); |
180 void SetOffset(intptr_t offset); | 352 void SetOffset(intptr_t offset); |
181 void SkipBytes(intptr_t skip); | 353 void SkipBytes(intptr_t skip); |
182 bool ReadBool(); | 354 bool ReadBool(); |
183 uint8_t ReadByte(); | 355 uint8_t ReadByte(); |
184 uint32_t ReadUInt(); | 356 uint32_t ReadUInt(); |
185 uint32_t PeekUInt(); | 357 uint32_t PeekUInt(); |
186 intptr_t ReadListLength(); | 358 intptr_t ReadListLength(); |
187 StringIndex ReadStringReference(); | 359 StringIndex ReadStringReference(); |
188 NameIndex ReadCanonicalNameReference(); | 360 NameIndex ReadCanonicalNameReference(); |
189 StringIndex ReadNameAsStringIndex(); | 361 StringIndex ReadNameAsStringIndex(); |
190 const dart::String& ReadNameAsMethodName(); | 362 const dart::String& ReadNameAsMethodName(); |
191 const dart::String& ReadNameAsGetterName(); | 363 const dart::String& ReadNameAsGetterName(); |
192 const dart::String& ReadNameAsSetterName(); | 364 const dart::String& ReadNameAsSetterName(); |
193 void SkipStringReference(); | 365 void SkipStringReference(); |
194 void SkipCanonicalNameReference(); | 366 void SkipCanonicalNameReference(); |
195 void SkipDartType(); | 367 void SkipDartType(); |
196 void SkipOptionalDartType(); | 368 void SkipOptionalDartType(); |
197 void SkipInterfaceType(bool simple); | 369 void SkipInterfaceType(bool simple); |
198 void SkipFunctionType(bool simple); | 370 void SkipFunctionType(bool simple); |
| 371 void SkipListOfExpressions(); |
| 372 void SkipListOfDartTypes(); |
| 373 void SkipListOfVariableDeclarations(); |
| 374 void SkipTypeParametersList(); |
199 void SkipExpression(); | 375 void SkipExpression(); |
200 void SkipStatement(); | 376 void SkipStatement(); |
| 377 void SkipFunctionNode(); |
201 void SkipName(); | 378 void SkipName(); |
202 void SkipArguments(); | 379 void SkipArguments(); |
203 void SkipVariableDeclaration(); | 380 void SkipVariableDeclaration(); |
204 TokenPosition ReadPosition(bool record = true); | 381 TokenPosition ReadPosition(bool record = true); |
205 Tag ReadTag(uint8_t* payload = NULL); | 382 Tag ReadTag(uint8_t* payload = NULL); |
206 Tag PeekTag(uint8_t* payload = NULL); | 383 Tag PeekTag(uint8_t* payload = NULL); |
207 word ReadFlags(); | 384 word ReadFlags(); |
208 | 385 |
209 void loop_depth_inc(); | 386 void loop_depth_inc(); |
210 void loop_depth_dec(); | 387 void loop_depth_dec(); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 Fragment BuildDoStatement(); | 557 Fragment BuildDoStatement(); |
381 Fragment BuildForStatement(); | 558 Fragment BuildForStatement(); |
382 Fragment BuildForInStatement(bool async); | 559 Fragment BuildForInStatement(bool async); |
383 Fragment BuildSwitchStatement(); | 560 Fragment BuildSwitchStatement(); |
384 Fragment BuildContinueSwitchStatement(); | 561 Fragment BuildContinueSwitchStatement(); |
385 Fragment BuildIfStatement(); | 562 Fragment BuildIfStatement(); |
386 Fragment BuildReturnStatement(); | 563 Fragment BuildReturnStatement(); |
387 Fragment BuildTryCatch(); | 564 Fragment BuildTryCatch(); |
388 Fragment BuildTryFinally(); | 565 Fragment BuildTryFinally(); |
389 Fragment BuildYieldStatement(); | 566 Fragment BuildYieldStatement(); |
390 Fragment BuildVariableDeclaration(bool has_tag); | 567 Fragment BuildVariableDeclaration(); |
391 | 568 |
392 FlowGraphBuilder* flow_graph_builder_; | 569 FlowGraphBuilder* flow_graph_builder_; |
393 TranslationHelper& translation_helper_; | 570 TranslationHelper& translation_helper_; |
394 Zone* zone_; | 571 Zone* zone_; |
395 Reader* reader_; | 572 Reader* reader_; |
396 StreamingConstantEvaluator constant_evaluator_; | 573 StreamingConstantEvaluator constant_evaluator_; |
397 StreamingDartTypeTranslator type_translator_; | 574 StreamingDartTypeTranslator type_translator_; |
398 | 575 |
399 friend class StreamingConstantEvaluator; | 576 friend class StreamingConstantEvaluator; |
400 friend class StreamingDartTypeTranslator; | 577 friend class StreamingDartTypeTranslator; |
| 578 friend class StreamingScopeBuilder; |
401 }; | 579 }; |
402 | 580 |
| 581 // A helper class that saves the current reader position, goes to another reader |
| 582 // position, and upon destruction, resets to the original reader position. |
| 583 class AlternativeReadingScope { |
| 584 public: |
| 585 AlternativeReadingScope(Reader* reader, intptr_t new_position) |
| 586 : reader_(reader), saved_offset_(reader_->offset()) { |
| 587 reader_->set_offset(new_position); |
| 588 } |
| 589 |
| 590 explicit AlternativeReadingScope(Reader* reader) |
| 591 : reader_(reader), saved_offset_(reader_->offset()) {} |
| 592 |
| 593 ~AlternativeReadingScope() { reader_->set_offset(saved_offset_); } |
| 594 |
| 595 private: |
| 596 Reader* reader_; |
| 597 intptr_t saved_offset_; |
| 598 }; |
403 | 599 |
404 } // namespace kernel | 600 } // namespace kernel |
405 } // namespace dart | 601 } // namespace dart |
406 | 602 |
407 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 603 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
408 #endif // RUNTIME_VM_KERNEL_BINARY_FLOWGRAPH_H_ | 604 #endif // RUNTIME_VM_KERNEL_BINARY_FLOWGRAPH_H_ |
OLD | NEW |