Index: runtime/vm/kernel_to_il.h |
diff --git a/runtime/vm/kernel_to_il.h b/runtime/vm/kernel_to_il.h |
index 959197744ac81bf629441c604af5ff272aac5596..038e0e1b0e706f8ce550e003543d814217912dea 100644 |
--- a/runtime/vm/kernel_to_il.h |
+++ b/runtime/vm/kernel_to_il.h |
@@ -13,6 +13,7 @@ |
#include "vm/flow_graph.h" |
#include "vm/flow_graph_builder.h" |
#include "vm/intermediate_language.h" |
+#include "vm/kernel.h" |
namespace dart { |
namespace kernel { |
@@ -550,6 +551,115 @@ class DartTypeTranslator : public DartTypeVisitor { |
}; |
+// 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>: |
+// |
+// In all cases `<expr>` must be recursively evaluated and canonicalized at |
+// compile-time. |
+class ConstantEvaluator : public ExpressionVisitor { |
+ public: |
+ ConstantEvaluator(FlowGraphBuilder* builder, |
+ Zone* zone, |
+ TranslationHelper* h, |
+ DartTypeTranslator* type_translator); |
+ virtual ~ConstantEvaluator() {} |
+ |
+ Instance& EvaluateExpression(Expression* node); |
+ Object& EvaluateExpressionSafe(Expression* node); |
+ Instance& EvaluateConstructorInvocation(ConstructorInvocation* node); |
+ Instance& EvaluateListLiteral(ListLiteral* node); |
+ Instance& EvaluateMapLiteral(MapLiteral* node); |
+ |
+ virtual void VisitDefaultExpression(Expression* node) { UNREACHABLE(); } |
+ |
+ virtual void VisitBigintLiteral(BigintLiteral* node); |
+ virtual void VisitBoolLiteral(BoolLiteral* node); |
+ virtual void VisitDoubleLiteral(DoubleLiteral* node); |
+ virtual void VisitIntLiteral(IntLiteral* node); |
+ virtual void VisitNullLiteral(NullLiteral* node); |
+ virtual void VisitStringLiteral(StringLiteral* node); |
+ virtual void VisitSymbolLiteral(SymbolLiteral* node); |
+ virtual void VisitTypeLiteral(TypeLiteral* node); |
+ |
+ virtual void VisitListLiteral(ListLiteral* node); |
+ virtual void VisitMapLiteral(MapLiteral* node); |
+ |
+ virtual void VisitConstructorInvocation(ConstructorInvocation* node); |
+ virtual void VisitMethodInvocation(MethodInvocation* node); |
+ virtual void VisitStaticGet(StaticGet* node); |
+ virtual void VisitVariableGet(VariableGet* node); |
+ virtual void VisitLet(Let* node); |
+ virtual void VisitStaticInvocation(StaticInvocation* node); |
+ virtual void VisitStringConcatenation(StringConcatenation* node); |
+ virtual void VisitConditionalExpression(ConditionalExpression* node); |
+ virtual void VisitLogicalExpression(LogicalExpression* node); |
+ virtual void VisitNot(Not* node); |
+ virtual void VisitPropertyGet(PropertyGet* node); |
+ |
+ private: |
+ // This will translate type arguments form [kernel_arguments]. If no type |
+ // arguments are passed and the [target] is a factory then the null type |
+ // argument array will be returned. |
+ // |
+ // If none of these cases apply, NULL will be returned. |
+ const TypeArguments* TranslateTypeArguments(const Function& target, |
+ dart::Class* target_klass, |
+ Arguments* kernel_arguments); |
+ |
+ const Object& RunFunction(const Function& function, |
+ Arguments* arguments, |
+ const Instance* receiver = NULL, |
+ const TypeArguments* type_args = NULL); |
+ |
+ const Object& RunFunction(const Function& function, |
+ const Array& arguments, |
+ const Array& names); |
+ |
+ RawObject* EvaluateConstConstructorCall(const dart::Class& type_class, |
+ const TypeArguments& type_arguments, |
+ const Function& constructor, |
+ const Object& argument); |
+ |
+ void AssertBoolInCheckedMode() { |
+ if (isolate_->type_checks() && !result_.IsBool()) { |
+ translation_helper_.ReportError("Expected boolean expression."); |
+ } |
+ } |
+ |
+ bool EvaluateBooleanExpression(Expression* expression) { |
+ EvaluateExpression(expression); |
+ AssertBoolInCheckedMode(); |
+ return result_.raw() == Bool::True().raw(); |
+ } |
+ |
+ bool GetCachedConstant(TreeNode* node, Instance* value); |
+ void CacheConstantValue(TreeNode* node, const Instance& value); |
+ |
+ FlowGraphBuilder* builder_; |
+ Isolate* isolate_; |
+ Zone* zone_; |
+ TranslationHelper& translation_helper_; |
+ DartTypeTranslator& type_translator_; |
+ |
+ Script& script_; |
+ Instance& result_; |
+}; |
+ |
+ |
struct FunctionScope { |
intptr_t kernel_offset; |
LocalScope* scope; |
@@ -618,9 +728,9 @@ struct YieldContinuation { |
: entry(NULL), try_index(CatchClauseNode::kInvalidTryIndex) {} |
}; |
-class FlowGraphBuilder { |
+class FlowGraphBuilder : public ExpressionVisitor, public StatementVisitor { |
public: |
- FlowGraphBuilder(intptr_t kernel_offset, |
+ FlowGraphBuilder(TreeNode* node, |
ParsedFunction* parsed_function, |
const ZoneGrowableArray<const ICData*>& ic_data_array, |
ZoneGrowableArray<intptr_t>* context_level_array, |
@@ -631,24 +741,106 @@ class FlowGraphBuilder { |
FlowGraph* BuildGraph(); |
+ virtual void VisitDefaultExpression(Expression* node) { UNREACHABLE(); } |
+ virtual void VisitDefaultStatement(Statement* node) { UNREACHABLE(); } |
+ |
+ virtual void VisitInvalidExpression(InvalidExpression* node); |
+ virtual void VisitNullLiteral(NullLiteral* node); |
+ virtual void VisitBoolLiteral(BoolLiteral* node); |
+ virtual void VisitIntLiteral(IntLiteral* node); |
+ virtual void VisitBigintLiteral(BigintLiteral* node); |
+ virtual void VisitDoubleLiteral(DoubleLiteral* node); |
+ virtual void VisitStringLiteral(StringLiteral* node); |
+ virtual void VisitSymbolLiteral(SymbolLiteral* node); |
+ virtual void VisitTypeLiteral(TypeLiteral* node); |
+ virtual void VisitVariableGet(VariableGet* node); |
+ virtual void VisitVariableSet(VariableSet* node); |
+ virtual void VisitStaticGet(StaticGet* node); |
+ virtual void VisitStaticSet(StaticSet* node); |
+ virtual void VisitPropertyGet(PropertyGet* node); |
+ virtual void VisitPropertySet(PropertySet* node); |
+ virtual void VisitDirectPropertyGet(DirectPropertyGet* node); |
+ virtual void VisitDirectPropertySet(DirectPropertySet* node); |
+ virtual void VisitStaticInvocation(StaticInvocation* node); |
+ virtual void VisitMethodInvocation(MethodInvocation* node); |
+ virtual void VisitDirectMethodInvocation(DirectMethodInvocation* node); |
+ virtual void VisitConstructorInvocation(ConstructorInvocation* node); |
+ virtual void VisitIsExpression(IsExpression* node); |
+ virtual void VisitAsExpression(AsExpression* node); |
+ virtual void VisitConditionalExpression(ConditionalExpression* node); |
+ virtual void VisitLogicalExpression(LogicalExpression* node); |
+ virtual void VisitNot(Not* node); |
+ virtual void VisitThisExpression(ThisExpression* node); |
+ virtual void VisitStringConcatenation(StringConcatenation* node); |
+ virtual void VisitListLiteral(ListLiteral* node); |
+ virtual void VisitMapLiteral(MapLiteral* node); |
+ virtual void VisitFunctionExpression(FunctionExpression* node); |
+ virtual void VisitLet(Let* node); |
+ virtual void VisitThrow(Throw* node); |
+ virtual void VisitRethrow(Rethrow* node); |
+ |
+ virtual void VisitInvalidStatement(InvalidStatement* node); |
+ virtual void VisitEmptyStatement(EmptyStatement* node); |
+ virtual void VisitBlock(Block* node); |
+ virtual void VisitReturnStatement(ReturnStatement* node); |
+ virtual void VisitExpressionStatement(ExpressionStatement* node); |
+ virtual void VisitVariableDeclaration(VariableDeclaration* node); |
+ virtual void VisitFunctionDeclaration(FunctionDeclaration* node); |
+ virtual void VisitIfStatement(IfStatement* node); |
+ virtual void VisitWhileStatement(WhileStatement* node); |
+ virtual void VisitDoStatement(DoStatement* node); |
+ virtual void VisitForStatement(ForStatement* node); |
+ virtual void VisitForInStatement(ForInStatement* node); |
+ virtual void VisitLabeledStatement(LabeledStatement* node); |
+ virtual void VisitBreakStatement(BreakStatement* node); |
+ virtual void VisitSwitchStatement(SwitchStatement* node); |
+ virtual void VisitContinueSwitchStatement(ContinueSwitchStatement* node); |
+ virtual void VisitAssertStatement(AssertStatement* node); |
+ virtual void VisitTryFinally(TryFinally* node); |
+ virtual void VisitTryCatch(TryCatch* node); |
+ virtual void VisitYieldStatement(YieldStatement* node); |
+ |
private: |
+ FlowGraph* BuildGraphOfFunction(FunctionNode* node, |
+ Constructor* constructor = NULL); |
+ FlowGraph* BuildGraphOfFieldAccessor(Field* node, |
+ LocalVariable* setter_value); |
+ FlowGraph* BuildGraphOfStaticFieldInitializer(Field* node); |
FlowGraph* BuildGraphOfMethodExtractor(const Function& method); |
+ FlowGraph* BuildGraphOfImplicitClosureFunction(FunctionNode* kernel_function, |
+ const Function& function); |
FlowGraph* BuildGraphOfNoSuchMethodDispatcher(const Function& function); |
FlowGraph* BuildGraphOfInvokeFieldDispatcher(const Function& function); |
- Fragment NativeFunctionBody(intptr_t first_positional_offset, |
+ Fragment NativeFunctionBody(FunctionNode* kernel_function, |
const Function& function); |
+ void SetupDefaultParameterValues(FunctionNode* function); |
+ |
TargetEntryInstr* BuildTargetEntry(); |
JoinEntryInstr* BuildJoinEntry(); |
JoinEntryInstr* BuildJoinEntry(intptr_t try_index); |
+ Fragment TranslateArguments(Arguments* node, Array* argument_names); |
ArgumentArray GetArguments(int count); |
+ Fragment TranslateInitializers(Class* kernel_class, |
+ List<Initializer>* initialiers); |
+ Fragment TranslateFieldInitializer(NameIndex canonical_name, |
+ Expression* init); |
+ |
+ Fragment TranslateStatement(Statement* statement); |
+ Fragment TranslateCondition(Expression* expression, bool* negate); |
+ Fragment TranslateExpression(Expression* expression); |
+ |
Fragment TranslateFinallyFinalizers(TryFinallyBlock* outer_finally, |
intptr_t target_context_depth); |
+ Fragment TranslateFunctionNode(FunctionNode* node, TreeNode* parent); |
+ |
+ Fragment EnterScope(TreeNode* node, bool* new_context = NULL); |
Fragment EnterScope(intptr_t kernel_offset, bool* new_context = NULL); |
+ Fragment ExitScope(TreeNode* node); |
Fragment ExitScope(intptr_t kernel_offset); |
Fragment LoadContextAt(int depth); |
@@ -751,6 +943,7 @@ class FlowGraphBuilder { |
Fragment EvaluateAssertion(); |
Fragment CheckReturnTypeInCheckedMode(); |
+ Fragment CheckVariableTypeInCheckedMode(VariableDeclaration* variable); |
Fragment CheckVariableTypeInCheckedMode(const AbstractType& dst_type, |
const dart::String& name_symbol); |
Fragment CheckBooleanInCheckedMode(); |
@@ -761,6 +954,9 @@ class FlowGraphBuilder { |
Fragment AssertAssignable(const dart::AbstractType& dst_type, |
const dart::String& dst_name); |
+ template <class Invocation> |
+ bool RecognizeComparisonWithNull(Token::Kind token_kind, Invocation* node); |
+ |
bool NeedsDebugStepCheck(const Function& function, TokenPosition position); |
bool NeedsDebugStepCheck(Value* value, TokenPosition position); |
Fragment DebugStepCheck(TokenPosition position); |
@@ -774,6 +970,10 @@ class FlowGraphBuilder { |
intptr_t CurrentTryIndex(); |
intptr_t AllocateTryIndex() { return next_used_try_index_++; } |
+ void AddVariable(VariableDeclaration* declaration, LocalVariable* variable); |
+ void AddParameter(VariableDeclaration* declaration, |
+ LocalVariable* variable, |
+ intptr_t pos); |
dart::LocalVariable* LookupVariable(VariableDeclaration* var); |
dart::LocalVariable* LookupVariable(intptr_t kernel_offset); |
@@ -793,7 +993,9 @@ class FlowGraphBuilder { |
Thread* thread_; |
Zone* zone_; |
- intptr_t kernel_offset_; |
+ // The node we are currently compiling (e.g. FunctionNode, Constructor, |
+ // Field) |
+ TreeNode* node_; |
ParsedFunction* parsed_function_; |
intptr_t osr_id_; |
@@ -823,6 +1025,7 @@ class FlowGraphBuilder { |
intptr_t try_depth_; |
intptr_t catch_depth_; |
intptr_t for_in_depth_; |
+ Fragment fragment_; |
Value* stack_; |
intptr_t pending_argument_count_; |
@@ -866,6 +1069,7 @@ class FlowGraphBuilder { |
ActiveClass active_class_; |
DartTypeTranslator type_translator_; |
+ ConstantEvaluator constant_evaluator_; |
StreamingFlowGraphBuilder* streaming_flow_graph_builder_; |