| Index: runtime/vm/kernel_binary_flowgraph.h
|
| diff --git a/runtime/vm/kernel_binary_flowgraph.h b/runtime/vm/kernel_binary_flowgraph.h
|
| index 4667e5152d1be8c4b134e8e9b40f62340486f9a3..f3cce6b2d2fabf7a09aa32bbd121a3baf1d7e57b 100644
|
| --- a/runtime/vm/kernel_binary_flowgraph.h
|
| +++ b/runtime/vm/kernel_binary_flowgraph.h
|
| @@ -198,11 +198,6 @@ class StreamingScopeBuilder {
|
|
|
| StreamingFlowGraphBuilder* builder_;
|
| StreamingDartTypeTranslator type_translator_;
|
| -
|
| - word unused_word;
|
| - intptr_t unused_intptr;
|
| - TokenPosition unused_tokenposition;
|
| - NameIndex unused_nameindex;
|
| };
|
|
|
|
|
| @@ -301,6 +296,7 @@ class StreamingConstantEvaluator {
|
| Instance& result_;
|
| };
|
|
|
| +class FunctionNodeHelper;
|
|
|
| class StreamingFlowGraphBuilder {
|
| public:
|
| @@ -343,33 +339,13 @@ class StreamingFlowGraphBuilder {
|
| void GetTypeParameterInfoForClass(intptr_t class_offset,
|
| intptr_t* type_paremeter_counts,
|
| intptr_t* type_paremeter_offset);
|
| - void ReadClassUntilFields();
|
| - void ReadClassUntilTypeParameters();
|
| - /**
|
| - * Will return binary offset of parent class.
|
| - */
|
| - intptr_t ReadConstructorUntilFunctionNode();
|
| - /**
|
| - * Will read until the function node; as this is optional, will return the tag
|
| - * (i.e. either kSomething or kNothing).
|
| - */
|
| - Tag ReadProcedureUntilFunctionNode(word* kind, intptr_t* parent_offset);
|
|
|
| - void ReadFieldUntilAnnotation(NameIndex* canonical_name,
|
| - TokenPosition* position,
|
| - TokenPosition* end_position,
|
| - word* flags,
|
| - intptr_t* parent_offset);
|
| void GetTypeParameterInfoForPossibleProcedure(
|
| intptr_t outermost_kernel_offset,
|
| bool* member_is_procedure,
|
| bool* is_factory_procedure,
|
| intptr_t* member_type_parameters,
|
| intptr_t* member_type_parameters_offset_start);
|
| - void ReadFunctionNodeUntilTypeParameters(TokenPosition* position,
|
| - TokenPosition* end_position,
|
| - word* async_marker,
|
| - word* dart_async_marker);
|
| /**
|
| * Will return kernel offset for parent class if reading a constructor.
|
| * Will otherwise return -1.
|
| @@ -618,7 +594,8 @@ class StreamingFlowGraphBuilder {
|
| void SetupFunctionParameters(const dart::Class& klass,
|
| const dart::Function& function,
|
| bool is_method,
|
| - bool is_closure);
|
| + bool is_closure,
|
| + FunctionNodeHelper* function_node_helper);
|
|
|
| FlowGraphBuilder* flow_graph_builder_;
|
| TranslationHelper& translation_helper_;
|
| @@ -627,14 +604,677 @@ class StreamingFlowGraphBuilder {
|
| StreamingConstantEvaluator constant_evaluator_;
|
| StreamingDartTypeTranslator type_translator_;
|
|
|
| - word unused_word;
|
| - intptr_t unused_intptr;
|
| - TokenPosition unused_tokenposition;
|
| - NameIndex unused_nameindex;
|
| -
|
| friend class StreamingConstantEvaluator;
|
| friend class StreamingDartTypeTranslator;
|
| friend class StreamingScopeBuilder;
|
| + friend class FunctionNodeHelper;
|
| + friend class VariableDeclarationHelper;
|
| + friend class FieldHelper;
|
| + friend class ProcedureHelper;
|
| + friend class ClassHelper;
|
| + friend class ConstructorHelper;
|
| +};
|
| +
|
| +// Helper class that reads a kernel FunctionNode from binary.
|
| +//
|
| +// Use ReadUntilExcluding to read up to but not including a field.
|
| +// One can then for instance read the field from the call-site (and remember to
|
| +// call SetAt to inform this helper class), and then use this to read more.
|
| +// "Dumb" fields are stored (e.g. integers) and can be fetched from this class.
|
| +// If asked to read a "non-dumb" field (e.g. an expression) it will be skipped.
|
| +class FunctionNodeHelper {
|
| + public:
|
| + enum Fields {
|
| + kStart, // tag.
|
| + kPosition,
|
| + kEndPosition,
|
| + kAsyncMarker,
|
| + kDartAsyncMarker,
|
| + kTypeParameters,
|
| + kTotalParameterCount,
|
| + kRequiredParameterCount,
|
| + kPositionalParameters,
|
| + kNamedParameters,
|
| + kReturnType,
|
| + kBody,
|
| + kEnd
|
| + };
|
| +
|
| + explicit FunctionNodeHelper(StreamingFlowGraphBuilder* builder) {
|
| + builder_ = builder;
|
| + next_read_ = kStart;
|
| + }
|
| +
|
| + void ReadUntilIncluding(Fields field) {
|
| + ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1));
|
| + }
|
| +
|
| + void ReadUntilExcluding(Fields field) {
|
| + if (field <= next_read_) return;
|
| +
|
| + // Ordered with fall-through.
|
| + switch (next_read_) {
|
| + case kStart: {
|
| + Tag tag = builder_->ReadTag(); // read tag.
|
| + ASSERT(tag == kFunctionNode);
|
| + if (++next_read_ == field) return;
|
| + }
|
| + case kPosition:
|
| + position_ = builder_->ReadPosition(); // read position.
|
| + if (++next_read_ == field) return;
|
| + case kEndPosition:
|
| + end_position_ = builder_->ReadPosition(); // read end position.
|
| + if (++next_read_ == field) return;
|
| + case kAsyncMarker:
|
| + async_marker_ = static_cast<FunctionNode::AsyncMarker>(
|
| + builder_->ReadByte()); // read async marker.
|
| + if (++next_read_ == field) return;
|
| + case kDartAsyncMarker:
|
| + dart_async_marker_ = static_cast<FunctionNode::AsyncMarker>(
|
| + builder_->ReadByte()); // read dart async marker.
|
| + if (++next_read_ == field) return;
|
| + case kTypeParameters:
|
| + builder_->SkipTypeParametersList(); // read type parameters.
|
| + if (++next_read_ == field) return;
|
| + case kTotalParameterCount:
|
| + total_parameter_count_ =
|
| + builder_->ReadUInt(); // read total parameter count.
|
| + if (++next_read_ == field) return;
|
| + case kRequiredParameterCount:
|
| + required_parameter_count_ =
|
| + builder_->ReadUInt(); // read required parameter count.
|
| + if (++next_read_ == field) return;
|
| + case kPositionalParameters:
|
| + builder_->SkipListOfVariableDeclarations(); // read positionals.
|
| + if (++next_read_ == field) return;
|
| + case kNamedParameters:
|
| + builder_->SkipListOfVariableDeclarations(); // read named.
|
| + if (++next_read_ == field) return;
|
| + case kReturnType:
|
| + builder_->SkipDartType(); // read return type.
|
| + if (++next_read_ == field) return;
|
| + case kBody:
|
| + if (builder_->ReadTag() == kSomething)
|
| + builder_->SkipStatement(); // read body.
|
| + if (++next_read_ == field) return;
|
| + case kEnd:
|
| + return;
|
| + }
|
| + }
|
| +
|
| + void SetNext(Fields field) { next_read_ = field; }
|
| + void SetJustRead(Fields field) {
|
| + next_read_ = field;
|
| + ++next_read_;
|
| + }
|
| +
|
| + TokenPosition position_;
|
| + TokenPosition end_position_;
|
| + FunctionNode::AsyncMarker async_marker_;
|
| + FunctionNode::AsyncMarker dart_async_marker_;
|
| + intptr_t total_parameter_count_;
|
| + intptr_t required_parameter_count_;
|
| +
|
| + private:
|
| + StreamingFlowGraphBuilder* builder_;
|
| + intptr_t next_read_;
|
| +};
|
| +
|
| +// Helper class that reads a kernel VariableDeclaration from binary.
|
| +//
|
| +// Use ReadUntilExcluding to read up to but not including a field.
|
| +// One can then for instance read the field from the call-site (and remember to
|
| +// call SetAt to inform this helper class), and then use this to read more.
|
| +// "Dumb" fields are stored (e.g. integers) and can be fetched from this class.
|
| +// If asked to read a "non-dumb" field (e.g. an expression) it will be skipped.
|
| +class VariableDeclarationHelper {
|
| + public:
|
| + enum Fields {
|
| + kPosition,
|
| + kEqualPosition,
|
| + kFlags,
|
| + kNameIndex,
|
| + kType,
|
| + kInitializer,
|
| + kEnd
|
| + };
|
| +
|
| + explicit VariableDeclarationHelper(StreamingFlowGraphBuilder* builder) {
|
| + builder_ = builder;
|
| + next_read_ = kPosition;
|
| + }
|
| +
|
| + void ReadUntilIncluding(Fields field) {
|
| + ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1));
|
| + }
|
| +
|
| + void ReadUntilExcluding(Fields field) {
|
| + if (field <= next_read_) return;
|
| +
|
| + // Ordered with fall-through.
|
| + switch (next_read_) {
|
| + case kPosition:
|
| + position_ = builder_->ReadPosition(); // read position.
|
| + if (++next_read_ == field) return;
|
| + case kEqualPosition:
|
| + equals_position_ = builder_->ReadPosition(); // read equals position.
|
| + if (++next_read_ == field) return;
|
| + case kFlags:
|
| + flags_ = builder_->ReadFlags(); // read flags.
|
| + if (++next_read_ == field) return;
|
| + case kNameIndex:
|
| + name_index_ = builder_->ReadStringReference(); // read name index.
|
| + if (++next_read_ == field) return;
|
| + case kType:
|
| + builder_->SkipDartType(); // read type.
|
| + if (++next_read_ == field) return;
|
| + case kInitializer:
|
| + if (builder_->ReadTag() == kSomething)
|
| + builder_->SkipExpression(); // read initializer.
|
| + if (++next_read_ == field) return;
|
| + case kEnd:
|
| + return;
|
| + }
|
| + }
|
| +
|
| + void SetNext(Fields field) { next_read_ = field; }
|
| + void SetJustRead(Fields field) {
|
| + next_read_ = field;
|
| + ++next_read_;
|
| + }
|
| +
|
| + bool IsConst() {
|
| + return (flags_ & VariableDeclaration::kFlagConst) ==
|
| + VariableDeclaration::kFlagConst;
|
| + }
|
| + bool IsFinal() {
|
| + return (flags_ & VariableDeclaration::kFlagFinal) ==
|
| + VariableDeclaration::kFlagFinal;
|
| + }
|
| +
|
| + TokenPosition position_;
|
| + TokenPosition equals_position_;
|
| + word flags_;
|
| + StringIndex name_index_;
|
| +
|
| + private:
|
| + StreamingFlowGraphBuilder* builder_;
|
| + intptr_t next_read_;
|
| +};
|
| +
|
| +// Helper class that reads a kernel Field from binary.
|
| +//
|
| +// Use ReadUntilExcluding to read up to but not including a field.
|
| +// One can then for instance read the field from the call-site (and remember to
|
| +// call SetAt to inform this helper class), and then use this to read more.
|
| +// "Dumb" fields are stored (e.g. integers) and can be fetched from this class.
|
| +// If asked to read a "non-dumb" field (e.g. an expression) it will be skipped.
|
| +class FieldHelper {
|
| + public:
|
| + enum Fields {
|
| + kStart, // tag.
|
| + kCanonicalName,
|
| + kPosition,
|
| + kEndPosition,
|
| + kFlags,
|
| + kParentClassBinaryOffset,
|
| + kName,
|
| + kSourceUriIndex,
|
| + kAnnotations,
|
| + kType,
|
| + kInitializer,
|
| + kEnd
|
| + };
|
| +
|
| + explicit FieldHelper(StreamingFlowGraphBuilder* builder) {
|
| + builder_ = builder;
|
| + next_read_ = kStart;
|
| + }
|
| +
|
| + void ReadUntilIncluding(Fields field) {
|
| + ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1));
|
| + }
|
| +
|
| + void ReadUntilExcluding(Fields field) {
|
| + if (field <= next_read_) return;
|
| +
|
| + // Ordered with fall-through.
|
| + switch (next_read_) {
|
| + case kStart: {
|
| + Tag tag = builder_->ReadTag(); // read tag.
|
| + ASSERT(tag == kField);
|
| + if (++next_read_ == field) return;
|
| + }
|
| + case kCanonicalName:
|
| + canonical_name_ =
|
| + builder_->ReadCanonicalNameReference(); // read canonical_name.
|
| + if (++next_read_ == field) return;
|
| + case kPosition:
|
| + position_ = builder_->ReadPosition(); // read position.
|
| + if (++next_read_ == field) return;
|
| + case kEndPosition:
|
| + end_position_ = builder_->ReadPosition(); // read end position.
|
| + if (++next_read_ == field) return;
|
| + case kFlags:
|
| + flags_ = builder_->ReadFlags(); // read flags.
|
| + if (++next_read_ == field) return;
|
| + case kParentClassBinaryOffset:
|
| + parent_class_binary_offset_ =
|
| + builder_->ReadUInt(); // read parent class binary offset.
|
| + if (++next_read_ == field) return;
|
| + case kName:
|
| + builder_->SkipName(); // read name.
|
| + if (++next_read_ == field) return;
|
| + case kSourceUriIndex:
|
| + source_uri_index_ = builder_->ReadUInt(); // read source_uri_index.
|
| + if (++next_read_ == field) return;
|
| + case kAnnotations:
|
| + builder_->SkipListOfExpressions(); // read annotations.
|
| + if (++next_read_ == field) return;
|
| + case kType:
|
| + builder_->SkipDartType(); // read type.
|
| + if (++next_read_ == field) return;
|
| + case kInitializer:
|
| + if (builder_->ReadTag() == kSomething)
|
| + builder_->SkipExpression(); // read initializer.
|
| + if (++next_read_ == field) return;
|
| + case kEnd:
|
| + return;
|
| + }
|
| + }
|
| +
|
| + void SetNext(Fields field) { next_read_ = field; }
|
| + void SetJustRead(Fields field) {
|
| + next_read_ = field;
|
| + ++next_read_;
|
| + }
|
| +
|
| + bool IsConst() { return (flags_ & Field::kFlagConst) == Field::kFlagConst; }
|
| + bool IsFinal() { return (flags_ & Field::kFlagFinal) == Field::kFlagFinal; }
|
| + bool IsStatic() {
|
| + return (flags_ & Field::kFlagStatic) == Field::kFlagStatic;
|
| + }
|
| +
|
| + NameIndex canonical_name_;
|
| + TokenPosition position_;
|
| + TokenPosition end_position_;
|
| + word flags_;
|
| + intptr_t parent_class_binary_offset_;
|
| + intptr_t source_uri_index_;
|
| +
|
| + private:
|
| + StreamingFlowGraphBuilder* builder_;
|
| + intptr_t next_read_;
|
| +};
|
| +
|
| +
|
| +// Helper class that reads a kernel Procedure from binary.
|
| +//
|
| +// Use ReadUntilExcluding to read up to but not including a field.
|
| +// One can then for instance read the field from the call-site (and remember to
|
| +// call SetAt to inform this helper class), and then use this to read more.
|
| +// "Dumb" fields are stored (e.g. integers) and can be fetched from this class.
|
| +// If asked to read a "non-dumb" field (e.g. an expression) it will be skipped.
|
| +class ProcedureHelper {
|
| + public:
|
| + enum Fields {
|
| + kStart, // tag.
|
| + kCanonicalName,
|
| + kPosition,
|
| + kEndPosition,
|
| + kKind,
|
| + kFlags,
|
| + kParentClassBinaryOffset,
|
| + kName,
|
| + kSourceUriIndex,
|
| + kAnnotations,
|
| + kFunction,
|
| + kEnd
|
| + };
|
| +
|
| + explicit ProcedureHelper(StreamingFlowGraphBuilder* builder) {
|
| + builder_ = builder;
|
| + next_read_ = kStart;
|
| + }
|
| +
|
| + void ReadUntilIncluding(Fields field) {
|
| + ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1));
|
| + }
|
| +
|
| + void ReadUntilExcluding(Fields field) {
|
| + if (field <= next_read_) return;
|
| +
|
| + // Ordered with fall-through.
|
| + switch (next_read_) {
|
| + case kStart: {
|
| + Tag tag = builder_->ReadTag(); // read tag.
|
| + ASSERT(tag == kProcedure);
|
| + if (++next_read_ == field) return;
|
| + }
|
| + case kCanonicalName:
|
| + canonical_name_ =
|
| + builder_->ReadCanonicalNameReference(); // read canonical_name.
|
| + if (++next_read_ == field) return;
|
| + case kPosition:
|
| + position_ = builder_->ReadPosition(); // read position.
|
| + if (++next_read_ == field) return;
|
| + case kEndPosition:
|
| + end_position_ = builder_->ReadPosition(); // read end position.
|
| + if (++next_read_ == field) return;
|
| + case kKind:
|
| + kind_ = static_cast<Procedure::ProcedureKind>(
|
| + builder_->ReadByte()); // read kind.
|
| + if (++next_read_ == field) return;
|
| + case kFlags:
|
| + flags_ = builder_->ReadFlags(); // read flags.
|
| + if (++next_read_ == field) return;
|
| + case kParentClassBinaryOffset:
|
| + parent_class_binary_offset_ =
|
| + builder_->ReadUInt(); // read parent class binary offset.
|
| + if (++next_read_ == field) return;
|
| + case kName:
|
| + builder_->SkipName(); // read name.
|
| + if (++next_read_ == field) return;
|
| + case kSourceUriIndex:
|
| + source_uri_index_ = builder_->ReadUInt(); // read source_uri_index.
|
| + if (++next_read_ == field) return;
|
| + case kAnnotations:
|
| + builder_->SkipListOfExpressions(); // read annotations.
|
| + if (++next_read_ == field) return;
|
| + case kFunction:
|
| + if (builder_->ReadTag() == kSomething)
|
| + builder_->SkipFunctionNode(); // read function node.
|
| + if (++next_read_ == field) return;
|
| + case kEnd:
|
| + return;
|
| + }
|
| + }
|
| +
|
| + void SetNext(Fields field) { next_read_ = field; }
|
| + void SetJustRead(Fields field) {
|
| + next_read_ = field;
|
| + ++next_read_;
|
| + }
|
| +
|
| + bool IsStatic() {
|
| + return (flags_ & Procedure::kFlagStatic) == Procedure::kFlagStatic;
|
| + }
|
| + bool IsAbstract() {
|
| + return (flags_ & Procedure::kFlagAbstract) == Procedure::kFlagAbstract;
|
| + }
|
| + bool IsExternal() {
|
| + return (flags_ & Procedure::kFlagExternal) == Procedure::kFlagExternal;
|
| + }
|
| + bool IsConst() {
|
| + return (flags_ & Procedure::kFlagConst) == Procedure::kFlagConst;
|
| + }
|
| +
|
| + NameIndex canonical_name_;
|
| + TokenPosition position_;
|
| + TokenPosition end_position_;
|
| + Procedure::ProcedureKind kind_;
|
| + word flags_;
|
| + intptr_t parent_class_binary_offset_;
|
| + intptr_t source_uri_index_;
|
| +
|
| + private:
|
| + StreamingFlowGraphBuilder* builder_;
|
| + intptr_t next_read_;
|
| +};
|
| +
|
| +// Helper class that reads a kernel Constructor from binary.
|
| +//
|
| +// Use ReadUntilExcluding to read up to but not including a field.
|
| +// One can then for instance read the field from the call-site (and remember to
|
| +// call SetAt to inform this helper class), and then use this to read more.
|
| +// "Dumb" fields are stored (e.g. integers) and can be fetched from this class.
|
| +// If asked to read a "non-dumb" field (e.g. an expression) it will be skipped.
|
| +class ConstructorHelper {
|
| + public:
|
| + enum Fields {
|
| + kStart, // tag.
|
| + kCanonicalName,
|
| + kPosition,
|
| + kEndPosition,
|
| + kFlags,
|
| + kParentClassBinaryOffset,
|
| + kName,
|
| + kAnnotations,
|
| + kFunction,
|
| + kInitializers,
|
| + kEnd
|
| + };
|
| +
|
| + explicit ConstructorHelper(StreamingFlowGraphBuilder* builder) {
|
| + builder_ = builder;
|
| + next_read_ = kStart;
|
| + }
|
| +
|
| + void ReadUntilIncluding(Fields field) {
|
| + ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1));
|
| + }
|
| +
|
| + void ReadUntilExcluding(Fields field) {
|
| + if (field <= next_read_) return;
|
| +
|
| + // Ordered with fall-through.
|
| + switch (next_read_) {
|
| + case kStart: {
|
| + Tag tag = builder_->ReadTag(); // read tag.
|
| + ASSERT(tag == kConstructor);
|
| + if (++next_read_ == field) return;
|
| + }
|
| + case kCanonicalName:
|
| + canonical_name_ =
|
| + builder_->ReadCanonicalNameReference(); // read canonical_name.
|
| + if (++next_read_ == field) return;
|
| + case kPosition:
|
| + position_ = builder_->ReadPosition(); // read position.
|
| + if (++next_read_ == field) return;
|
| + case kEndPosition:
|
| + end_position_ = builder_->ReadPosition(); // read end position.
|
| + if (++next_read_ == field) return;
|
| + case kFlags:
|
| + flags_ = builder_->ReadFlags(); // read flags.
|
| + if (++next_read_ == field) return;
|
| + case kParentClassBinaryOffset:
|
| + parent_class_binary_offset_ =
|
| + builder_->ReadUInt(); // read parent class binary offset.
|
| + if (++next_read_ == field) return;
|
| + case kName:
|
| + builder_->SkipName(); // read name.
|
| + if (++next_read_ == field) return;
|
| + case kAnnotations:
|
| + builder_->SkipListOfExpressions(); // read annotations.
|
| + if (++next_read_ == field) return;
|
| + case kFunction:
|
| + builder_->SkipFunctionNode(); // read function.
|
| + if (++next_read_ == field) return;
|
| + case kInitializers: {
|
| + intptr_t list_length =
|
| + builder_->ReadListLength(); // read initializers list length.
|
| + for (intptr_t i = 0; i < list_length; i++) {
|
| + Tag tag = builder_->ReadTag();
|
| + switch (tag) {
|
| + case kInvalidInitializer:
|
| + continue;
|
| + case kFieldInitializer:
|
| + builder_->SkipCanonicalNameReference(); // read field_reference.
|
| + builder_->SkipExpression(); // read value.
|
| + continue;
|
| + case kSuperInitializer:
|
| + builder_->SkipCanonicalNameReference(); // read target_reference.
|
| + builder_->SkipArguments(); // read arguments.
|
| + continue;
|
| + case kRedirectingInitializer:
|
| + builder_->SkipCanonicalNameReference(); // read target_reference.
|
| + builder_->SkipArguments(); // read arguments.
|
| + continue;
|
| + case kLocalInitializer:
|
| + builder_->SkipVariableDeclaration(); // read variable.
|
| + continue;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + }
|
| + if (++next_read_ == field) return;
|
| + }
|
| + case kEnd:
|
| + return;
|
| + }
|
| + }
|
| +
|
| + void SetNext(Fields field) { next_read_ = field; }
|
| + void SetJustRead(Fields field) {
|
| + next_read_ = field;
|
| + ++next_read_;
|
| + }
|
| +
|
| + NameIndex canonical_name_;
|
| + TokenPosition position_;
|
| + TokenPosition end_position_;
|
| + word flags_;
|
| + intptr_t parent_class_binary_offset_;
|
| +
|
| + private:
|
| + StreamingFlowGraphBuilder* builder_;
|
| + intptr_t next_read_;
|
| +};
|
| +
|
| +// Helper class that reads a kernel Class from binary.
|
| +//
|
| +// Use ReadUntilExcluding to read up to but not including a field.
|
| +// One can then for instance read the field from the call-site (and remember to
|
| +// call SetAt to inform this helper class), and then use this to read more.
|
| +// "Dumb" fields are stored (e.g. integers) and can be fetched from this class.
|
| +// If asked to read a "non-dumb" field (e.g. an expression) it will be skipped.
|
| +class ClassHelper {
|
| + public:
|
| + enum Fields {
|
| + kStart, // tag.
|
| + kCanonicalName,
|
| + kPosition,
|
| + kIsAbstract,
|
| + kNameIndex,
|
| + kSourceUriIndex,
|
| + kAnnotations,
|
| + kTypeParameters,
|
| + kSuperClass,
|
| + kMixinType,
|
| + kImplementedClasses,
|
| + kFields,
|
| + kConstructors,
|
| + kProcedures,
|
| + kEnd
|
| + };
|
| +
|
| + explicit ClassHelper(StreamingFlowGraphBuilder* builder) {
|
| + builder_ = builder;
|
| + next_read_ = kStart;
|
| + }
|
| +
|
| + void ReadUntilIncluding(Fields field) {
|
| + ReadUntilExcluding(static_cast<Fields>(static_cast<int>(field) + 1));
|
| + }
|
| +
|
| + void ReadUntilExcluding(Fields field) {
|
| + if (field <= next_read_) return;
|
| +
|
| + // Ordered with fall-through.
|
| + switch (next_read_) {
|
| + case kStart: {
|
| + Tag tag = builder_->ReadTag(); // read tag.
|
| + ASSERT(tag == kClass);
|
| + if (++next_read_ == field) return;
|
| + }
|
| + case kCanonicalName:
|
| + canonical_name_ =
|
| + builder_->ReadCanonicalNameReference(); // read canonical_name.
|
| + if (++next_read_ == field) return;
|
| + case kPosition:
|
| + position_ = builder_->ReadPosition(); // read position.
|
| + if (++next_read_ == field) return;
|
| + case kIsAbstract:
|
| + is_abstract_ = builder_->ReadBool(); // read is_abstract.
|
| + if (++next_read_ == field) return;
|
| + case kNameIndex:
|
| + name_index_ = builder_->ReadStringReference(); // read name index.
|
| + if (++next_read_ == field) return;
|
| + case kSourceUriIndex:
|
| + source_uri_index_ = builder_->ReadUInt(); // read source_uri_index.
|
| + if (++next_read_ == field) return;
|
| + case kAnnotations:
|
| + builder_->SkipListOfExpressions(); // read annotations.
|
| + if (++next_read_ == field) return;
|
| + case kTypeParameters:
|
| + builder_->SkipTypeParametersList(); // read type parameters.
|
| + if (++next_read_ == field) return;
|
| + case kSuperClass: {
|
| + Tag type_tag = builder_->ReadTag(); // read super class type (part 1).
|
| + if (type_tag == kSomething) {
|
| + builder_->SkipDartType(); // read super class type (part 2).
|
| + }
|
| + if (++next_read_ == field) return;
|
| + }
|
| + case kMixinType: {
|
| + Tag type_tag = builder_->ReadTag(); // read mixin type (part 1).
|
| + if (type_tag == kSomething) {
|
| + builder_->SkipDartType(); // read mixin type (part 2).
|
| + }
|
| + if (++next_read_ == field) return;
|
| + }
|
| + case kImplementedClasses:
|
| + builder_->SkipListOfDartTypes(); // read implemented_classes.
|
| + if (++next_read_ == field) return;
|
| + case kFields: {
|
| + intptr_t list_length =
|
| + builder_->ReadListLength(); // read fields list length.
|
| + for (intptr_t i = 0; i < list_length; i++) {
|
| + FieldHelper field_helper(builder_);
|
| + field_helper.ReadUntilExcluding(FieldHelper::kEnd); // read field.
|
| + }
|
| + if (++next_read_ == field) return;
|
| + }
|
| + case kConstructors: {
|
| + intptr_t list_length =
|
| + builder_->ReadListLength(); // read constructors list length.
|
| + for (intptr_t i = 0; i < list_length; i++) {
|
| + ConstructorHelper constructor_helper(builder_);
|
| + constructor_helper.ReadUntilExcluding(
|
| + ConstructorHelper::kEnd); // read constructor.
|
| + }
|
| + if (++next_read_ == field) return;
|
| + }
|
| + case kProcedures: {
|
| + intptr_t list_length =
|
| + builder_->ReadListLength(); // read procedures list length.
|
| + for (intptr_t i = 0; i < list_length; i++) {
|
| + ProcedureHelper procedure_helper(builder_);
|
| + procedure_helper.ReadUntilExcluding(
|
| + ProcedureHelper::kEnd); // read procedure.
|
| + }
|
| + if (++next_read_ == field) return;
|
| + }
|
| + case kEnd:
|
| + return;
|
| + }
|
| + }
|
| +
|
| + void SetNext(Fields field) { next_read_ = field; }
|
| + void SetJustRead(Fields field) {
|
| + next_read_ = field;
|
| + ++next_read_;
|
| + }
|
| +
|
| + NameIndex canonical_name_;
|
| + TokenPosition position_;
|
| + bool is_abstract_;
|
| + StringIndex name_index_;
|
| + intptr_t source_uri_index_;
|
| +
|
| + private:
|
| + StreamingFlowGraphBuilder* builder_;
|
| + intptr_t next_read_;
|
| };
|
|
|
| // A helper class that saves the current reader position, goes to another reader
|
| @@ -651,6 +1291,8 @@ class AlternativeReadingScope {
|
|
|
| ~AlternativeReadingScope() { reader_->set_offset(saved_offset_); }
|
|
|
| + intptr_t saved_offset() { return saved_offset_; }
|
| +
|
| private:
|
| Reader* reader_;
|
| intptr_t saved_offset_;
|
|
|