Index: runtime/vm/kernel_binary_flowgraph.h |
diff --git a/runtime/vm/kernel_binary_flowgraph.h b/runtime/vm/kernel_binary_flowgraph.h |
index 124987afdf1607f448d698e61407083c110f3db1..3e741db6a38e91504abca280eeca4794f12c1e6b 100644 |
--- a/runtime/vm/kernel_binary_flowgraph.h |
+++ b/runtime/vm/kernel_binary_flowgraph.h |
@@ -17,27 +17,132 @@ |
namespace dart { |
namespace kernel { |
+class StreamingDartTypeTranslator { |
+ public: |
+ StreamingDartTypeTranslator(StreamingFlowGraphBuilder* builder, |
+ bool finalize = false); |
+ |
+ // 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 build a malformed type. |
+ void BuildTypeInternal(); |
+ void BuildInterfaceType(bool simple); |
+ void BuildFunctionType(bool simple); |
+ 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, |
- Zone* zone, |
- TranslationHelper* h, |
- DartTypeTranslator* type_translator); |
+ explicit StreamingConstantEvaluator(StreamingFlowGraphBuilder* builder); |
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 +150,7 @@ class StreamingConstantEvaluator { |
Isolate* isolate_; |
Zone* zone_; |
TranslationHelper& translation_helper_; |
- // DartTypeTranslator& type_translator_; |
+ StreamingDartTypeTranslator& type_translator_; |
Script& script_; |
Instance& result_; |
@@ -61,32 +166,91 @@ class StreamingFlowGraphBuilder { |
translation_helper_(flow_graph_builder->translation_helper_), |
zone_(flow_graph_builder->zone_), |
reader_(new Reader(buffer, buffer_length)), |
- constant_evaluator_(this, |
- flow_graph_builder->zone_, |
- &flow_graph_builder->translation_helper_, |
- &flow_graph_builder->type_translator_) {} |
- |
- virtual ~StreamingFlowGraphBuilder() {} |
+ constant_evaluator_(this), |
+ type_translator_(this, /* finalize= */ true) {} |
- Fragment BuildAt(intptr_t kernel_offset); |
+ Fragment BuildExpressionAt(intptr_t kernel_offset); |
+ Fragment BuildStatementAt(intptr_t kernel_offset); |
private: |
+ Fragment BuildExpression(TokenPosition* position = NULL); |
+ Fragment BuildStatement(); |
+ |
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(); |
+ void SkipStringReference(); |
+ void SkipCanonicalNameReference(); |
+ 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(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); |
@@ -95,27 +259,145 @@ 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(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 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 BuildInvalidExpression(); |
- Fragment BuildStaticGet(); |
- Fragment BuildSymbolLiteral(); |
- Fragment BuildThisExpression(); |
- Fragment BuildRethrow(); |
- Fragment BuildBigIntLiteral(); |
- Fragment BuildStringLiteral(); |
- Fragment BuildIntLiteral(uint8_t payload); |
- Fragment BuildIntLiteral(bool is_negative); |
- Fragment BuildDoubleLiteral(); |
- 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_; |
Reader* reader_; |
StreamingConstantEvaluator constant_evaluator_; |
+ StreamingDartTypeTranslator type_translator_; |
friend class StreamingConstantEvaluator; |
+ friend class StreamingDartTypeTranslator; |
}; |