Chromium Code Reviews| Index: runtime/vm/kernel_binary_flowgraph.h |
| diff --git a/runtime/vm/kernel_binary_flowgraph.h b/runtime/vm/kernel_binary_flowgraph.h |
| index d2ce8474055bfe7d57878bc4399a205f463ebdf8..fc18e33ae459aa1f085408e56cb1594ba1e433c1 100644 |
| --- a/runtime/vm/kernel_binary_flowgraph.h |
| +++ b/runtime/vm/kernel_binary_flowgraph.h |
| @@ -17,27 +17,155 @@ |
| namespace dart { |
| namespace kernel { |
| +enum LogicalOperator { kAnd, kOr }; |
|
Kevin Millikin (Google)
2017/05/11 10:38:36
You should be able to use LogicalExpression::Opera
jensj
2017/05/11 12:59:25
Done.
|
| +enum VariableDeclarationFlags { |
|
Kevin Millikin (Google)
2017/05/11 10:38:36
Similarly use VariableDeclaration::Flags instead.
jensj
2017/05/11 12:59:25
Done.
|
| + kFlagFinal = 1 << 0, |
| + kFlagConst = 1 << 1, |
| +}; |
| +enum YieldFlags { |
|
Kevin Millikin (Google)
2017/05/11 10:38:36
Similarly use YieldStatement::Flags instead.
jensj
2017/05/11 12:59:25
Done.
|
| + kFlagYieldStar = 1 << 0, |
| + kFlagNative = 1 << 1, |
| +}; |
| + |
| +class StreamingDartTypeTranslator { |
| + public: |
| + StreamingDartTypeTranslator(StreamingFlowGraphBuilder* builder, |
|
Kevin Millikin (Google)
2017/05/11 10:38:36
Unless we actually want to support the behavior of
jensj
2017/05/11 12:59:25
Done.
|
| + TranslationHelper* helper, |
| + ActiveClass* active_class, |
| + bool finalize = false) |
| + : builder_(builder), |
| + translation_helper_(*helper), |
| + active_class_(active_class), |
| + type_parameter_scope_(NULL), |
| + zone_(helper->zone()), |
| + result_(AbstractType::Handle(helper->zone())), |
| + finalize_(finalize) {} |
| + |
| + // Can return a malformed type. |
| + AbstractType& BuildType(); |
| + // 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 return a malformed type. |
|
Kevin Millikin (Google)
2017/05/11 10:38:36
Technically, it can't return anything.
jensj
2017/05/11 12:59:25
Done.
|
| + void BuildTypeInternal(); |
| + void BuildInterfaceType(bool simple); |
| + void BuildFunctionType(); |
| + void BuildSimpleFunctionType(); |
| + void BuildTypeParameterType(); |
| + |
| + class TypeParameterScope { |
| + public: |
| + TypeParameterScope(StreamingDartTypeTranslator* translator, |
| + intptr_t* parameters, |
| + intptr_t parameters_count) |
| + : parameters_(parameters), |
| + parameters_count_(parameters_count), |
| + outer_(translator->type_parameter_scope_), |
| + translator_(translator) { |
| + translator_->type_parameter_scope_ = this; |
| + } |
| + ~TypeParameterScope() { |
| + delete[] parameters_; |
| + translator_->type_parameter_scope_ = outer_; |
| + } |
| + |
| + TypeParameterScope* outer() const { return outer_; } |
| + intptr_t* parameters() const { return parameters_; } |
| + intptr_t parameters_count() const { return parameters_count_; } |
| + |
| + private: |
| + intptr_t* parameters_; |
| + intptr_t parameters_count_; |
| + TypeParameterScope* outer_; |
| + StreamingDartTypeTranslator* translator_; |
| + }; |
| + |
| + StreamingFlowGraphBuilder* builder_; |
| + TranslationHelper& translation_helper_; |
| + ActiveClass* active_class_; |
| + TypeParameterScope* type_parameter_scope_; |
| + Zone* zone_; |
| + AbstractType& result_; |
| + bool finalize_; |
| +}; |
| + |
| + |
| class StreamingConstantEvaluator { |
| public: |
| StreamingConstantEvaluator(StreamingFlowGraphBuilder* builder, |
|
Kevin Millikin (Google)
2017/05/11 10:38:36
Same here, don't pass the zone, TranslationHelper,
jensj
2017/05/11 12:59:25
Done.
|
| Zone* zone, |
| - TranslationHelper* h, |
| - DartTypeTranslator* type_translator); |
| + TranslationHelper* helper, |
| + StreamingDartTypeTranslator* type_translator); |
| virtual ~StreamingConstantEvaluator() {} |
| - Instance& EvaluateExpression(); |
| + 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); |
| + 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(); |
| + |
| + const Object& RunFunction(const Function& function, |
| + intptr_t argument_count, |
| + const Instance* receiver, |
| + const TypeArguments* type_args); |
| + |
| + const Object& RunFunction(const Function& function, |
| + const Array& arguments, |
| + const Array& names); |
| - private: |
| RawObject* EvaluateConstConstructorCall(const dart::Class& type_class, |
| const TypeArguments& type_arguments, |
| const Function& constructor, |
| const Object& argument); |
| + const TypeArguments* TranslateTypeArguments(const Function& target, |
| + dart::Class* target_klass); |
| + |
| + void AssertBoolInCheckedMode() { |
| + if (isolate_->type_checks() && !result_.IsBool()) { |
| + translation_helper_.ReportError("Expected boolean expression."); |
| + } |
| + } |
| + |
| + bool EvaluateBooleanExpressionHere(); |
| + |
| bool GetCachedConstant(intptr_t kernel_offset, Instance* value); |
| void CacheConstantValue(intptr_t kernel_offset, const Instance& value); |
| @@ -45,7 +173,7 @@ class StreamingConstantEvaluator { |
| Isolate* isolate_; |
| Zone* zone_; |
| TranslationHelper& translation_helper_; |
| - // DartTypeTranslator& type_translator_; |
| + StreamingDartTypeTranslator& type_translator_; |
| Script& script_; |
| Instance& result_; |
| @@ -62,13 +190,18 @@ class StreamingFlowGraphBuilder { |
| zone_(flow_graph_builder->zone_), |
| reader_(new kernel::Reader(buffer, buffer_length)), |
| constant_evaluator_(this, |
| - flow_graph_builder->zone_, |
| - &flow_graph_builder->translation_helper_, |
| - &flow_graph_builder->type_translator_), |
| + zone_, |
| + &translation_helper_, |
| + &type_translator_), |
| + type_translator_(this, |
| + &translation_helper_, |
| + &flow_graph_builder->active_class_, |
| + /* finalize= */ true), |
| canonical_names_(NULL), |
| canonical_names_size_(-1), |
| canonical_names_entries_read_(0), |
| - canonical_names_next_offset_(-1) {} |
| + canonical_names_next_offset_(-1), |
| + direct_descendant_position_(TokenPosition::kLast) {} |
| virtual ~StreamingFlowGraphBuilder() { |
| delete reader_; |
| @@ -76,26 +209,88 @@ class StreamingFlowGraphBuilder { |
| delete[] canonical_names_; |
| } |
| - Fragment BuildAt(intptr_t kernel_offset); |
| + Fragment BuildExpressionAt(intptr_t kernel_offset); |
| + Fragment BuildExpression(); |
| + Fragment BuildStatementAt(intptr_t kernel_offset); |
| + Fragment BuildStatement(); |
| private: |
| CanonicalName* GetCanonicalName(intptr_t index); |
| + intptr_t ReadNameAsStringIndex(); |
| + const dart::String& ReadNameAsMethodName(); |
| + const dart::String& ReadNameAsGetterName(); |
| + const dart::String& ReadNameAsSetterName(); |
| + |
| + void UpdateDirectDescendantPosition(TokenPosition position); |
| + void ResetDirectDescendantPosition(); |
| 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(); |
| + void SkipDartType(); |
| + void SkipOptionalDartType(); |
| + void SkipInterfaceType(bool simple); |
| + void SkipFunctionType(bool simple); |
| + void SkipExpression(); |
| + void SkipStatement(); |
| + void SkipName(); |
| + void SkipArguments(); |
| + void SkipVariableDeclaration(); |
| TokenPosition ReadPosition(bool record = true); |
| 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(); |
| ParsedFunction* parsed_function(); |
| + TryFinallyBlock* try_finally_block(); |
| + SwitchBlock* switch_block(); |
| + BreakableBlock* breakable_block(); |
| + GrowableArray<YieldContinuation>& yield_continuations(); |
| + Value* stack(); |
| + 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(CanonicalName* 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); |
| @@ -104,12 +299,108 @@ class StreamingFlowGraphBuilder { |
| 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); |
| + Fragment InstanceCall(TokenPosition position, |
| + const dart::String& name, |
| + Token::Kind kind, |
| + intptr_t argument_count, |
| + intptr_t num_args_checked = 1); |
| + Fragment InstanceCall(TokenPosition position, |
| + const dart::String& name, |
| + Token::Kind kind, |
| + intptr_t argument_count, |
| + const Array& argument_names, |
| + intptr_t num_args_checked); |
| + Fragment ThrowException(TokenPosition position); |
| + Fragment BooleanNegate(); |
| + Fragment TranslateInstantiatedTypeArguments( |
| + const TypeArguments& type_arguments); |
| + Fragment StrictCompare(Token::Kind kind, bool number_check = false); |
| + Fragment AllocateObject(const dart::Class& klass, intptr_t argument_count); |
| + Fragment StoreLocal(TokenPosition position, LocalVariable* variable); |
| + Fragment StoreStaticField(TokenPosition position, const dart::Field& field); |
| + 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(); |
| + Fragment BuildVariableGet(); |
| + Fragment BuildVariableGet(uint8_t payload); |
| + Fragment BuildVariableSet(); |
| + Fragment BuildVariableSet(uint8_t payload); |
| + Fragment BuildPropertyGet(); |
| + Fragment BuildPropertySet(); |
| + Fragment BuildDirectPropertyGet(); |
| + Fragment BuildDirectPropertySet(); |
| Fragment BuildStaticGet(); |
| + Fragment BuildStaticSet(); |
| + Fragment BuildMethodInvocation(); |
| + Fragment BuildDirectMethodInvocation(); |
| + Fragment BuildStaticInvocation(bool is_const); |
| + Fragment BuildConstructorInvocation(bool is_const); |
| + Fragment BuildNot(); |
| + Fragment BuildLogicalExpression(); |
| + Fragment BuildConditionalExpression(); |
| + Fragment BuildStringConcatenation(); |
| + Fragment BuildIsExpression(); |
| + Fragment BuildAsExpression(); |
| Fragment BuildSymbolLiteral(); |
| + Fragment BuildTypeLiteral(); |
| Fragment BuildThisExpression(); |
| Fragment BuildRethrow(); |
| + Fragment BuildThrow(); |
| + Fragment BuildListLiteral(bool is_const); |
| + Fragment BuildMapLiteral(bool is_const); |
| + Fragment BuildLet(); |
| Fragment BuildBigIntLiteral(); |
| Fragment BuildStringLiteral(); |
| Fragment BuildIntLiteral(uint8_t payload); |
| @@ -118,18 +409,44 @@ class StreamingFlowGraphBuilder { |
| Fragment BuildBoolLiteral(bool value); |
| Fragment BuildNullLiteral(); |
| + 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(bool has_tag); |
| + |
| FlowGraphBuilder* flow_graph_builder_; |
| TranslationHelper& translation_helper_; |
| Zone* zone_; |
| kernel::Reader* reader_; |
| StreamingConstantEvaluator constant_evaluator_; |
| + StreamingDartTypeTranslator type_translator_; |
| CanonicalName** canonical_names_; |
| intptr_t canonical_names_size_; |
| intptr_t canonical_names_entries_read_; |
| intptr_t canonical_names_next_offset_; |
| + // Keep track of direct-descendant Expressions token position. |
| + // Note: This is set to TokenPosition::kLast to indicate 'not set'. |
| + TokenPosition direct_descendant_position_; |
| + |
| friend class StreamingConstantEvaluator; |
| + friend class StreamingDartTypeTranslator; |
| }; |