Chromium Code Reviews| 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 { | |
|
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_ |
| OLD | NEW |