Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(655)

Unified Diff: runtime/vm/kernel_binary_flowgraph.h

Issue 3001093002: Remove some "namespace" classes from C++ Kernel (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/kernel.h ('k') | runtime/vm/kernel_binary_flowgraph.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/kernel_binary_flowgraph.h
diff --git a/runtime/vm/kernel_binary_flowgraph.h b/runtime/vm/kernel_binary_flowgraph.h
index b1097865d09e3c0ed8e6be65d1aa064bec6dde24..34d06f864943f61c26486bf1541780d75f91440b 100644
--- a/runtime/vm/kernel_binary_flowgraph.h
+++ b/runtime/vm/kernel_binary_flowgraph.h
@@ -17,727 +17,402 @@
namespace dart {
namespace kernel {
-class StreamingDartTypeTranslator {
Kevin Millikin (Google) 2017/08/17 12:29:25 The ...Helper classes were just moved before this,
+// 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.
+// Simple fields are stored (e.g. integers) and can be fetched from this class.
+// If asked to read a compound field (e.g. an expression) it will be skipped.
+class FunctionNodeHelper {
public:
- StreamingDartTypeTranslator(StreamingFlowGraphBuilder* builder,
- bool finalize = false);
-
- // Can return a malformed type.
- AbstractType& BuildType();
- // Can return a malformed type.
- AbstractType& BuildTypeWithoutFinalization();
- // Is guaranteed to be not malformed.
- AbstractType& BuildVariableType();
-
- // Will return `TypeArguments::null()` in case any of the arguments are
- // malformed.
- const TypeArguments& BuildTypeArguments(intptr_t length);
+ enum Field {
+ kStart, // tag.
+ kPosition,
+ kEndPosition,
+ kAsyncMarker,
+ kDartAsyncMarker,
+ kTypeParameters,
+ kTotalParameterCount,
+ kRequiredParameterCount,
+ kPositionalParameters,
+ kNamedParameters,
+ kReturnType,
+ kBody,
+ kEnd,
+ };
- // Will return `TypeArguments::null()` in case any of the arguments are
- // malformed.
- const TypeArguments& BuildInstantiatedTypeArguments(
- const dart::Class& receiver_class,
- intptr_t length);
+ enum AsyncMarker {
+ kSync = 0,
+ kSyncStar = 1,
+ kAsync = 2,
+ kAsyncStar = 3,
+ kSyncYielding = 4,
+ };
- const Type& ReceiverType(const dart::Class& klass);
+ explicit FunctionNodeHelper(StreamingFlowGraphBuilder* builder) {
+ builder_ = builder;
+ next_read_ = kStart;
+ }
- private:
- // Can build a malformed type.
- void BuildTypeInternal();
- void BuildInterfaceType(bool simple);
- void BuildFunctionType(bool simple);
- void BuildTypeParameterType();
+ void ReadUntilIncluding(Field field) {
+ ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
+ }
- class TypeParameterScope {
- public:
- TypeParameterScope(StreamingDartTypeTranslator* translator,
- intptr_t parameter_count)
- : parameter_count_(parameter_count),
- outer_(translator->type_parameter_scope_),
- translator_(translator) {
- outer_parameter_count_ = 0;
- if (outer_ != NULL) {
- outer_parameter_count_ =
- outer_->outer_parameter_count_ + outer_->parameter_count_;
- }
- translator_->type_parameter_scope_ = this;
- }
- ~TypeParameterScope() { translator_->type_parameter_scope_ = outer_; }
+ void ReadUntilExcluding(Field field);
- TypeParameterScope* outer() const { return outer_; }
- intptr_t parameter_count() const { return parameter_count_; }
- intptr_t outer_parameter_count() const { return outer_parameter_count_; }
+ void SetNext(Field field) { next_read_ = field; }
+ void SetJustRead(Field field) { next_read_ = field + 1; }
- private:
- intptr_t parameter_count_;
- intptr_t outer_parameter_count_;
- TypeParameterScope* outer_;
- StreamingDartTypeTranslator* translator_;
- };
+ TokenPosition position_;
+ TokenPosition end_position_;
+ AsyncMarker async_marker_;
+ AsyncMarker dart_async_marker_;
+ intptr_t total_parameter_count_;
+ intptr_t required_parameter_count_;
+ private:
StreamingFlowGraphBuilder* builder_;
- TranslationHelper& translation_helper_;
- ActiveClass* active_class_;
- TypeParameterScope* type_parameter_scope_;
- Zone* zone_;
- AbstractType& result_;
- bool finalize_;
-
- friend class StreamingScopeBuilder;
- friend class KernelReader;
+ intptr_t next_read_;
};
-class StreamingScopeBuilder {
+// 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.
+// Simple fields are stored (e.g. integers) and can be fetched from this class.
+// If asked to read a compound field (e.g. an expression) it will be skipped.
+class VariableDeclarationHelper {
public:
- StreamingScopeBuilder(ParsedFunction* parsed_function,
- intptr_t relative_kernel_offset,
- const TypedData& data);
+ enum Field {
+ kPosition,
+ kEqualPosition,
+ kFlags,
+ kNameIndex,
+ kType,
+ kInitializer,
+ kEnd,
+ };
- virtual ~StreamingScopeBuilder();
+ enum Flag {
+ kFinal = 1 << 0,
+ kConst = 1 << 1,
+ };
- ScopeBuildingResult* BuildScopes();
+ explicit VariableDeclarationHelper(StreamingFlowGraphBuilder* builder) {
+ builder_ = builder;
+ next_read_ = kPosition;
+ }
- private:
- void VisitField();
+ void ReadUntilIncluding(Field field) {
+ ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
+ }
- void VisitProcedure();
+ void ReadUntilExcluding(Field field);
- void VisitConstructor();
+ void SetNext(Field field) { next_read_ = field; }
+ void SetJustRead(Field field) { next_read_ = field + 1; }
- void VisitFunctionNode();
- void VisitNode();
- void VisitInitializer();
- void VisitExpression();
- void VisitStatement();
- void VisitArguments();
- void VisitVariableDeclaration();
- void VisitDartType();
- void VisitInterfaceType(bool simple);
- void VisitFunctionType(bool simple);
- void VisitTypeParameterType();
- void VisitVectorType();
- void HandleLocalFunction(intptr_t parent_kernel_offset);
+ bool IsConst() { return (flags_ & kConst) != 0; }
+ bool IsFinal() { return (flags_ & kFinal) != 0; }
- void EnterScope(intptr_t kernel_offset);
- void ExitScope(TokenPosition start_position, TokenPosition end_position);
+ TokenPosition position_;
+ TokenPosition equals_position_;
+ word flags_;
+ StringIndex name_index_;
- /**
- * This assumes that the reader is at a FunctionNode,
- * about to read the positional parameters.
- */
- void AddPositionalAndNamedParameters(intptr_t pos = 0);
- /**
- * This assumes that the reader is at a FunctionNode,
- * about to read a parameter (i.e. VariableDeclaration).
- */
- void AddVariableDeclarationParameter(intptr_t pos);
+ private:
+ StreamingFlowGraphBuilder* builder_;
+ intptr_t next_read_;
+};
- LocalVariable* MakeVariable(TokenPosition declaration_pos,
- TokenPosition token_pos,
- const dart::String& name,
- const AbstractType& type);
+// 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.
+// Simple fields are stored (e.g. integers) and can be fetched from this class.
+// If asked to read a compound field (e.g. an expression) it will be skipped.
+class FieldHelper {
+ public:
+ enum Field {
+ kStart, // tag.
+ kCanonicalName,
+ kPosition,
+ kEndPosition,
+ kFlags,
+ kName,
+ kSourceUriIndex,
+ kDocumentationCommentIndex,
+ kAnnotations,
+ kType,
+ kInitializer,
+ kEnd,
+ };
- void AddExceptionVariable(GrowableArray<LocalVariable*>* variables,
- const char* prefix,
- intptr_t nesting_depth);
+ enum Flag {
+ kFinal = 1 << 0,
+ kConst = 1 << 1,
+ kStatic = 1 << 2,
+ };
- void AddTryVariables();
- void AddCatchVariables();
- void AddIteratorVariable();
- void AddSwitchVariable();
+ explicit FieldHelper(StreamingFlowGraphBuilder* builder)
+ : builder_(builder),
+ next_read_(kStart),
+ has_function_literal_initializer_(false) {}
- // Record an assignment or reference to a variable. If the occurrence is
- // in a nested function, ensure that the variable is handled properly as a
- // captured variable.
- void LookupVariable(intptr_t declaration_binary_offset);
+ FieldHelper(StreamingFlowGraphBuilder* builder, intptr_t offset);
- const dart::String& GenerateName(const char* prefix, intptr_t suffix);
+ void ReadUntilIncluding(Field field) {
+ ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
+ }
- void HandleSpecialLoad(LocalVariable** variable, const dart::String& symbol);
- void LookupCapturedVariableByName(LocalVariable** variable,
- const dart::String& name);
+ void ReadUntilExcluding(Field field,
+ bool detect_function_literal_initializer = false);
- struct DepthState {
- explicit DepthState(intptr_t function)
- : loop_(0),
- function_(function),
- try_(0),
- catch_(0),
- finally_(0),
- for_in_(0) {}
+ void SetNext(Field field) { next_read_ = field; }
+ void SetJustRead(Field field) { next_read_ = field + 1; }
- intptr_t loop_;
- intptr_t function_;
- intptr_t try_;
- intptr_t catch_;
- intptr_t finally_;
- intptr_t for_in_;
- };
+ bool IsConst() { return (flags_ & kConst) != 0; }
+ bool IsFinal() { return (flags_ & kFinal) != 0; }
+ bool IsStatic() { return (flags_ & kStatic) != 0; }
- ScopeBuildingResult* result_;
- ParsedFunction* parsed_function_;
- intptr_t relative_kernel_offset_;
+ bool FieldHasFunctionLiteralInitializer(TokenPosition* start,
+ TokenPosition* end) {
+ if (has_function_literal_initializer_) {
+ *start = function_literal_start_;
+ *end = function_literal_end_;
+ }
+ return has_function_literal_initializer_;
+ }
- ActiveClass active_class_;
-
- TranslationHelper translation_helper_;
- Zone* zone_;
-
- FunctionNode::AsyncMarker current_function_async_marker_;
- LocalScope* current_function_scope_;
- LocalScope* scope_;
- DepthState depth_;
-
- intptr_t name_index_;
-
- bool needs_expr_temp_;
- TokenPosition first_body_token_position_;
+ NameIndex canonical_name_;
+ TokenPosition position_;
+ TokenPosition end_position_;
+ word flags_;
+ intptr_t source_uri_index_;
+ intptr_t annotation_count_;
+ private:
StreamingFlowGraphBuilder* builder_;
- StreamingDartTypeTranslator type_translator_;
+ intptr_t next_read_;
+
+ bool has_function_literal_initializer_;
+ TokenPosition function_literal_start_;
+ TokenPosition function_literal_end_;
};
-// There are several cases when we are compiling constant expressions:
-//
-// * constant field initializers:
-// const FieldName = <expr>;
-//
-// * constant expressions:
-// const [<expr>, ...]
-// const {<expr> : <expr>, ...}
-// const Constructor(<expr>, ...)
-//
-// * constant default parameters:
-// f(a, [b = <expr>])
-// f(a, {b: <expr>})
-//
-// * constant values to compare in a [SwitchCase]
-// case <expr>:
+// Helper class that reads a kernel Procedure from binary.
//
-// In all cases `<expr>` must be recursively evaluated and canonicalized at
-// compile-time.
-class StreamingConstantEvaluator {
+// 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.
+// Simple fields are stored (e.g. integers) and can be fetched from this class.
+// If asked to read a compound field (e.g. an expression) it will be skipped.
+class ProcedureHelper {
public:
- explicit StreamingConstantEvaluator(StreamingFlowGraphBuilder* builder);
-
- virtual ~StreamingConstantEvaluator() {}
-
- Instance& EvaluateExpression(intptr_t offset, bool reset_position = true);
- Instance& EvaluateListLiteral(intptr_t offset, bool reset_position = true);
- Instance& EvaluateMapLiteral(intptr_t offset, bool reset_position = true);
- Instance& EvaluateConstructorInvocation(intptr_t offset,
- bool reset_position = true);
- Object& EvaluateExpressionSafe(intptr_t offset);
+ enum Field {
+ kStart, // tag.
+ kCanonicalName,
+ kPosition,
+ kEndPosition,
+ kKind,
+ kFlags,
+ kName,
+ kSourceUriIndex,
+ kDocumentationCommentIndex,
+ kAnnotations,
+ kFunction,
+ kEnd,
+ };
- private:
- void EvaluateVariableGet();
- void EvaluateVariableGet(uint8_t payload);
- void EvaluatePropertyGet();
- void EvaluateStaticGet();
- void EvaluateMethodInvocation();
- void EvaluateStaticInvocation();
- void EvaluateConstructorInvocationInternal();
- void EvaluateNot();
- void EvaluateLogicalExpression();
- void EvaluateConditionalExpression();
- void EvaluateStringConcatenation();
- void EvaluateSymbolLiteral();
- void EvaluateTypeLiteral();
- void EvaluateListLiteralInternal();
- void EvaluateMapLiteralInternal();
- void EvaluateLet();
- void EvaluateBigIntLiteral();
- void EvaluateStringLiteral();
- void EvaluateIntLiteral(uint8_t payload);
- void EvaluateIntLiteral(bool is_negative);
- void EvaluateDoubleLiteral();
- void EvaluateBoolLiteral(bool value);
- void EvaluateNullLiteral();
+ enum Kind {
+ kMethod,
+ kGetter,
+ kSetter,
+ kOperator,
+ kFactory,
+ };
- const Object& RunFunction(const Function& function,
- intptr_t argument_count,
- const Instance* receiver,
- const TypeArguments* type_args);
+ enum Flag {
+ kStatic = 1 << 0,
+ kAbstract = 1 << 1,
+ kExternal = 1 << 2,
+ kConst = 1 << 3, // Only for external const factories.
+ };
- const Object& RunFunction(const Function& function,
- const Array& arguments,
- const Array& names);
+ explicit ProcedureHelper(StreamingFlowGraphBuilder* builder) {
+ builder_ = builder;
+ next_read_ = kStart;
+ }
- RawObject* EvaluateConstConstructorCall(const dart::Class& type_class,
- const TypeArguments& type_arguments,
- const Function& constructor,
- const Object& argument);
+ void ReadUntilIncluding(Field field) {
+ ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
+ }
- const TypeArguments* TranslateTypeArguments(const Function& target,
- dart::Class* target_klass);
+ void ReadUntilExcluding(Field field);
- void AssertBool() {
- if (!result_.IsBool()) {
- translation_helper_.ReportError("Expected boolean expression.");
- }
- }
+ void SetNext(Field field) { next_read_ = field; }
+ void SetJustRead(Field field) { next_read_ = field + 1; }
- bool EvaluateBooleanExpressionHere();
+ bool IsStatic() { return (flags_ & kStatic) != 0; }
+ bool IsAbstract() { return (flags_ & kAbstract) != 0; }
+ bool IsExternal() { return (flags_ & kExternal) != 0; }
+ bool IsConst() { return (flags_ & kConst) != 0; }
- bool GetCachedConstant(intptr_t kernel_offset, Instance* value);
- void CacheConstantValue(intptr_t kernel_offset, const Instance& value);
+ NameIndex canonical_name_;
+ TokenPosition position_;
+ TokenPosition end_position_;
+ Kind kind_;
+ word flags_;
+ intptr_t source_uri_index_;
+ intptr_t annotation_count_;
+ private:
StreamingFlowGraphBuilder* builder_;
- Isolate* isolate_;
- Zone* zone_;
- TranslationHelper& translation_helper_;
- StreamingDartTypeTranslator& type_translator_;
-
- Script& script_;
- Instance& result_;
+ intptr_t next_read_;
};
-class FunctionNodeHelper;
-
-class StreamingFlowGraphBuilder {
+// 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.
+// Simple fields are stored (e.g. integers) and can be fetched from this class.
+// If asked to read a compound field (e.g. an expression) it will be skipped.
+class ConstructorHelper {
public:
- StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder,
- intptr_t relative_kernel_offset,
- const TypedData& data)
- : flow_graph_builder_(flow_graph_builder),
- translation_helper_(flow_graph_builder->translation_helper_),
- zone_(flow_graph_builder->zone_),
- reader_(new Reader(data)),
- constant_evaluator_(this),
- type_translator_(this, /* finalize= */ true),
- relative_kernel_offset_(relative_kernel_offset),
- current_script_id_(-1),
- record_for_script_id_(-1),
- record_token_positions_into_(NULL),
- record_yield_positions_into_(NULL) {}
-
- StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
- Zone* zone,
- const uint8_t* buffer,
- intptr_t buffer_length)
- : flow_graph_builder_(NULL),
- translation_helper_(*translation_helper),
- zone_(zone),
- reader_(new Reader(buffer, buffer_length)),
- constant_evaluator_(this),
- type_translator_(this, /* finalize= */ true),
- relative_kernel_offset_(0),
- current_script_id_(-1),
- record_for_script_id_(-1),
- record_token_positions_into_(NULL),
- record_yield_positions_into_(NULL) {}
+ enum Field {
+ kStart, // tag.
+ kCanonicalName,
+ kPosition,
+ kEndPosition,
+ kFlags,
+ kName,
+ kDocumentationCommentIndex,
+ kAnnotations,
+ kFunction,
+ kInitializers,
+ kEnd,
+ };
- StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
- Zone* zone,
- intptr_t relative_kernel_offset,
- const TypedData& data)
- : flow_graph_builder_(NULL),
- translation_helper_(*translation_helper),
- zone_(zone),
- reader_(new Reader(data)),
- constant_evaluator_(this),
- type_translator_(this, /* finalize= */ true),
- relative_kernel_offset_(relative_kernel_offset),
- current_script_id_(-1),
- record_for_script_id_(-1),
- record_token_positions_into_(NULL),
- record_yield_positions_into_(NULL) {}
+ enum Flag {
+ kConst = 1 << 0,
+ kExternal = 1 << 1,
+ };
- ~StreamingFlowGraphBuilder() { delete reader_; }
+ explicit ConstructorHelper(StreamingFlowGraphBuilder* builder) {
+ builder_ = builder;
+ next_read_ = kStart;
+ }
- FlowGraph* BuildGraph(intptr_t kernel_offset);
+ void ReadUntilIncluding(Field field) {
+ ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
+ }
- Fragment BuildStatementAt(intptr_t kernel_offset);
- RawObject* BuildParameterDescriptor(intptr_t kernel_offset);
- RawObject* EvaluateMetadata(intptr_t kernel_offset);
- void CollectTokenPositionsFor(
- intptr_t script_index,
- intptr_t initial_script_index,
- GrowableArray<intptr_t>* record_token_positions_in,
- GrowableArray<intptr_t>* record_yield_positions_in);
- intptr_t SourceTableSize();
- String& SourceTableUriFor(intptr_t index);
- String& GetSourceFor(intptr_t index);
- Array& GetLineStartsFor(intptr_t index);
+ void ReadUntilExcluding(Field field);
- private:
- void DiscoverEnclosingElements(Zone* zone,
- const Function& function,
- Function* outermost_function);
+ void SetNext(Field field) { next_read_ = field; }
+ void SetJustRead(Field field) { next_read_ = field + 1; }
- void ReadUntilFunctionNode();
- StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset,
- const Function& function);
+ bool IsExternal() { return (flags_ & kExternal) != 0; }
+ bool IsConst() { return (flags_ & kConst) != 0; }
- FlowGraph* BuildGraphOfStaticFieldInitializer();
- FlowGraph* BuildGraphOfFieldAccessor(LocalVariable* setter_value);
- void SetupDefaultParameterValues();
- Fragment BuildFieldInitializer(NameIndex canonical_name);
- Fragment BuildInitializers(const Class& parent_class);
- FlowGraph* BuildGraphOfImplicitClosureFunction(const Function& function);
- FlowGraph* BuildGraphOfConvertedClosureFunction(const Function& function);
- FlowGraph* BuildGraphOfFunction(bool constructor);
+ NameIndex canonical_name_;
+ TokenPosition position_;
+ TokenPosition end_position_;
+ word flags_;
+ intptr_t annotation_count_;
- Fragment BuildExpression(TokenPosition* position = NULL);
- Fragment BuildStatement();
+ private:
+ StreamingFlowGraphBuilder* builder_;
+ intptr_t next_read_;
+};
- intptr_t ReaderOffset();
- void SetOffset(intptr_t offset);
- void SkipBytes(intptr_t skip);
- bool ReadBool();
- uint8_t ReadByte();
- uint32_t ReadUInt();
- uint32_t PeekUInt();
- intptr_t ReadListLength();
- StringIndex ReadStringReference();
- NameIndex ReadCanonicalNameReference();
- StringIndex ReadNameAsStringIndex();
- const dart::String& ReadNameAsMethodName();
- const dart::String& ReadNameAsGetterName();
- const dart::String& ReadNameAsSetterName();
- const dart::String& ReadNameAsFieldName();
- void SkipStringReference();
- void SkipCanonicalNameReference();
- void SkipDartType();
- void SkipOptionalDartType();
- void SkipInterfaceType(bool simple);
- void SkipFunctionType(bool simple);
- void SkipListOfExpressions();
- void SkipListOfDartTypes();
- void SkipListOfStrings();
- void SkipListOfVariableDeclarations();
- void SkipTypeParametersList();
- void SkipInitializer();
- void SkipExpression();
- void SkipStatement();
- void SkipFunctionNode();
- void SkipName();
- void SkipArguments();
- void SkipVariableDeclaration();
- void SkipLibraryCombinator();
- void SkipLibraryDependency();
- void SkipLibraryPart();
- void SkipLibraryTypedef();
- TokenPosition ReadPosition(bool record = true);
- void record_token_position(TokenPosition position);
- void record_yield_position(TokenPosition position);
- Tag ReadTag(uint8_t* payload = NULL);
- Tag PeekTag(uint8_t* payload = NULL);
- word ReadFlags();
-
- void loop_depth_inc();
- void loop_depth_dec();
- intptr_t for_in_depth();
- void for_in_depth_inc();
- void for_in_depth_dec();
- void catch_depth_inc();
- void catch_depth_dec();
- void try_depth_inc();
- void try_depth_dec();
- intptr_t CurrentTryIndex();
- intptr_t AllocateTryIndex();
- LocalVariable* CurrentException();
- LocalVariable* CurrentStackTrace();
- CatchBlock* catch_block();
- ActiveClass* active_class();
- ScopeBuildingResult* scopes();
- void set_scopes(ScopeBuildingResult* scope);
- ParsedFunction* parsed_function();
- TryFinallyBlock* try_finally_block();
- SwitchBlock* switch_block();
- BreakableBlock* breakable_block();
- GrowableArray<YieldContinuation>& yield_continuations();
- Value* stack();
- void Push(Definition* definition);
- Value* Pop();
-
- Tag PeekArgumentsFirstPositionalTag();
- const TypeArguments& PeekArgumentsInstantiatedType(const dart::Class& klass);
- intptr_t PeekArgumentsCount();
- intptr_t PeekArgumentsTypeCount();
- void SkipArgumentsBeforeActualArguments();
-
- LocalVariable* LookupVariable(intptr_t kernel_offset);
- LocalVariable* MakeTemporary();
- Token::Kind MethodKind(const dart::String& name);
- dart::RawFunction* LookupMethodByMember(NameIndex target,
- const dart::String& method_name);
-
- bool NeedsDebugStepCheck(const Function& function, TokenPosition position);
- bool NeedsDebugStepCheck(Value* value, TokenPosition position);
-
- void InlineBailout(const char* reason);
- Fragment DebugStepCheck(TokenPosition position);
- Fragment LoadLocal(LocalVariable* variable);
- Fragment Return(TokenPosition position);
- Fragment PushArgument();
- Fragment EvaluateAssertion();
- Fragment RethrowException(TokenPosition position, int catch_try_index);
- Fragment ThrowNoSuchMethodError();
- Fragment Constant(const Object& value);
- Fragment IntConstant(int64_t value);
- Fragment LoadStaticField();
- Fragment StaticCall(TokenPosition position,
- const Function& target,
- intptr_t argument_count);
- Fragment StaticCall(TokenPosition position,
- const Function& target,
- intptr_t argument_count,
- const Array& argument_names,
- intptr_t type_args_len = 0);
- Fragment InstanceCall(TokenPosition position,
- const dart::String& name,
- Token::Kind kind,
- intptr_t argument_count,
- intptr_t checked_argument_count = 1);
- Fragment InstanceCall(TokenPosition position,
- const dart::String& name,
- Token::Kind kind,
- intptr_t type_args_len,
- intptr_t argument_count,
- const Array& argument_names,
- intptr_t checked_argument_count);
- Fragment ThrowException(TokenPosition position);
- Fragment BooleanNegate();
- Fragment TranslateInstantiatedTypeArguments(
- const TypeArguments& type_arguments);
- Fragment StrictCompare(Token::Kind kind, bool number_check = false);
- Fragment AllocateObject(TokenPosition position,
- const dart::Class& klass,
- intptr_t argument_count);
- Fragment AllocateObject(const dart::Class& klass,
- const Function& closure_function);
- Fragment AllocateContext(intptr_t size);
- Fragment LoadField(intptr_t offset);
- Fragment StoreLocal(TokenPosition position, LocalVariable* variable);
- Fragment StoreStaticField(TokenPosition position, const dart::Field& field);
- Fragment StoreInstanceField(TokenPosition position, intptr_t offset);
- Fragment StringInterpolate(TokenPosition position);
- Fragment StringInterpolateSingle(TokenPosition position);
- Fragment ThrowTypeError();
- Fragment LoadInstantiatorTypeArguments();
- Fragment LoadFunctionTypeArguments();
- Fragment InstantiateType(const AbstractType& type);
- Fragment CreateArray();
- Fragment StoreIndexed(intptr_t class_id);
- Fragment CheckStackOverflow();
- Fragment CloneContext();
- Fragment TranslateFinallyFinalizers(TryFinallyBlock* outer_finally,
- intptr_t target_context_depth);
- Fragment BranchIfTrue(TargetEntryInstr** then_entry,
- TargetEntryInstr** otherwise_entry,
- bool negate);
- Fragment BranchIfEqual(TargetEntryInstr** then_entry,
- TargetEntryInstr** otherwise_entry,
- bool negate);
- Fragment BranchIfNull(TargetEntryInstr** then_entry,
- TargetEntryInstr** otherwise_entry,
- bool negate = false);
- Fragment CatchBlockEntry(const Array& handler_types,
- intptr_t handler_index,
- bool needs_stacktrace);
- Fragment TryCatch(int try_handler_index);
- Fragment Drop();
- Fragment NullConstant();
- JoinEntryInstr* BuildJoinEntry();
- JoinEntryInstr* BuildJoinEntry(intptr_t try_index);
- Fragment Goto(JoinEntryInstr* destination);
- Fragment BuildImplicitClosureCreation(const Function& target);
- Fragment CheckBooleanInCheckedMode();
- Fragment CheckAssignableInCheckedMode(const dart::AbstractType& dst_type,
- const dart::String& dst_name);
- Fragment CheckVariableTypeInCheckedMode(intptr_t variable_kernel_position);
- Fragment CheckVariableTypeInCheckedMode(const AbstractType& dst_type,
- const dart::String& name_symbol);
- Fragment EnterScope(intptr_t kernel_offset, bool* new_context = NULL);
- Fragment ExitScope(intptr_t kernel_offset);
-
- Fragment TranslateCondition(bool* negate);
- const TypeArguments& BuildTypeArguments();
- Fragment BuildArguments(Array* argument_names,
- intptr_t* argument_count,
- bool skip_push_arguments = false,
- bool do_drop = false);
- Fragment BuildArgumentsFromActualArguments(Array* argument_names,
- bool skip_push_arguments = false,
- bool do_drop = false);
-
- Fragment BuildInvalidExpression(TokenPosition* position);
- Fragment BuildVariableGet(TokenPosition* position);
- Fragment BuildVariableGet(uint8_t payload, TokenPosition* position);
- Fragment BuildVariableSet(TokenPosition* position);
- Fragment BuildVariableSet(uint8_t payload, TokenPosition* position);
- Fragment BuildPropertyGet(TokenPosition* position);
- Fragment BuildPropertySet(TokenPosition* position);
- Fragment BuildDirectPropertyGet(TokenPosition* position);
- Fragment BuildDirectPropertySet(TokenPosition* position);
- Fragment BuildStaticGet(TokenPosition* position);
- Fragment BuildStaticSet(TokenPosition* position);
- Fragment BuildMethodInvocation(TokenPosition* position);
- Fragment BuildDirectMethodInvocation(TokenPosition* position);
- Fragment BuildStaticInvocation(bool is_const, TokenPosition* position);
- Fragment BuildConstructorInvocation(bool is_const, TokenPosition* position);
- Fragment BuildNot(TokenPosition* position);
- Fragment BuildLogicalExpression(TokenPosition* position);
- Fragment BuildConditionalExpression(TokenPosition* position);
- Fragment BuildStringConcatenation(TokenPosition* position);
- Fragment BuildIsExpression(TokenPosition* position);
- Fragment BuildAsExpression(TokenPosition* position);
- Fragment BuildSymbolLiteral(TokenPosition* position);
- Fragment BuildTypeLiteral(TokenPosition* position);
- Fragment BuildThisExpression(TokenPosition* position);
- Fragment BuildRethrow(TokenPosition* position);
- Fragment BuildThrow(TokenPosition* position);
- Fragment BuildListLiteral(bool is_const, TokenPosition* position);
- Fragment BuildMapLiteral(bool is_const, TokenPosition* position);
- Fragment BuildFunctionExpression();
- Fragment BuildLet(TokenPosition* position);
- Fragment BuildBigIntLiteral(TokenPosition* position);
- Fragment BuildStringLiteral(TokenPosition* position);
- Fragment BuildIntLiteral(uint8_t payload, TokenPosition* position);
- Fragment BuildIntLiteral(bool is_negative, TokenPosition* position);
- Fragment BuildDoubleLiteral(TokenPosition* position);
- Fragment BuildBoolLiteral(bool value, TokenPosition* position);
- Fragment BuildNullLiteral(TokenPosition* position);
- Fragment BuildVectorCreation(TokenPosition* position);
- Fragment BuildVectorGet(TokenPosition* position);
- Fragment BuildVectorSet(TokenPosition* position);
- Fragment BuildVectorCopy(TokenPosition* position);
- Fragment BuildClosureCreation(TokenPosition* position);
-
- Fragment BuildInvalidStatement();
- Fragment BuildExpressionStatement();
- Fragment BuildBlock();
- Fragment BuildEmptyStatement();
- Fragment BuildAssertStatement();
- Fragment BuildLabeledStatement();
- Fragment BuildBreakStatement();
- Fragment BuildWhileStatement();
- Fragment BuildDoStatement();
- Fragment BuildForStatement();
- Fragment BuildForInStatement(bool async);
- Fragment BuildSwitchStatement();
- Fragment BuildContinueSwitchStatement();
- Fragment BuildIfStatement();
- Fragment BuildReturnStatement();
- Fragment BuildTryCatch();
- Fragment BuildTryFinally();
- Fragment BuildYieldStatement();
- Fragment BuildVariableDeclaration();
- Fragment BuildFunctionDeclaration();
- Fragment BuildFunctionNode(TokenPosition parent_position,
- StringIndex name_index);
- void SetupFunctionParameters(const dart::Class& klass,
- const dart::Function& function,
- bool is_method,
- bool is_closure,
- FunctionNodeHelper* function_node_helper);
-
- FlowGraphBuilder* flow_graph_builder_;
- TranslationHelper& translation_helper_;
- Zone* zone_;
- Reader* reader_;
- StreamingConstantEvaluator constant_evaluator_;
- StreamingDartTypeTranslator type_translator_;
- intptr_t relative_kernel_offset_;
- intptr_t current_script_id_;
- intptr_t record_for_script_id_;
- GrowableArray<intptr_t>* record_token_positions_into_;
- GrowableArray<intptr_t>* record_yield_positions_into_;
-
- 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 LibraryHelper;
- friend class ConstructorHelper;
- friend class SimpleExpressionConverter;
- friend class KernelReader;
-};
-
-// A helper class that saves the current reader position, goes to another reader
-// position, and upon destruction, resets to the original reader position.
-class AlternativeReadingScope {
+// 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.
+// Simple fields are stored (e.g. integers) and can be fetched from this class.
+// If asked to read a compound field (e.g. an expression) it will be skipped.
+class ClassHelper {
public:
- AlternativeReadingScope(Reader* reader, intptr_t new_position)
- : reader_(reader),
- saved_size_(reader_->size()),
- saved_raw_buffer_(reader_->raw_buffer()),
- saved_typed_data_(reader_->typed_data()),
- saved_offset_(reader_->offset()) {
- reader_->set_offset(new_position);
+ enum Field {
+ kStart, // tag.
+ kCanonicalName,
+ kPosition,
+ kEndPosition,
+ kIsAbstract,
+ kNameIndex,
+ kSourceUriIndex,
+ kDocumentationCommentIndex,
+ kAnnotations,
+ kTypeParameters,
+ kSuperClass,
+ kMixinType,
+ kImplementedClasses,
+ kFields,
+ kConstructors,
+ kProcedures,
+ kEnd,
+ };
+
+ explicit ClassHelper(StreamingFlowGraphBuilder* builder) {
+ builder_ = builder;
+ next_read_ = kStart;
}
- AlternativeReadingScope(Reader* reader,
- const TypedData* new_typed_data,
- intptr_t new_position)
- : reader_(reader),
- saved_size_(reader_->size()),
- saved_raw_buffer_(reader_->raw_buffer()),
- saved_typed_data_(reader_->typed_data()),
- saved_offset_(reader_->offset()) {
- reader_->set_raw_buffer(NULL);
- reader_->set_typed_data(new_typed_data);
- reader_->set_size(new_typed_data->Length());
- reader_->set_offset(new_position);
+ void ReadUntilIncluding(Field field) {
+ ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
}
- explicit AlternativeReadingScope(Reader* reader)
- : reader_(reader),
- saved_size_(reader_->size()),
- saved_raw_buffer_(reader_->raw_buffer()),
- saved_typed_data_(reader_->typed_data()),
- saved_offset_(reader_->offset()) {}
+ void ReadUntilExcluding(Field field);
- ~AlternativeReadingScope() {
- reader_->set_raw_buffer(saved_raw_buffer_);
- reader_->set_typed_data(saved_typed_data_);
- reader_->set_size(saved_size_);
- reader_->set_offset(saved_offset_);
- }
+ void SetNext(Field field) { next_read_ = field; }
+ void SetJustRead(Field field) { next_read_ = field + 1; }
- intptr_t saved_offset() { return saved_offset_; }
+ NameIndex canonical_name_;
+ TokenPosition position_;
+ TokenPosition end_position_;
+ bool is_abstract_;
+ StringIndex name_index_;
+ intptr_t source_uri_index_;
+ intptr_t annotation_count_;
private:
- Reader* reader_;
- intptr_t saved_size_;
- const uint8_t* saved_raw_buffer_;
- const TypedData* saved_typed_data_;
- intptr_t saved_offset_;
+ StreamingFlowGraphBuilder* builder_;
+ intptr_t next_read_;
};
-// Helper class that reads a kernel FunctionNode from binary.
+// Helper class that reads a kernel Library 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.
// Simple fields are stored (e.g. integers) and can be fetched from this class.
// If asked to read a compound field (e.g. an expression) it will be skipped.
-class FunctionNodeHelper {
+class LibraryHelper {
public:
enum Field {
- kStart, // tag.
- kPosition,
- kEndPosition,
- kAsyncMarker,
- kDartAsyncMarker,
- kTypeParameters,
- kTotalParameterCount,
- kRequiredParameterCount,
- kPositionalParameters,
- kNamedParameters,
- kReturnType,
- kBody,
- kEnd
+ kFlags,
+ kCanonicalName,
+ kName,
+ kSourceUriIndex,
+ kAnnotations,
+ kDependencies,
+ kParts,
+ kTypedefs,
+ kClasses,
+ kToplevelField,
+ kToplevelProcedures,
+ kEnd,
};
- explicit FunctionNodeHelper(StreamingFlowGraphBuilder* builder) {
+ explicit LibraryHelper(StreamingFlowGraphBuilder* builder) {
builder_ = builder;
- next_read_ = kStart;
+ next_read_ = kFlags;
}
void ReadUntilIncluding(Field field) {
@@ -749,371 +424,704 @@ class FunctionNodeHelper {
void SetNext(Field field) { next_read_ = field; }
void SetJustRead(Field field) { next_read_ = field + 1; }
- TokenPosition position_;
- TokenPosition end_position_;
- FunctionNode::AsyncMarker async_marker_;
- FunctionNode::AsyncMarker dart_async_marker_;
- intptr_t total_parameter_count_;
- intptr_t required_parameter_count_;
+ NameIndex canonical_name_;
+ StringIndex name_index_;
+ intptr_t source_uri_index_;
+
+ private:
+ StreamingFlowGraphBuilder* builder_;
+ intptr_t next_read_;
+};
+
+class StreamingDartTypeTranslator {
+ public:
+ StreamingDartTypeTranslator(StreamingFlowGraphBuilder* builder,
+ bool finalize = false);
+
+ // Can return a malformed type.
+ AbstractType& BuildType();
+ // Can return a malformed type.
+ AbstractType& BuildTypeWithoutFinalization();
+ // Is guaranteed to be not malformed.
+ AbstractType& BuildVariableType();
+
+ // Will return `TypeArguments::null()` in case any of the arguments are
+ // malformed.
+ const TypeArguments& BuildTypeArguments(intptr_t length);
+
+ // Will return `TypeArguments::null()` in case any of the arguments are
+ // malformed.
+ const TypeArguments& BuildInstantiatedTypeArguments(
+ const dart::Class& receiver_class,
+ intptr_t length);
+
+ const Type& ReceiverType(const dart::Class& klass);
+
+ private:
+ // Can build a malformed type.
+ void BuildTypeInternal();
+ void BuildInterfaceType(bool simple);
+ void BuildFunctionType(bool simple);
+ void BuildTypeParameterType();
+
+ class TypeParameterScope {
+ public:
+ TypeParameterScope(StreamingDartTypeTranslator* translator,
+ intptr_t parameter_count)
+ : parameter_count_(parameter_count),
+ outer_(translator->type_parameter_scope_),
+ translator_(translator) {
+ outer_parameter_count_ = 0;
+ if (outer_ != NULL) {
+ outer_parameter_count_ =
+ outer_->outer_parameter_count_ + outer_->parameter_count_;
+ }
+ translator_->type_parameter_scope_ = this;
+ }
+ ~TypeParameterScope() { translator_->type_parameter_scope_ = outer_; }
+
+ TypeParameterScope* outer() const { return outer_; }
+ intptr_t parameter_count() const { return parameter_count_; }
+ intptr_t outer_parameter_count() const { return outer_parameter_count_; }
+
+ private:
+ intptr_t parameter_count_;
+ intptr_t outer_parameter_count_;
+ TypeParameterScope* outer_;
+ StreamingDartTypeTranslator* translator_;
+ };
+
+ StreamingFlowGraphBuilder* builder_;
+ TranslationHelper& translation_helper_;
+ ActiveClass* active_class_;
+ TypeParameterScope* type_parameter_scope_;
+ Zone* zone_;
+ AbstractType& result_;
+ bool finalize_;
+
+ friend class StreamingScopeBuilder;
+ friend class KernelReader;
+};
+
+class StreamingScopeBuilder {
+ public:
+ StreamingScopeBuilder(ParsedFunction* parsed_function,
+ intptr_t relative_kernel_offset,
+ const TypedData& data);
+
+ virtual ~StreamingScopeBuilder();
+
+ ScopeBuildingResult* BuildScopes();
+
+ private:
+ void VisitField();
+
+ void VisitProcedure();
+
+ void VisitConstructor();
+
+ void VisitFunctionNode();
+ void VisitNode();
+ void VisitInitializer();
+ void VisitExpression();
+ void VisitStatement();
+ void VisitArguments();
+ void VisitVariableDeclaration();
+ void VisitDartType();
+ void VisitInterfaceType(bool simple);
+ void VisitFunctionType(bool simple);
+ void VisitTypeParameterType();
+ void VisitVectorType();
+ void HandleLocalFunction(intptr_t parent_kernel_offset);
+
+ void EnterScope(intptr_t kernel_offset);
+ void ExitScope(TokenPosition start_position, TokenPosition end_position);
+
+ /**
+ * This assumes that the reader is at a FunctionNode,
+ * about to read the positional parameters.
+ */
+ void AddPositionalAndNamedParameters(intptr_t pos = 0);
+ /**
+ * This assumes that the reader is at a FunctionNode,
+ * about to read a parameter (i.e. VariableDeclaration).
+ */
+ void AddVariableDeclarationParameter(intptr_t pos);
+
+ LocalVariable* MakeVariable(TokenPosition declaration_pos,
+ TokenPosition token_pos,
+ const dart::String& name,
+ const AbstractType& type);
+
+ void AddExceptionVariable(GrowableArray<LocalVariable*>* variables,
+ const char* prefix,
+ intptr_t nesting_depth);
+
+ void AddTryVariables();
+ void AddCatchVariables();
+ void AddIteratorVariable();
+ void AddSwitchVariable();
+
+ // Record an assignment or reference to a variable. If the occurrence is
+ // in a nested function, ensure that the variable is handled properly as a
+ // captured variable.
+ void LookupVariable(intptr_t declaration_binary_offset);
+
+ const dart::String& GenerateName(const char* prefix, intptr_t suffix);
+
+ void HandleSpecialLoad(LocalVariable** variable, const dart::String& symbol);
+ void LookupCapturedVariableByName(LocalVariable** variable,
+ const dart::String& name);
- private:
- StreamingFlowGraphBuilder* builder_;
- intptr_t next_read_;
-};
+ struct DepthState {
+ explicit DepthState(intptr_t function)
+ : loop_(0),
+ function_(function),
+ try_(0),
+ catch_(0),
+ finally_(0),
+ for_in_(0) {}
-// 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.
-// Simple fields are stored (e.g. integers) and can be fetched from this class.
-// If asked to read a compound field (e.g. an expression) it will be skipped.
-class VariableDeclarationHelper {
- public:
- enum Field {
- kPosition,
- kEqualPosition,
- kFlags,
- kNameIndex,
- kType,
- kInitializer,
- kEnd
+ intptr_t loop_;
+ intptr_t function_;
+ intptr_t try_;
+ intptr_t catch_;
+ intptr_t finally_;
+ intptr_t for_in_;
};
- explicit VariableDeclarationHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
- next_read_ = kPosition;
- }
+ ScopeBuildingResult* result_;
+ ParsedFunction* parsed_function_;
+ intptr_t relative_kernel_offset_;
- void ReadUntilIncluding(Field field) {
- ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
- }
+ ActiveClass active_class_;
- void ReadUntilExcluding(Field field);
+ TranslationHelper translation_helper_;
+ Zone* zone_;
- void SetNext(Field field) { next_read_ = field; }
- void SetJustRead(Field field) { next_read_ = field + 1; }
+ FunctionNodeHelper::AsyncMarker current_function_async_marker_;
+ LocalScope* current_function_scope_;
+ LocalScope* scope_;
+ DepthState depth_;
- bool IsConst() {
- return (flags_ & VariableDeclaration::kFlagConst) ==
- VariableDeclaration::kFlagConst;
- }
- bool IsFinal() {
- return (flags_ & VariableDeclaration::kFlagFinal) ==
- VariableDeclaration::kFlagFinal;
- }
+ intptr_t name_index_;
- TokenPosition position_;
- TokenPosition equals_position_;
- word flags_;
- StringIndex name_index_;
+ bool needs_expr_temp_;
+ TokenPosition first_body_token_position_;
- private:
StreamingFlowGraphBuilder* builder_;
- intptr_t next_read_;
+ StreamingDartTypeTranslator type_translator_;
};
-// Helper class that reads a kernel Field from binary.
+// There are several cases when we are compiling constant expressions:
//
-// 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.
-// Simple fields are stored (e.g. integers) and can be fetched from this class.
-// If asked to read a compound field (e.g. an expression) it will be skipped.
-class FieldHelper {
+// * constant field initializers:
+// const FieldName = <expr>;
+//
+// * constant expressions:
+// const [<expr>, ...]
+// const {<expr> : <expr>, ...}
+// const Constructor(<expr>, ...)
+//
+// * constant default parameters:
+// f(a, [b = <expr>])
+// f(a, {b: <expr>})
+//
+// * constant values to compare in a [SwitchCase]
+// case <expr>:
+//
+// In all cases `<expr>` must be recursively evaluated and canonicalized at
+// compile-time.
+class StreamingConstantEvaluator {
public:
- enum Field {
- kStart, // tag.
- kCanonicalName,
- kPosition,
- kEndPosition,
- kFlags,
- kName,
- kSourceUriIndex,
- kDocumentationCommentIndex,
- kAnnotations,
- kType,
- kInitializer,
- kEnd
- };
+ explicit StreamingConstantEvaluator(StreamingFlowGraphBuilder* builder);
- explicit FieldHelper(StreamingFlowGraphBuilder* builder)
- : builder_(builder),
- next_read_(kStart),
- has_function_literal_initializer_(false) {}
+ virtual ~StreamingConstantEvaluator() {}
- FieldHelper(StreamingFlowGraphBuilder* builder, intptr_t offset)
- : builder_(builder),
- next_read_(kStart),
- has_function_literal_initializer_(false) {
- builder_->SetOffset(offset);
- }
+ Instance& EvaluateExpression(intptr_t offset, bool reset_position = true);
+ Instance& EvaluateListLiteral(intptr_t offset, bool reset_position = true);
+ Instance& EvaluateMapLiteral(intptr_t offset, bool reset_position = true);
+ Instance& EvaluateConstructorInvocation(intptr_t offset,
+ bool reset_position = true);
+ Object& EvaluateExpressionSafe(intptr_t offset);
- void ReadUntilIncluding(Field field) {
- ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
- }
+ private:
+ void EvaluateVariableGet();
+ void EvaluateVariableGet(uint8_t payload);
+ void EvaluatePropertyGet();
+ void EvaluateStaticGet();
+ void EvaluateMethodInvocation();
+ void EvaluateStaticInvocation();
+ void EvaluateConstructorInvocationInternal();
+ void EvaluateNot();
+ void EvaluateLogicalExpression();
+ void EvaluateConditionalExpression();
+ void EvaluateStringConcatenation();
+ void EvaluateSymbolLiteral();
+ void EvaluateTypeLiteral();
+ void EvaluateListLiteralInternal();
+ void EvaluateMapLiteralInternal();
+ void EvaluateLet();
+ void EvaluateBigIntLiteral();
+ void EvaluateStringLiteral();
+ void EvaluateIntLiteral(uint8_t payload);
+ void EvaluateIntLiteral(bool is_negative);
+ void EvaluateDoubleLiteral();
+ void EvaluateBoolLiteral(bool value);
+ void EvaluateNullLiteral();
- void ReadUntilExcluding(Field field,
- bool detect_function_literal_initializer = false);
+ const Object& RunFunction(const Function& function,
+ intptr_t argument_count,
+ const Instance* receiver,
+ const TypeArguments* type_args);
- void SetNext(Field field) { next_read_ = field; }
- void SetJustRead(Field field) { next_read_ = field + 1; }
+ const Object& RunFunction(const Function& function,
+ const Array& arguments,
+ const Array& names);
- bool IsConst() {
- return (flags_ & kernel::Field::kFlagConst) == kernel::Field::kFlagConst;
- }
- bool IsFinal() {
- return (flags_ & kernel::Field::kFlagFinal) == kernel::Field::kFlagFinal;
- }
- bool IsStatic() {
- return (flags_ & kernel::Field::kFlagStatic) == kernel::Field::kFlagStatic;
- }
+ RawObject* EvaluateConstConstructorCall(const dart::Class& type_class,
+ const TypeArguments& type_arguments,
+ const Function& constructor,
+ const Object& argument);
- bool FieldHasFunctionLiteralInitializer(TokenPosition* start,
- TokenPosition* end) {
- if (has_function_literal_initializer_) {
- *start = function_literal_start_;
- *end = function_literal_end_;
+ const TypeArguments* TranslateTypeArguments(const Function& target,
+ dart::Class* target_klass);
+
+ void AssertBool() {
+ if (!result_.IsBool()) {
+ translation_helper_.ReportError("Expected boolean expression.");
}
- return has_function_literal_initializer_;
}
- NameIndex canonical_name_;
- TokenPosition position_;
- TokenPosition end_position_;
- word flags_;
- intptr_t source_uri_index_;
- intptr_t annotation_count_;
+ bool EvaluateBooleanExpressionHere();
+
+ bool GetCachedConstant(intptr_t kernel_offset, Instance* value);
+ void CacheConstantValue(intptr_t kernel_offset, const Instance& value);
- private:
StreamingFlowGraphBuilder* builder_;
- intptr_t next_read_;
+ Isolate* isolate_;
+ Zone* zone_;
+ TranslationHelper& translation_helper_;
+ StreamingDartTypeTranslator& type_translator_;
- bool has_function_literal_initializer_;
- TokenPosition function_literal_start_;
- TokenPosition function_literal_end_;
+ Script& script_;
+ Instance& result_;
};
-// 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.
-// Simple fields are stored (e.g. integers) and can be fetched from this class.
-// If asked to read a compound field (e.g. an expression) it will be skipped.
-class ProcedureHelper {
- public:
- enum Field {
- kStart, // tag.
- kCanonicalName,
- kPosition,
- kEndPosition,
- kKind,
- kFlags,
- kName,
- kSourceUriIndex,
- kDocumentationCommentIndex,
- kAnnotations,
- kFunction,
- kEnd
- };
+class StreamingFlowGraphBuilder {
+ public:
+ StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder,
+ intptr_t relative_kernel_offset,
+ const TypedData& data)
+ : flow_graph_builder_(flow_graph_builder),
+ translation_helper_(flow_graph_builder->translation_helper_),
+ zone_(flow_graph_builder->zone_),
+ reader_(new Reader(data)),
+ constant_evaluator_(this),
+ type_translator_(this, /* finalize= */ true),
+ relative_kernel_offset_(relative_kernel_offset),
+ current_script_id_(-1),
+ record_for_script_id_(-1),
+ record_token_positions_into_(NULL),
+ record_yield_positions_into_(NULL) {}
+
+ StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
+ Zone* zone,
+ const uint8_t* buffer,
+ intptr_t buffer_length)
+ : flow_graph_builder_(NULL),
+ translation_helper_(*translation_helper),
+ zone_(zone),
+ reader_(new Reader(buffer, buffer_length)),
+ constant_evaluator_(this),
+ type_translator_(this, /* finalize= */ true),
+ relative_kernel_offset_(0),
+ current_script_id_(-1),
+ record_for_script_id_(-1),
+ record_token_positions_into_(NULL),
+ record_yield_positions_into_(NULL) {}
+
+ StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
+ Zone* zone,
+ intptr_t relative_kernel_offset,
+ const TypedData& data)
+ : flow_graph_builder_(NULL),
+ translation_helper_(*translation_helper),
+ zone_(zone),
+ reader_(new Reader(data)),
+ constant_evaluator_(this),
+ type_translator_(this, /* finalize= */ true),
+ relative_kernel_offset_(relative_kernel_offset),
+ current_script_id_(-1),
+ record_for_script_id_(-1),
+ record_token_positions_into_(NULL),
+ record_yield_positions_into_(NULL) {}
+
+ ~StreamingFlowGraphBuilder() { delete reader_; }
+
+ FlowGraph* BuildGraph(intptr_t kernel_offset);
- explicit ProcedureHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
- next_read_ = kStart;
- }
+ Fragment BuildStatementAt(intptr_t kernel_offset);
+ RawObject* BuildParameterDescriptor(intptr_t kernel_offset);
+ RawObject* EvaluateMetadata(intptr_t kernel_offset);
+ void CollectTokenPositionsFor(
+ intptr_t script_index,
+ intptr_t initial_script_index,
+ GrowableArray<intptr_t>* record_token_positions_in,
+ GrowableArray<intptr_t>* record_yield_positions_in);
+ intptr_t SourceTableSize();
+ String& SourceTableUriFor(intptr_t index);
+ String& GetSourceFor(intptr_t index);
+ Array& GetLineStartsFor(intptr_t index);
- void ReadUntilIncluding(Field field) {
- ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
- }
+ private:
+ void DiscoverEnclosingElements(Zone* zone,
+ const Function& function,
+ Function* outermost_function);
- void ReadUntilExcluding(Field field);
+ void ReadUntilFunctionNode();
+ StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset,
+ const Function& function);
- void SetNext(Field field) { next_read_ = field; }
- void SetJustRead(Field field) { next_read_ = field + 1; }
+ FlowGraph* BuildGraphOfStaticFieldInitializer();
+ FlowGraph* BuildGraphOfFieldAccessor(LocalVariable* setter_value);
+ void SetupDefaultParameterValues();
+ Fragment BuildFieldInitializer(NameIndex canonical_name);
+ Fragment BuildInitializers(const Class& parent_class);
+ FlowGraph* BuildGraphOfImplicitClosureFunction(const Function& function);
+ FlowGraph* BuildGraphOfConvertedClosureFunction(const Function& function);
+ FlowGraph* BuildGraphOfFunction(bool constructor);
- 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;
- }
+ Fragment BuildExpression(TokenPosition* position = NULL);
+ Fragment BuildStatement();
- NameIndex canonical_name_;
- TokenPosition position_;
- TokenPosition end_position_;
- Procedure::ProcedureKind kind_;
- word flags_;
- intptr_t source_uri_index_;
- intptr_t annotation_count_;
+ intptr_t ReaderOffset();
+ void SetOffset(intptr_t offset);
+ void SkipBytes(intptr_t skip);
+ bool ReadBool();
+ uint8_t ReadByte();
+ uint32_t ReadUInt();
+ uint32_t PeekUInt();
+ intptr_t ReadListLength();
+ StringIndex ReadStringReference();
+ NameIndex ReadCanonicalNameReference();
+ StringIndex ReadNameAsStringIndex();
+ const dart::String& ReadNameAsMethodName();
+ const dart::String& ReadNameAsGetterName();
+ const dart::String& ReadNameAsSetterName();
+ const dart::String& ReadNameAsFieldName();
+ void SkipStringReference();
+ void SkipCanonicalNameReference();
+ void SkipDartType();
+ void SkipOptionalDartType();
+ void SkipInterfaceType(bool simple);
+ void SkipFunctionType(bool simple);
+ void SkipListOfExpressions();
+ void SkipListOfDartTypes();
+ void SkipListOfStrings();
+ void SkipListOfVariableDeclarations();
+ void SkipTypeParametersList();
+ void SkipInitializer();
+ void SkipExpression();
+ void SkipStatement();
+ void SkipFunctionNode();
+ void SkipName();
+ void SkipArguments();
+ void SkipVariableDeclaration();
+ void SkipLibraryCombinator();
+ void SkipLibraryDependency();
+ void SkipLibraryPart();
+ void SkipLibraryTypedef();
+ TokenPosition ReadPosition(bool record = true);
+ void record_token_position(TokenPosition position);
+ void record_yield_position(TokenPosition position);
+ Tag ReadTag(uint8_t* payload = NULL);
+ Tag PeekTag(uint8_t* payload = NULL);
+ word ReadFlags();
- private:
- StreamingFlowGraphBuilder* builder_;
- intptr_t next_read_;
-};
+ void loop_depth_inc();
+ void loop_depth_dec();
+ intptr_t for_in_depth();
+ void for_in_depth_inc();
+ void for_in_depth_dec();
+ void catch_depth_inc();
+ void catch_depth_dec();
+ void try_depth_inc();
+ void try_depth_dec();
+ intptr_t CurrentTryIndex();
+ intptr_t AllocateTryIndex();
+ LocalVariable* CurrentException();
+ LocalVariable* CurrentStackTrace();
+ CatchBlock* catch_block();
+ ActiveClass* active_class();
+ ScopeBuildingResult* scopes();
+ void set_scopes(ScopeBuildingResult* scope);
+ ParsedFunction* parsed_function();
+ TryFinallyBlock* try_finally_block();
+ SwitchBlock* switch_block();
+ BreakableBlock* breakable_block();
+ GrowableArray<YieldContinuation>& yield_continuations();
+ Value* stack();
+ void Push(Definition* definition);
+ Value* Pop();
-// 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.
-// Simple fields are stored (e.g. integers) and can be fetched from this class.
-// If asked to read a compound field (e.g. an expression) it will be skipped.
-class ConstructorHelper {
- public:
- enum Field {
- kStart, // tag.
- kCanonicalName,
- kPosition,
- kEndPosition,
- kFlags,
- kName,
- kDocumentationCommentIndex,
- kAnnotations,
- kFunction,
- kInitializers,
- kEnd
- };
+ Tag PeekArgumentsFirstPositionalTag();
+ const TypeArguments& PeekArgumentsInstantiatedType(const dart::Class& klass);
+ intptr_t PeekArgumentsCount();
+ intptr_t PeekArgumentsTypeCount();
+ void SkipArgumentsBeforeActualArguments();
- explicit ConstructorHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
- next_read_ = kStart;
- }
+ LocalVariable* LookupVariable(intptr_t kernel_offset);
+ LocalVariable* MakeTemporary();
+ Token::Kind MethodKind(const dart::String& name);
+ dart::RawFunction* LookupMethodByMember(NameIndex target,
+ const dart::String& method_name);
- void ReadUntilIncluding(Field field) {
- ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
- }
+ bool NeedsDebugStepCheck(const Function& function, TokenPosition position);
+ bool NeedsDebugStepCheck(Value* value, TokenPosition position);
+
+ void InlineBailout(const char* reason);
+ Fragment DebugStepCheck(TokenPosition position);
+ Fragment LoadLocal(LocalVariable* variable);
+ Fragment Return(TokenPosition position);
+ Fragment PushArgument();
+ Fragment EvaluateAssertion();
+ Fragment RethrowException(TokenPosition position, int catch_try_index);
+ Fragment ThrowNoSuchMethodError();
+ Fragment Constant(const Object& value);
+ Fragment IntConstant(int64_t value);
+ Fragment LoadStaticField();
+ Fragment StaticCall(TokenPosition position,
+ const Function& target,
+ intptr_t argument_count);
+ Fragment StaticCall(TokenPosition position,
+ const Function& target,
+ intptr_t argument_count,
+ const Array& argument_names,
+ intptr_t type_args_len = 0);
+ Fragment InstanceCall(TokenPosition position,
+ const dart::String& name,
+ Token::Kind kind,
+ intptr_t argument_count,
+ intptr_t checked_argument_count = 1);
+ Fragment InstanceCall(TokenPosition position,
+ const dart::String& name,
+ Token::Kind kind,
+ intptr_t type_args_len,
+ intptr_t argument_count,
+ const Array& argument_names,
+ intptr_t checked_argument_count);
+ Fragment ThrowException(TokenPosition position);
+ Fragment BooleanNegate();
+ Fragment TranslateInstantiatedTypeArguments(
+ const TypeArguments& type_arguments);
+ Fragment StrictCompare(Token::Kind kind, bool number_check = false);
+ Fragment AllocateObject(TokenPosition position,
+ const dart::Class& klass,
+ intptr_t argument_count);
+ Fragment AllocateObject(const dart::Class& klass,
+ const Function& closure_function);
+ Fragment AllocateContext(intptr_t size);
+ Fragment LoadField(intptr_t offset);
+ Fragment StoreLocal(TokenPosition position, LocalVariable* variable);
+ Fragment StoreStaticField(TokenPosition position, const dart::Field& field);
+ Fragment StoreInstanceField(TokenPosition position, intptr_t offset);
+ Fragment StringInterpolate(TokenPosition position);
+ Fragment StringInterpolateSingle(TokenPosition position);
+ Fragment ThrowTypeError();
+ Fragment LoadInstantiatorTypeArguments();
+ Fragment LoadFunctionTypeArguments();
+ Fragment InstantiateType(const AbstractType& type);
+ Fragment CreateArray();
+ Fragment StoreIndexed(intptr_t class_id);
+ Fragment CheckStackOverflow();
+ Fragment CloneContext();
+ Fragment TranslateFinallyFinalizers(TryFinallyBlock* outer_finally,
+ intptr_t target_context_depth);
+ Fragment BranchIfTrue(TargetEntryInstr** then_entry,
+ TargetEntryInstr** otherwise_entry,
+ bool negate);
+ Fragment BranchIfEqual(TargetEntryInstr** then_entry,
+ TargetEntryInstr** otherwise_entry,
+ bool negate);
+ Fragment BranchIfNull(TargetEntryInstr** then_entry,
+ TargetEntryInstr** otherwise_entry,
+ bool negate = false);
+ Fragment CatchBlockEntry(const Array& handler_types,
+ intptr_t handler_index,
+ bool needs_stacktrace);
+ Fragment TryCatch(int try_handler_index);
+ Fragment Drop();
+ Fragment NullConstant();
+ JoinEntryInstr* BuildJoinEntry();
+ JoinEntryInstr* BuildJoinEntry(intptr_t try_index);
+ Fragment Goto(JoinEntryInstr* destination);
+ Fragment BuildImplicitClosureCreation(const Function& target);
+ Fragment CheckBooleanInCheckedMode();
+ Fragment CheckAssignableInCheckedMode(const dart::AbstractType& dst_type,
+ const dart::String& dst_name);
+ Fragment CheckVariableTypeInCheckedMode(intptr_t variable_kernel_position);
+ Fragment CheckVariableTypeInCheckedMode(const AbstractType& dst_type,
+ const dart::String& name_symbol);
+ Fragment EnterScope(intptr_t kernel_offset, bool* new_context = NULL);
+ Fragment ExitScope(intptr_t kernel_offset);
- void ReadUntilExcluding(Field field);
+ Fragment TranslateCondition(bool* negate);
+ const TypeArguments& BuildTypeArguments();
+ Fragment BuildArguments(Array* argument_names,
+ intptr_t* argument_count,
+ bool skip_push_arguments = false,
+ bool do_drop = false);
+ Fragment BuildArgumentsFromActualArguments(Array* argument_names,
+ bool skip_push_arguments = false,
+ bool do_drop = false);
- void SetNext(Field field) { next_read_ = field; }
- void SetJustRead(Field field) { next_read_ = field + 1; }
+ Fragment BuildInvalidExpression(TokenPosition* position);
+ Fragment BuildVariableGet(TokenPosition* position);
+ Fragment BuildVariableGet(uint8_t payload, TokenPosition* position);
+ Fragment BuildVariableSet(TokenPosition* position);
+ Fragment BuildVariableSet(uint8_t payload, TokenPosition* position);
+ Fragment BuildPropertyGet(TokenPosition* position);
+ Fragment BuildPropertySet(TokenPosition* position);
+ Fragment BuildDirectPropertyGet(TokenPosition* position);
+ Fragment BuildDirectPropertySet(TokenPosition* position);
+ Fragment BuildStaticGet(TokenPosition* position);
+ Fragment BuildStaticSet(TokenPosition* position);
+ Fragment BuildMethodInvocation(TokenPosition* position);
+ Fragment BuildDirectMethodInvocation(TokenPosition* position);
+ Fragment BuildStaticInvocation(bool is_const, TokenPosition* position);
+ Fragment BuildConstructorInvocation(bool is_const, TokenPosition* position);
+ Fragment BuildNot(TokenPosition* position);
+ Fragment BuildLogicalExpression(TokenPosition* position);
+ Fragment BuildConditionalExpression(TokenPosition* position);
+ Fragment BuildStringConcatenation(TokenPosition* position);
+ Fragment BuildIsExpression(TokenPosition* position);
+ Fragment BuildAsExpression(TokenPosition* position);
+ Fragment BuildSymbolLiteral(TokenPosition* position);
+ Fragment BuildTypeLiteral(TokenPosition* position);
+ Fragment BuildThisExpression(TokenPosition* position);
+ Fragment BuildRethrow(TokenPosition* position);
+ Fragment BuildThrow(TokenPosition* position);
+ Fragment BuildListLiteral(bool is_const, TokenPosition* position);
+ Fragment BuildMapLiteral(bool is_const, TokenPosition* position);
+ Fragment BuildFunctionExpression();
+ Fragment BuildLet(TokenPosition* position);
+ Fragment BuildBigIntLiteral(TokenPosition* position);
+ Fragment BuildStringLiteral(TokenPosition* position);
+ Fragment BuildIntLiteral(uint8_t payload, TokenPosition* position);
+ Fragment BuildIntLiteral(bool is_negative, TokenPosition* position);
+ Fragment BuildDoubleLiteral(TokenPosition* position);
+ Fragment BuildBoolLiteral(bool value, TokenPosition* position);
+ Fragment BuildNullLiteral(TokenPosition* position);
+ Fragment BuildVectorCreation(TokenPosition* position);
+ Fragment BuildVectorGet(TokenPosition* position);
+ Fragment BuildVectorSet(TokenPosition* position);
+ Fragment BuildVectorCopy(TokenPosition* position);
+ Fragment BuildClosureCreation(TokenPosition* position);
- bool IsExternal() {
- return (flags_ & Constructor::kFlagExternal) == Constructor::kFlagExternal;
- }
- bool IsConst() {
- return (flags_ & Constructor::kFlagConst) == Constructor::kFlagConst;
- }
+ Fragment BuildInvalidStatement();
+ Fragment BuildExpressionStatement();
+ Fragment BuildBlock();
+ Fragment BuildEmptyStatement();
+ Fragment BuildAssertStatement();
+ Fragment BuildLabeledStatement();
+ Fragment BuildBreakStatement();
+ Fragment BuildWhileStatement();
+ Fragment BuildDoStatement();
+ Fragment BuildForStatement();
+ Fragment BuildForInStatement(bool async);
+ Fragment BuildSwitchStatement();
+ Fragment BuildContinueSwitchStatement();
+ Fragment BuildIfStatement();
+ Fragment BuildReturnStatement();
+ Fragment BuildTryCatch();
+ Fragment BuildTryFinally();
+ Fragment BuildYieldStatement();
+ Fragment BuildVariableDeclaration();
+ Fragment BuildFunctionDeclaration();
+ Fragment BuildFunctionNode(TokenPosition parent_position,
+ StringIndex name_index);
+ void SetupFunctionParameters(const dart::Class& klass,
+ const dart::Function& function,
+ bool is_method,
+ bool is_closure,
+ FunctionNodeHelper* function_node_helper);
- NameIndex canonical_name_;
- TokenPosition position_;
- TokenPosition end_position_;
- word flags_;
- intptr_t annotation_count_;
+ FlowGraphBuilder* flow_graph_builder_;
+ TranslationHelper& translation_helper_;
+ Zone* zone_;
+ Reader* reader_;
+ StreamingConstantEvaluator constant_evaluator_;
+ StreamingDartTypeTranslator type_translator_;
+ intptr_t relative_kernel_offset_;
+ intptr_t current_script_id_;
+ intptr_t record_for_script_id_;
+ GrowableArray<intptr_t>* record_token_positions_into_;
+ GrowableArray<intptr_t>* record_yield_positions_into_;
- private:
- StreamingFlowGraphBuilder* builder_;
- intptr_t next_read_;
+ 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 LibraryHelper;
+ friend class ConstructorHelper;
+ friend class SimpleExpressionConverter;
+ friend class KernelReader;
};
-// 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.
-// Simple fields are stored (e.g. integers) and can be fetched from this class.
-// If asked to read a compound field (e.g. an expression) it will be skipped.
-class ClassHelper {
+// A helper class that saves the current reader position, goes to another reader
+// position, and upon destruction, resets to the original reader position.
+class AlternativeReadingScope {
public:
- enum Field {
- kStart, // tag.
- kCanonicalName,
- kPosition,
- kEndPosition,
- kIsAbstract,
- kNameIndex,
- kSourceUriIndex,
- kDocumentationCommentIndex,
- kAnnotations,
- kTypeParameters,
- kSuperClass,
- kMixinType,
- kImplementedClasses,
- kFields,
- kConstructors,
- kProcedures,
- kEnd
- };
-
- explicit ClassHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
- next_read_ = kStart;
+ AlternativeReadingScope(Reader* reader, intptr_t new_position)
+ : reader_(reader),
+ saved_size_(reader_->size()),
+ saved_raw_buffer_(reader_->raw_buffer()),
+ saved_typed_data_(reader_->typed_data()),
+ saved_offset_(reader_->offset()) {
+ reader_->set_offset(new_position);
}
- void ReadUntilIncluding(Field field) {
- ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
+ AlternativeReadingScope(Reader* reader,
+ const TypedData* new_typed_data,
+ intptr_t new_position)
+ : reader_(reader),
+ saved_size_(reader_->size()),
+ saved_raw_buffer_(reader_->raw_buffer()),
+ saved_typed_data_(reader_->typed_data()),
+ saved_offset_(reader_->offset()) {
+ reader_->set_raw_buffer(NULL);
+ reader_->set_typed_data(new_typed_data);
+ reader_->set_size(new_typed_data->Length());
+ reader_->set_offset(new_position);
}
- void ReadUntilExcluding(Field field);
-
- void SetNext(Field field) { next_read_ = field; }
- void SetJustRead(Field field) { next_read_ = field + 1; }
-
- NameIndex canonical_name_;
- TokenPosition position_;
- TokenPosition end_position_;
- bool is_abstract_;
- StringIndex name_index_;
- intptr_t source_uri_index_;
- intptr_t annotation_count_;
-
- private:
- StreamingFlowGraphBuilder* builder_;
- intptr_t next_read_;
-};
-
-// Helper class that reads a kernel Library 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.
-// Simple fields are stored (e.g. integers) and can be fetched from this class.
-// If asked to read a compound field (e.g. an expression) it will be skipped.
-class LibraryHelper {
- public:
- enum Field {
- kFlags,
- kCanonicalName,
- kName,
- kSourceUriIndex,
- kAnnotations,
- kDependencies,
- kParts,
- kTypedefs,
- kClasses,
- kToplevelField,
- kToplevelProcedures,
- kEnd
- };
-
- explicit LibraryHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
- next_read_ = kFlags;
- }
+ explicit AlternativeReadingScope(Reader* reader)
+ : reader_(reader),
+ saved_size_(reader_->size()),
+ saved_raw_buffer_(reader_->raw_buffer()),
+ saved_typed_data_(reader_->typed_data()),
+ saved_offset_(reader_->offset()) {}
- void ReadUntilIncluding(Field field) {
- ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
+ ~AlternativeReadingScope() {
+ reader_->set_raw_buffer(saved_raw_buffer_);
+ reader_->set_typed_data(saved_typed_data_);
+ reader_->set_size(saved_size_);
+ reader_->set_offset(saved_offset_);
}
- void ReadUntilExcluding(Field field);
-
- void SetNext(Field field) { next_read_ = field; }
- void SetJustRead(Field field) { next_read_ = field + 1; }
-
- NameIndex canonical_name_;
- StringIndex name_index_;
- intptr_t source_uri_index_;
+ intptr_t saved_offset() { return saved_offset_; }
private:
- StreamingFlowGraphBuilder* builder_;
- intptr_t next_read_;
+ Reader* reader_;
+ intptr_t saved_size_;
+ const uint8_t* saved_raw_buffer_;
+ const TypedData* saved_typed_data_;
+ intptr_t saved_offset_;
};
} // namespace kernel
« no previous file with comments | « runtime/vm/kernel.h ('k') | runtime/vm/kernel_binary_flowgraph.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698