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> |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 LocalScope* scope_; | 191 LocalScope* scope_; |
192 DepthState depth_; | 192 DepthState depth_; |
193 | 193 |
194 intptr_t name_index_; | 194 intptr_t name_index_; |
195 | 195 |
196 bool needs_expr_temp_; | 196 bool needs_expr_temp_; |
197 TokenPosition first_body_token_position_; | 197 TokenPosition first_body_token_position_; |
198 | 198 |
199 StreamingFlowGraphBuilder* builder_; | 199 StreamingFlowGraphBuilder* builder_; |
200 StreamingDartTypeTranslator type_translator_; | 200 StreamingDartTypeTranslator type_translator_; |
201 | |
202 word unused_word; | |
203 intptr_t unused_intptr; | |
204 TokenPosition unused_tokenposition; | |
205 NameIndex unused_nameindex; | |
206 }; | 201 }; |
207 | 202 |
208 | 203 |
209 // There are several cases when we are compiling constant expressions: | 204 // There are several cases when we are compiling constant expressions: |
210 // | 205 // |
211 // * constant field initializers: | 206 // * constant field initializers: |
212 // const FieldName = <expr>; | 207 // const FieldName = <expr>; |
213 // | 208 // |
214 // * constant expressions: | 209 // * constant expressions: |
215 // const [<expr>, ...] | 210 // const [<expr>, ...] |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 StreamingFlowGraphBuilder* builder_; | 289 StreamingFlowGraphBuilder* builder_; |
295 Isolate* isolate_; | 290 Isolate* isolate_; |
296 Zone* zone_; | 291 Zone* zone_; |
297 TranslationHelper& translation_helper_; | 292 TranslationHelper& translation_helper_; |
298 StreamingDartTypeTranslator& type_translator_; | 293 StreamingDartTypeTranslator& type_translator_; |
299 | 294 |
300 Script& script_; | 295 Script& script_; |
301 Instance& result_; | 296 Instance& result_; |
302 }; | 297 }; |
303 | 298 |
| 299 class FunctionNodeHelper; |
304 | 300 |
305 class StreamingFlowGraphBuilder { | 301 class StreamingFlowGraphBuilder { |
306 public: | 302 public: |
307 StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder, | 303 StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder, |
308 const uint8_t* buffer, | 304 const uint8_t* buffer, |
309 intptr_t buffer_length) | 305 intptr_t buffer_length) |
310 : flow_graph_builder_(flow_graph_builder), | 306 : flow_graph_builder_(flow_graph_builder), |
311 translation_helper_(flow_graph_builder->translation_helper_), | 307 translation_helper_(flow_graph_builder->translation_helper_), |
312 zone_(flow_graph_builder->zone_), | 308 zone_(flow_graph_builder->zone_), |
313 reader_(new Reader(buffer, buffer_length)), | 309 reader_(new Reader(buffer, buffer_length)), |
(...skipping 22 matching lines...) Expand all Loading... |
336 private: | 332 private: |
337 void DiscoverEnclosingElements(Zone* zone, | 333 void DiscoverEnclosingElements(Zone* zone, |
338 const Function& function, | 334 const Function& function, |
339 Function* outermost_function, | 335 Function* outermost_function, |
340 intptr_t* outermost_kernel_offset, | 336 intptr_t* outermost_kernel_offset, |
341 intptr_t* parent_class_offset); | 337 intptr_t* parent_class_offset); |
342 intptr_t GetParentOffset(intptr_t offset); | 338 intptr_t GetParentOffset(intptr_t offset); |
343 void GetTypeParameterInfoForClass(intptr_t class_offset, | 339 void GetTypeParameterInfoForClass(intptr_t class_offset, |
344 intptr_t* type_paremeter_counts, | 340 intptr_t* type_paremeter_counts, |
345 intptr_t* type_paremeter_offset); | 341 intptr_t* type_paremeter_offset); |
346 void ReadClassUntilFields(); | |
347 void ReadClassUntilTypeParameters(); | |
348 /** | |
349 * Will return binary offset of parent class. | |
350 */ | |
351 intptr_t ReadConstructorUntilFunctionNode(); | |
352 /** | |
353 * Will read until the function node; as this is optional, will return the tag | |
354 * (i.e. either kSomething or kNothing). | |
355 */ | |
356 Tag ReadProcedureUntilFunctionNode(word* kind, intptr_t* parent_offset); | |
357 | 342 |
358 void ReadFieldUntilAnnotation(NameIndex* canonical_name, | |
359 TokenPosition* position, | |
360 TokenPosition* end_position, | |
361 word* flags, | |
362 intptr_t* parent_offset); | |
363 void GetTypeParameterInfoForPossibleProcedure( | 343 void GetTypeParameterInfoForPossibleProcedure( |
364 intptr_t outermost_kernel_offset, | 344 intptr_t outermost_kernel_offset, |
365 bool* member_is_procedure, | 345 bool* member_is_procedure, |
366 bool* is_factory_procedure, | 346 bool* is_factory_procedure, |
367 intptr_t* member_type_parameters, | 347 intptr_t* member_type_parameters, |
368 intptr_t* member_type_parameters_offset_start); | 348 intptr_t* member_type_parameters_offset_start); |
369 void ReadFunctionNodeUntilTypeParameters(TokenPosition* position, | |
370 TokenPosition* end_position, | |
371 word* async_marker, | |
372 word* dart_async_marker); | |
373 /** | 349 /** |
374 * Will return kernel offset for parent class if reading a constructor. | 350 * Will return kernel offset for parent class if reading a constructor. |
375 * Will otherwise return -1. | 351 * Will otherwise return -1. |
376 */ | 352 */ |
377 intptr_t ReadUntilFunctionNode(); | 353 intptr_t ReadUntilFunctionNode(); |
378 StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset); | 354 StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset); |
379 | 355 |
380 FlowGraph* BuildGraphOfStaticFieldInitializer(); | 356 FlowGraph* BuildGraphOfStaticFieldInitializer(); |
381 FlowGraph* BuildGraphOfFieldAccessor(LocalVariable* setter_value); | 357 FlowGraph* BuildGraphOfFieldAccessor(LocalVariable* setter_value); |
382 void SetupDefaultParameterValues(); | 358 void SetupDefaultParameterValues(); |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 Fragment BuildYieldStatement(); | 587 Fragment BuildYieldStatement(); |
612 Fragment BuildVariableDeclaration(); | 588 Fragment BuildVariableDeclaration(); |
613 Fragment BuildFunctionDeclaration(); | 589 Fragment BuildFunctionDeclaration(); |
614 Fragment BuildFunctionNode(intptr_t parent_kernel_offset, | 590 Fragment BuildFunctionNode(intptr_t parent_kernel_offset, |
615 TokenPosition parent_position, | 591 TokenPosition parent_position, |
616 bool declaration, | 592 bool declaration, |
617 intptr_t variable_offeset); | 593 intptr_t variable_offeset); |
618 void SetupFunctionParameters(const dart::Class& klass, | 594 void SetupFunctionParameters(const dart::Class& klass, |
619 const dart::Function& function, | 595 const dart::Function& function, |
620 bool is_method, | 596 bool is_method, |
621 bool is_closure); | 597 bool is_closure, |
| 598 FunctionNodeHelper* function_node_helper); |
622 | 599 |
623 FlowGraphBuilder* flow_graph_builder_; | 600 FlowGraphBuilder* flow_graph_builder_; |
624 TranslationHelper& translation_helper_; | 601 TranslationHelper& translation_helper_; |
625 Zone* zone_; | 602 Zone* zone_; |
626 Reader* reader_; | 603 Reader* reader_; |
627 StreamingConstantEvaluator constant_evaluator_; | 604 StreamingConstantEvaluator constant_evaluator_; |
628 StreamingDartTypeTranslator type_translator_; | 605 StreamingDartTypeTranslator type_translator_; |
629 | 606 |
630 word unused_word; | |
631 intptr_t unused_intptr; | |
632 TokenPosition unused_tokenposition; | |
633 NameIndex unused_nameindex; | |
634 | |
635 friend class StreamingConstantEvaluator; | 607 friend class StreamingConstantEvaluator; |
636 friend class StreamingDartTypeTranslator; | 608 friend class StreamingDartTypeTranslator; |
637 friend class StreamingScopeBuilder; | 609 friend class StreamingScopeBuilder; |
| 610 friend class FunctionNodeHelper; |
| 611 friend class VariableDeclarationHelper; |
| 612 friend class FieldHelper; |
| 613 friend class ProcedureHelper; |
| 614 friend class ClassHelper; |
| 615 friend class ConstructorHelper; |
638 }; | 616 }; |
639 | 617 |
| 618 // Helper class that reads a kernel FunctionNode from binary. |
| 619 // |
| 620 // Use ReadUntilExcluding to read up to but not including a field. |
| 621 // One can then for instance read the field from the call-site (and remember to |
| 622 // call SetAt to inform this helper class), and then use this to read more. |
| 623 // "Dumb" fields are stored (e.g. integers) and can be fetched from this class. |
| 624 // If asked to read a "non-dumb" field (e.g. an expression) it will be skipped. |
| 625 class FunctionNodeHelper { |
| 626 public: |
| 627 enum Fields { |
| 628 kStart, // tag. |
| 629 kPosition, |
| 630 kEndPosition, |
| 631 kAsyncMarker, |
| 632 kDartAsyncMarker, |
| 633 kTypeParameters, |
| 634 kTotalParameterCount, |
| 635 kRequiredParameterCount, |
| 636 kPositionalParameters, |
| 637 kNamedParameters, |
| 638 kReturnType, |
| 639 kBody, |
| 640 kEnd |
| 641 }; |
| 642 |
| 643 explicit FunctionNodeHelper(StreamingFlowGraphBuilder* builder) { |
| 644 builder_ = builder; |
| 645 next_read_ = kStart; |
| 646 } |
| 647 |
| 648 void ReadUntilIncluding(Fields field) { |
| 649 ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1)); |
| 650 } |
| 651 |
| 652 void ReadUntilExcluding(Fields field) { |
| 653 if (field <= next_read_) return; |
| 654 |
| 655 // Ordered with fall-through. |
| 656 switch (next_read_) { |
| 657 case kStart: { |
| 658 Tag tag = builder_->ReadTag(); // read tag. |
| 659 ASSERT(tag == kFunctionNode); |
| 660 if (++next_read_ == field) return; |
| 661 } |
| 662 case kPosition: |
| 663 position_ = builder_->ReadPosition(); // read position. |
| 664 if (++next_read_ == field) return; |
| 665 case kEndPosition: |
| 666 end_position_ = builder_->ReadPosition(); // read end position. |
| 667 if (++next_read_ == field) return; |
| 668 case kAsyncMarker: |
| 669 async_marker_ = static_cast<FunctionNode::AsyncMarker>( |
| 670 builder_->ReadByte()); // read async marker. |
| 671 if (++next_read_ == field) return; |
| 672 case kDartAsyncMarker: |
| 673 dart_async_marker_ = static_cast<FunctionNode::AsyncMarker>( |
| 674 builder_->ReadByte()); // read dart async marker. |
| 675 if (++next_read_ == field) return; |
| 676 case kTypeParameters: |
| 677 builder_->SkipTypeParametersList(); // read type parameters. |
| 678 if (++next_read_ == field) return; |
| 679 case kTotalParameterCount: |
| 680 total_parameter_count_ = |
| 681 builder_->ReadUInt(); // read total parameter count. |
| 682 if (++next_read_ == field) return; |
| 683 case kRequiredParameterCount: |
| 684 required_parameter_count_ = |
| 685 builder_->ReadUInt(); // read required parameter count. |
| 686 if (++next_read_ == field) return; |
| 687 case kPositionalParameters: |
| 688 builder_->SkipListOfVariableDeclarations(); // read positionals. |
| 689 if (++next_read_ == field) return; |
| 690 case kNamedParameters: |
| 691 builder_->SkipListOfVariableDeclarations(); // read named. |
| 692 if (++next_read_ == field) return; |
| 693 case kReturnType: |
| 694 builder_->SkipDartType(); // read return type. |
| 695 if (++next_read_ == field) return; |
| 696 case kBody: |
| 697 if (builder_->ReadTag() == kSomething) |
| 698 builder_->SkipStatement(); // read body. |
| 699 if (++next_read_ == field) return; |
| 700 case kEnd: |
| 701 return; |
| 702 } |
| 703 } |
| 704 |
| 705 void SetNext(Fields field) { next_read_ = field; } |
| 706 void SetJustRead(Fields field) { |
| 707 next_read_ = field; |
| 708 ++next_read_; |
| 709 } |
| 710 |
| 711 TokenPosition position_; |
| 712 TokenPosition end_position_; |
| 713 FunctionNode::AsyncMarker async_marker_; |
| 714 FunctionNode::AsyncMarker dart_async_marker_; |
| 715 intptr_t total_parameter_count_; |
| 716 intptr_t required_parameter_count_; |
| 717 |
| 718 private: |
| 719 StreamingFlowGraphBuilder* builder_; |
| 720 intptr_t next_read_; |
| 721 }; |
| 722 |
| 723 // Helper class that reads a kernel VariableDeclaration from binary. |
| 724 // |
| 725 // Use ReadUntilExcluding to read up to but not including a field. |
| 726 // One can then for instance read the field from the call-site (and remember to |
| 727 // call SetAt to inform this helper class), and then use this to read more. |
| 728 // "Dumb" fields are stored (e.g. integers) and can be fetched from this class. |
| 729 // If asked to read a "non-dumb" field (e.g. an expression) it will be skipped. |
| 730 class VariableDeclarationHelper { |
| 731 public: |
| 732 enum Fields { |
| 733 kPosition, |
| 734 kEqualPosition, |
| 735 kFlags, |
| 736 kNameIndex, |
| 737 kType, |
| 738 kInitializer, |
| 739 kEnd |
| 740 }; |
| 741 |
| 742 explicit VariableDeclarationHelper(StreamingFlowGraphBuilder* builder) { |
| 743 builder_ = builder; |
| 744 next_read_ = kPosition; |
| 745 } |
| 746 |
| 747 void ReadUntilIncluding(Fields field) { |
| 748 ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1)); |
| 749 } |
| 750 |
| 751 void ReadUntilExcluding(Fields field) { |
| 752 if (field <= next_read_) return; |
| 753 |
| 754 // Ordered with fall-through. |
| 755 switch (next_read_) { |
| 756 case kPosition: |
| 757 position_ = builder_->ReadPosition(); // read position. |
| 758 if (++next_read_ == field) return; |
| 759 case kEqualPosition: |
| 760 equals_position_ = builder_->ReadPosition(); // read equals position. |
| 761 if (++next_read_ == field) return; |
| 762 case kFlags: |
| 763 flags_ = builder_->ReadFlags(); // read flags. |
| 764 if (++next_read_ == field) return; |
| 765 case kNameIndex: |
| 766 name_index_ = builder_->ReadStringReference(); // read name index. |
| 767 if (++next_read_ == field) return; |
| 768 case kType: |
| 769 builder_->SkipDartType(); // read type. |
| 770 if (++next_read_ == field) return; |
| 771 case kInitializer: |
| 772 if (builder_->ReadTag() == kSomething) |
| 773 builder_->SkipExpression(); // read initializer. |
| 774 if (++next_read_ == field) return; |
| 775 case kEnd: |
| 776 return; |
| 777 } |
| 778 } |
| 779 |
| 780 void SetNext(Fields field) { next_read_ = field; } |
| 781 void SetJustRead(Fields field) { |
| 782 next_read_ = field; |
| 783 ++next_read_; |
| 784 } |
| 785 |
| 786 bool IsConst() { |
| 787 return (flags_ & VariableDeclaration::kFlagConst) == |
| 788 VariableDeclaration::kFlagConst; |
| 789 } |
| 790 bool IsFinal() { |
| 791 return (flags_ & VariableDeclaration::kFlagFinal) == |
| 792 VariableDeclaration::kFlagFinal; |
| 793 } |
| 794 |
| 795 TokenPosition position_; |
| 796 TokenPosition equals_position_; |
| 797 word flags_; |
| 798 StringIndex name_index_; |
| 799 |
| 800 private: |
| 801 StreamingFlowGraphBuilder* builder_; |
| 802 intptr_t next_read_; |
| 803 }; |
| 804 |
| 805 // Helper class that reads a kernel Field from binary. |
| 806 // |
| 807 // Use ReadUntilExcluding to read up to but not including a field. |
| 808 // One can then for instance read the field from the call-site (and remember to |
| 809 // call SetAt to inform this helper class), and then use this to read more. |
| 810 // "Dumb" fields are stored (e.g. integers) and can be fetched from this class. |
| 811 // If asked to read a "non-dumb" field (e.g. an expression) it will be skipped. |
| 812 class FieldHelper { |
| 813 public: |
| 814 enum Fields { |
| 815 kStart, // tag. |
| 816 kCanonicalName, |
| 817 kPosition, |
| 818 kEndPosition, |
| 819 kFlags, |
| 820 kParentClassBinaryOffset, |
| 821 kName, |
| 822 kSourceUriIndex, |
| 823 kAnnotations, |
| 824 kType, |
| 825 kInitializer, |
| 826 kEnd |
| 827 }; |
| 828 |
| 829 explicit FieldHelper(StreamingFlowGraphBuilder* builder) { |
| 830 builder_ = builder; |
| 831 next_read_ = kStart; |
| 832 } |
| 833 |
| 834 void ReadUntilIncluding(Fields field) { |
| 835 ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1)); |
| 836 } |
| 837 |
| 838 void ReadUntilExcluding(Fields field) { |
| 839 if (field <= next_read_) return; |
| 840 |
| 841 // Ordered with fall-through. |
| 842 switch (next_read_) { |
| 843 case kStart: { |
| 844 Tag tag = builder_->ReadTag(); // read tag. |
| 845 ASSERT(tag == kField); |
| 846 if (++next_read_ == field) return; |
| 847 } |
| 848 case kCanonicalName: |
| 849 canonical_name_ = |
| 850 builder_->ReadCanonicalNameReference(); // read canonical_name. |
| 851 if (++next_read_ == field) return; |
| 852 case kPosition: |
| 853 position_ = builder_->ReadPosition(); // read position. |
| 854 if (++next_read_ == field) return; |
| 855 case kEndPosition: |
| 856 end_position_ = builder_->ReadPosition(); // read end position. |
| 857 if (++next_read_ == field) return; |
| 858 case kFlags: |
| 859 flags_ = builder_->ReadFlags(); // read flags. |
| 860 if (++next_read_ == field) return; |
| 861 case kParentClassBinaryOffset: |
| 862 parent_class_binary_offset_ = |
| 863 builder_->ReadUInt(); // read parent class binary offset. |
| 864 if (++next_read_ == field) return; |
| 865 case kName: |
| 866 builder_->SkipName(); // read name. |
| 867 if (++next_read_ == field) return; |
| 868 case kSourceUriIndex: |
| 869 source_uri_index_ = builder_->ReadUInt(); // read source_uri_index. |
| 870 if (++next_read_ == field) return; |
| 871 case kAnnotations: |
| 872 builder_->SkipListOfExpressions(); // read annotations. |
| 873 if (++next_read_ == field) return; |
| 874 case kType: |
| 875 builder_->SkipDartType(); // read type. |
| 876 if (++next_read_ == field) return; |
| 877 case kInitializer: |
| 878 if (builder_->ReadTag() == kSomething) |
| 879 builder_->SkipExpression(); // read initializer. |
| 880 if (++next_read_ == field) return; |
| 881 case kEnd: |
| 882 return; |
| 883 } |
| 884 } |
| 885 |
| 886 void SetNext(Fields field) { next_read_ = field; } |
| 887 void SetJustRead(Fields field) { |
| 888 next_read_ = field; |
| 889 ++next_read_; |
| 890 } |
| 891 |
| 892 bool IsConst() { return (flags_ & Field::kFlagConst) == Field::kFlagConst; } |
| 893 bool IsFinal() { return (flags_ & Field::kFlagFinal) == Field::kFlagFinal; } |
| 894 bool IsStatic() { |
| 895 return (flags_ & Field::kFlagStatic) == Field::kFlagStatic; |
| 896 } |
| 897 |
| 898 NameIndex canonical_name_; |
| 899 TokenPosition position_; |
| 900 TokenPosition end_position_; |
| 901 word flags_; |
| 902 intptr_t parent_class_binary_offset_; |
| 903 intptr_t source_uri_index_; |
| 904 |
| 905 private: |
| 906 StreamingFlowGraphBuilder* builder_; |
| 907 intptr_t next_read_; |
| 908 }; |
| 909 |
| 910 |
| 911 // Helper class that reads a kernel Procedure from binary. |
| 912 // |
| 913 // Use ReadUntilExcluding to read up to but not including a field. |
| 914 // One can then for instance read the field from the call-site (and remember to |
| 915 // call SetAt to inform this helper class), and then use this to read more. |
| 916 // "Dumb" fields are stored (e.g. integers) and can be fetched from this class. |
| 917 // If asked to read a "non-dumb" field (e.g. an expression) it will be skipped. |
| 918 class ProcedureHelper { |
| 919 public: |
| 920 enum Fields { |
| 921 kStart, // tag. |
| 922 kCanonicalName, |
| 923 kPosition, |
| 924 kEndPosition, |
| 925 kKind, |
| 926 kFlags, |
| 927 kParentClassBinaryOffset, |
| 928 kName, |
| 929 kSourceUriIndex, |
| 930 kAnnotations, |
| 931 kFunction, |
| 932 kEnd |
| 933 }; |
| 934 |
| 935 explicit ProcedureHelper(StreamingFlowGraphBuilder* builder) { |
| 936 builder_ = builder; |
| 937 next_read_ = kStart; |
| 938 } |
| 939 |
| 940 void ReadUntilIncluding(Fields field) { |
| 941 ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1)); |
| 942 } |
| 943 |
| 944 void ReadUntilExcluding(Fields field) { |
| 945 if (field <= next_read_) return; |
| 946 |
| 947 // Ordered with fall-through. |
| 948 switch (next_read_) { |
| 949 case kStart: { |
| 950 Tag tag = builder_->ReadTag(); // read tag. |
| 951 ASSERT(tag == kProcedure); |
| 952 if (++next_read_ == field) return; |
| 953 } |
| 954 case kCanonicalName: |
| 955 canonical_name_ = |
| 956 builder_->ReadCanonicalNameReference(); // read canonical_name. |
| 957 if (++next_read_ == field) return; |
| 958 case kPosition: |
| 959 position_ = builder_->ReadPosition(); // read position. |
| 960 if (++next_read_ == field) return; |
| 961 case kEndPosition: |
| 962 end_position_ = builder_->ReadPosition(); // read end position. |
| 963 if (++next_read_ == field) return; |
| 964 case kKind: |
| 965 kind_ = static_cast<Procedure::ProcedureKind>( |
| 966 builder_->ReadByte()); // read kind. |
| 967 if (++next_read_ == field) return; |
| 968 case kFlags: |
| 969 flags_ = builder_->ReadFlags(); // read flags. |
| 970 if (++next_read_ == field) return; |
| 971 case kParentClassBinaryOffset: |
| 972 parent_class_binary_offset_ = |
| 973 builder_->ReadUInt(); // read parent class binary offset. |
| 974 if (++next_read_ == field) return; |
| 975 case kName: |
| 976 builder_->SkipName(); // read name. |
| 977 if (++next_read_ == field) return; |
| 978 case kSourceUriIndex: |
| 979 source_uri_index_ = builder_->ReadUInt(); // read source_uri_index. |
| 980 if (++next_read_ == field) return; |
| 981 case kAnnotations: |
| 982 builder_->SkipListOfExpressions(); // read annotations. |
| 983 if (++next_read_ == field) return; |
| 984 case kFunction: |
| 985 if (builder_->ReadTag() == kSomething) |
| 986 builder_->SkipFunctionNode(); // read function node. |
| 987 if (++next_read_ == field) return; |
| 988 case kEnd: |
| 989 return; |
| 990 } |
| 991 } |
| 992 |
| 993 void SetNext(Fields field) { next_read_ = field; } |
| 994 void SetJustRead(Fields field) { |
| 995 next_read_ = field; |
| 996 ++next_read_; |
| 997 } |
| 998 |
| 999 bool IsStatic() { |
| 1000 return (flags_ & Procedure::kFlagStatic) == Procedure::kFlagStatic; |
| 1001 } |
| 1002 bool IsAbstract() { |
| 1003 return (flags_ & Procedure::kFlagAbstract) == Procedure::kFlagAbstract; |
| 1004 } |
| 1005 bool IsExternal() { |
| 1006 return (flags_ & Procedure::kFlagExternal) == Procedure::kFlagExternal; |
| 1007 } |
| 1008 bool IsConst() { |
| 1009 return (flags_ & Procedure::kFlagConst) == Procedure::kFlagConst; |
| 1010 } |
| 1011 |
| 1012 NameIndex canonical_name_; |
| 1013 TokenPosition position_; |
| 1014 TokenPosition end_position_; |
| 1015 Procedure::ProcedureKind kind_; |
| 1016 word flags_; |
| 1017 intptr_t parent_class_binary_offset_; |
| 1018 intptr_t source_uri_index_; |
| 1019 |
| 1020 private: |
| 1021 StreamingFlowGraphBuilder* builder_; |
| 1022 intptr_t next_read_; |
| 1023 }; |
| 1024 |
| 1025 // Helper class that reads a kernel Constructor from binary. |
| 1026 // |
| 1027 // Use ReadUntilExcluding to read up to but not including a field. |
| 1028 // One can then for instance read the field from the call-site (and remember to |
| 1029 // call SetAt to inform this helper class), and then use this to read more. |
| 1030 // "Dumb" fields are stored (e.g. integers) and can be fetched from this class. |
| 1031 // If asked to read a "non-dumb" field (e.g. an expression) it will be skipped. |
| 1032 class ConstructorHelper { |
| 1033 public: |
| 1034 enum Fields { |
| 1035 kStart, // tag. |
| 1036 kCanonicalName, |
| 1037 kPosition, |
| 1038 kEndPosition, |
| 1039 kFlags, |
| 1040 kParentClassBinaryOffset, |
| 1041 kName, |
| 1042 kAnnotations, |
| 1043 kFunction, |
| 1044 kInitializers, |
| 1045 kEnd |
| 1046 }; |
| 1047 |
| 1048 explicit ConstructorHelper(StreamingFlowGraphBuilder* builder) { |
| 1049 builder_ = builder; |
| 1050 next_read_ = kStart; |
| 1051 } |
| 1052 |
| 1053 void ReadUntilIncluding(Fields field) { |
| 1054 ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1)); |
| 1055 } |
| 1056 |
| 1057 void ReadUntilExcluding(Fields field) { |
| 1058 if (field <= next_read_) return; |
| 1059 |
| 1060 // Ordered with fall-through. |
| 1061 switch (next_read_) { |
| 1062 case kStart: { |
| 1063 Tag tag = builder_->ReadTag(); // read tag. |
| 1064 ASSERT(tag == kConstructor); |
| 1065 if (++next_read_ == field) return; |
| 1066 } |
| 1067 case kCanonicalName: |
| 1068 canonical_name_ = |
| 1069 builder_->ReadCanonicalNameReference(); // read canonical_name. |
| 1070 if (++next_read_ == field) return; |
| 1071 case kPosition: |
| 1072 position_ = builder_->ReadPosition(); // read position. |
| 1073 if (++next_read_ == field) return; |
| 1074 case kEndPosition: |
| 1075 end_position_ = builder_->ReadPosition(); // read end position. |
| 1076 if (++next_read_ == field) return; |
| 1077 case kFlags: |
| 1078 flags_ = builder_->ReadFlags(); // read flags. |
| 1079 if (++next_read_ == field) return; |
| 1080 case kParentClassBinaryOffset: |
| 1081 parent_class_binary_offset_ = |
| 1082 builder_->ReadUInt(); // read parent class binary offset. |
| 1083 if (++next_read_ == field) return; |
| 1084 case kName: |
| 1085 builder_->SkipName(); // read name. |
| 1086 if (++next_read_ == field) return; |
| 1087 case kAnnotations: |
| 1088 builder_->SkipListOfExpressions(); // read annotations. |
| 1089 if (++next_read_ == field) return; |
| 1090 case kFunction: |
| 1091 builder_->SkipFunctionNode(); // read function. |
| 1092 if (++next_read_ == field) return; |
| 1093 case kInitializers: { |
| 1094 intptr_t list_length = |
| 1095 builder_->ReadListLength(); // read initializers list length. |
| 1096 for (intptr_t i = 0; i < list_length; i++) { |
| 1097 Tag tag = builder_->ReadTag(); |
| 1098 switch (tag) { |
| 1099 case kInvalidInitializer: |
| 1100 continue; |
| 1101 case kFieldInitializer: |
| 1102 builder_->SkipCanonicalNameReference(); // read field_reference. |
| 1103 builder_->SkipExpression(); // read value. |
| 1104 continue; |
| 1105 case kSuperInitializer: |
| 1106 builder_->SkipCanonicalNameReference(); // read target_reference. |
| 1107 builder_->SkipArguments(); // read arguments. |
| 1108 continue; |
| 1109 case kRedirectingInitializer: |
| 1110 builder_->SkipCanonicalNameReference(); // read target_reference. |
| 1111 builder_->SkipArguments(); // read arguments. |
| 1112 continue; |
| 1113 case kLocalInitializer: |
| 1114 builder_->SkipVariableDeclaration(); // read variable. |
| 1115 continue; |
| 1116 default: |
| 1117 UNREACHABLE(); |
| 1118 } |
| 1119 } |
| 1120 if (++next_read_ == field) return; |
| 1121 } |
| 1122 case kEnd: |
| 1123 return; |
| 1124 } |
| 1125 } |
| 1126 |
| 1127 void SetNext(Fields field) { next_read_ = field; } |
| 1128 void SetJustRead(Fields field) { |
| 1129 next_read_ = field; |
| 1130 ++next_read_; |
| 1131 } |
| 1132 |
| 1133 NameIndex canonical_name_; |
| 1134 TokenPosition position_; |
| 1135 TokenPosition end_position_; |
| 1136 word flags_; |
| 1137 intptr_t parent_class_binary_offset_; |
| 1138 |
| 1139 private: |
| 1140 StreamingFlowGraphBuilder* builder_; |
| 1141 intptr_t next_read_; |
| 1142 }; |
| 1143 |
| 1144 // Helper class that reads a kernel Class from binary. |
| 1145 // |
| 1146 // Use ReadUntilExcluding to read up to but not including a field. |
| 1147 // One can then for instance read the field from the call-site (and remember to |
| 1148 // call SetAt to inform this helper class), and then use this to read more. |
| 1149 // "Dumb" fields are stored (e.g. integers) and can be fetched from this class. |
| 1150 // If asked to read a "non-dumb" field (e.g. an expression) it will be skipped. |
| 1151 class ClassHelper { |
| 1152 public: |
| 1153 enum Fields { |
| 1154 kStart, // tag. |
| 1155 kCanonicalName, |
| 1156 kPosition, |
| 1157 kIsAbstract, |
| 1158 kNameIndex, |
| 1159 kSourceUriIndex, |
| 1160 kAnnotations, |
| 1161 kTypeParameters, |
| 1162 kSuperClass, |
| 1163 kMixinType, |
| 1164 kImplementedClasses, |
| 1165 kFields, |
| 1166 kConstructors, |
| 1167 kProcedures, |
| 1168 kEnd |
| 1169 }; |
| 1170 |
| 1171 explicit ClassHelper(StreamingFlowGraphBuilder* builder) { |
| 1172 builder_ = builder; |
| 1173 next_read_ = kStart; |
| 1174 } |
| 1175 |
| 1176 void ReadUntilIncluding(Fields field) { |
| 1177 ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1)); |
| 1178 } |
| 1179 |
| 1180 void ReadUntilExcluding(Fields field) { |
| 1181 if (field <= next_read_) return; |
| 1182 |
| 1183 // Ordered with fall-through. |
| 1184 switch (next_read_) { |
| 1185 case kStart: { |
| 1186 Tag tag = builder_->ReadTag(); // read tag. |
| 1187 ASSERT(tag == kClass); |
| 1188 if (++next_read_ == field) return; |
| 1189 } |
| 1190 case kCanonicalName: |
| 1191 canonical_name_ = |
| 1192 builder_->ReadCanonicalNameReference(); // read canonical_name. |
| 1193 if (++next_read_ == field) return; |
| 1194 case kPosition: |
| 1195 position_ = builder_->ReadPosition(); // read position. |
| 1196 if (++next_read_ == field) return; |
| 1197 case kIsAbstract: |
| 1198 is_abstract_ = builder_->ReadBool(); // read is_abstract. |
| 1199 if (++next_read_ == field) return; |
| 1200 case kNameIndex: |
| 1201 name_index_ = builder_->ReadStringReference(); // read name index. |
| 1202 if (++next_read_ == field) return; |
| 1203 case kSourceUriIndex: |
| 1204 source_uri_index_ = builder_->ReadUInt(); // read source_uri_index. |
| 1205 if (++next_read_ == field) return; |
| 1206 case kAnnotations: |
| 1207 builder_->SkipListOfExpressions(); // read annotations. |
| 1208 if (++next_read_ == field) return; |
| 1209 case kTypeParameters: |
| 1210 builder_->SkipTypeParametersList(); // read type parameters. |
| 1211 if (++next_read_ == field) return; |
| 1212 case kSuperClass: { |
| 1213 Tag type_tag = builder_->ReadTag(); // read super class type (part 1). |
| 1214 if (type_tag == kSomething) { |
| 1215 builder_->SkipDartType(); // read super class type (part 2). |
| 1216 } |
| 1217 if (++next_read_ == field) return; |
| 1218 } |
| 1219 case kMixinType: { |
| 1220 Tag type_tag = builder_->ReadTag(); // read mixin type (part 1). |
| 1221 if (type_tag == kSomething) { |
| 1222 builder_->SkipDartType(); // read mixin type (part 2). |
| 1223 } |
| 1224 if (++next_read_ == field) return; |
| 1225 } |
| 1226 case kImplementedClasses: |
| 1227 builder_->SkipListOfDartTypes(); // read implemented_classes. |
| 1228 if (++next_read_ == field) return; |
| 1229 case kFields: { |
| 1230 intptr_t list_length = |
| 1231 builder_->ReadListLength(); // read fields list length. |
| 1232 for (intptr_t i = 0; i < list_length; i++) { |
| 1233 FieldHelper field_helper(builder_); |
| 1234 field_helper.ReadUntilExcluding(FieldHelper::kEnd); // read field. |
| 1235 } |
| 1236 if (++next_read_ == field) return; |
| 1237 } |
| 1238 case kConstructors: { |
| 1239 intptr_t list_length = |
| 1240 builder_->ReadListLength(); // read constructors list length. |
| 1241 for (intptr_t i = 0; i < list_length; i++) { |
| 1242 ConstructorHelper constructor_helper(builder_); |
| 1243 constructor_helper.ReadUntilExcluding( |
| 1244 ConstructorHelper::kEnd); // read constructor. |
| 1245 } |
| 1246 if (++next_read_ == field) return; |
| 1247 } |
| 1248 case kProcedures: { |
| 1249 intptr_t list_length = |
| 1250 builder_->ReadListLength(); // read procedures list length. |
| 1251 for (intptr_t i = 0; i < list_length; i++) { |
| 1252 ProcedureHelper procedure_helper(builder_); |
| 1253 procedure_helper.ReadUntilExcluding( |
| 1254 ProcedureHelper::kEnd); // read procedure. |
| 1255 } |
| 1256 if (++next_read_ == field) return; |
| 1257 } |
| 1258 case kEnd: |
| 1259 return; |
| 1260 } |
| 1261 } |
| 1262 |
| 1263 void SetNext(Fields field) { next_read_ = field; } |
| 1264 void SetJustRead(Fields field) { |
| 1265 next_read_ = field; |
| 1266 ++next_read_; |
| 1267 } |
| 1268 |
| 1269 NameIndex canonical_name_; |
| 1270 TokenPosition position_; |
| 1271 bool is_abstract_; |
| 1272 StringIndex name_index_; |
| 1273 intptr_t source_uri_index_; |
| 1274 |
| 1275 private: |
| 1276 StreamingFlowGraphBuilder* builder_; |
| 1277 intptr_t next_read_; |
| 1278 }; |
| 1279 |
640 // A helper class that saves the current reader position, goes to another reader | 1280 // A helper class that saves the current reader position, goes to another reader |
641 // position, and upon destruction, resets to the original reader position. | 1281 // position, and upon destruction, resets to the original reader position. |
642 class AlternativeReadingScope { | 1282 class AlternativeReadingScope { |
643 public: | 1283 public: |
644 AlternativeReadingScope(Reader* reader, intptr_t new_position) | 1284 AlternativeReadingScope(Reader* reader, intptr_t new_position) |
645 : reader_(reader), saved_offset_(reader_->offset()) { | 1285 : reader_(reader), saved_offset_(reader_->offset()) { |
646 reader_->set_offset(new_position); | 1286 reader_->set_offset(new_position); |
647 } | 1287 } |
648 | 1288 |
649 explicit AlternativeReadingScope(Reader* reader) | 1289 explicit AlternativeReadingScope(Reader* reader) |
650 : reader_(reader), saved_offset_(reader_->offset()) {} | 1290 : reader_(reader), saved_offset_(reader_->offset()) {} |
651 | 1291 |
652 ~AlternativeReadingScope() { reader_->set_offset(saved_offset_); } | 1292 ~AlternativeReadingScope() { reader_->set_offset(saved_offset_); } |
653 | 1293 |
| 1294 intptr_t saved_offset() { return saved_offset_; } |
| 1295 |
654 private: | 1296 private: |
655 Reader* reader_; | 1297 Reader* reader_; |
656 intptr_t saved_offset_; | 1298 intptr_t saved_offset_; |
657 }; | 1299 }; |
658 | 1300 |
659 } // namespace kernel | 1301 } // namespace kernel |
660 } // namespace dart | 1302 } // namespace dart |
661 | 1303 |
662 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 1304 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
663 #endif // RUNTIME_VM_KERNEL_BINARY_FLOWGRAPH_H_ | 1305 #endif // RUNTIME_VM_KERNEL_BINARY_FLOWGRAPH_H_ |
OLD | NEW |