| 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 |