Chromium Code Reviews| Index: pkg/compiler/lib/src/ssa/builder.dart |
| diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart |
| index 50fa510cee2b5419e9214dcabb19d4b9338af5c8..ec0f0b2720ea6ece7398402618f86fbeaecfd2d6 100644 |
| --- a/pkg/compiler/lib/src/ssa/builder.dart |
| +++ b/pkg/compiler/lib/src/ssa/builder.dart |
| @@ -1019,12 +1019,18 @@ class SwitchCaseJumpHandler extends TargetJumpHandler { |
| /** |
| * This class builds SSA nodes for functions represented in AST. |
| */ |
| -class SsaBuilder extends NewResolvedVisitor { |
| +class SsaBuilder extends ast.Visitor |
| + with BaseImplementationOfCompoundsMixin, |
| + SendResolverMixin, |
| + SemanticSendResolvedMixin, |
| + NewBulkMixin |
| + implements SemanticSendVisitor { |
| final Compiler compiler; |
| final JavaScriptBackend backend; |
| final ConstantSystem constantSystem; |
| final CodegenWorkItem work; |
| final RuntimeTypes rti; |
| + TreeElements elements; |
| SourceInformationBuilder sourceInformationBuilder; |
| bool inLazyInitializerExpression = false; |
| @@ -1119,13 +1125,26 @@ class SsaBuilder extends NewResolvedVisitor { |
| this.constantSystem = backend.constantSystem, |
| this.work = work, |
| this.rti = backend.rti, |
| - super(work.resolutionTree) { |
| + this.elements = work.resolutionTree { |
| localsHandler = new LocalsHandler(this, work.element, null); |
| sourceElementStack.add(work.element); |
| sourceInformationBuilder = |
| sourceInformationFactory.forContext(work.element.implementation); |
| } |
| + @override |
| + SemanticSendVisitor get sendVisitor => this; |
| + |
| + @override |
| + void visitNode(ast.Node node) { |
| + internalError(node, "Unhandled node: $node"); |
| + } |
| + |
| + @override |
| + void apply(ast.Node node, [_]) { |
| + node.accept(this); |
| + } |
| + |
| CodegenRegistry get registry => work.registry; |
| /// Returns the current source element. |
| @@ -3123,9 +3142,14 @@ class SsaBuilder extends NewResolvedVisitor { |
| localsHandler.updateLocal(localFunction, pop()); |
| } |
| + @override |
| + void visitThisGet(ast.Identifier node, [_]) { |
|
sigurdm
2015/06/26 07:44:19
Should this be called `handleThisGet`? I am not ex
Johnni Winther
2015/06/26 10:15:25
It is part of the [SemanticSendVisitor]. `this` is
|
| + stack.add(localsHandler.readThis()); |
| + } |
| + |
| visitIdentifier(ast.Identifier node) { |
| if (node.isThis()) { |
| - stack.add(localsHandler.readThis()); |
| + visitThisGet(node); |
| } else { |
| compiler.internalError(node, |
| "SsaFromAstMixin.visitIdentifier on non-this."); |
| @@ -4401,18 +4425,6 @@ class SsaBuilder extends NewResolvedVisitor { |
| generateSuperNoSuchMethodSend(node, selector, arguments); |
| } |
| - /// Handle super constructor invocation. |
| - @override |
| - void handleSuperConstructorInvoke(ast.Send node) { |
| - Selector selector = elements.getSelector(node); |
| - Element element = elements[node]; |
| - if (selector.applies(element, compiler.world)) { |
| - generateSuperInvoke(node, element); |
| - } else { |
| - generateWrongArgumentCountError(node, element, node.arguments); |
| - } |
| - } |
| - |
| @override |
| void visitUnresolvedSuperIndex( |
| ast.Send node, |
| @@ -4575,6 +4587,20 @@ class SsaBuilder extends NewResolvedVisitor { |
| ast.NodeList arguments, |
| CallStructure callStructure, |
| _) { |
| + handleInvalidSuperInvoke(node, arguments); |
| + } |
| + |
| + @override |
| + visitSuperSetterInvoke( |
|
sigurdm
2015/06/26 07:44:19
void return type?
Johnni Winther
2015/06/26 10:15:25
Done.
|
| + ast.Send node, |
| + SetterElement setter, |
| + ast.NodeList arguments, |
| + CallStructure callStructure, |
| + _) { |
| + handleInvalidSuperInvoke(node, arguments); |
| + } |
| + |
| + void handleInvalidSuperInvoke(ast.Send node, ast.NodeList arguments) { |
| Selector selector = elements.getSelector(node); |
| List<HInstruction> inputs = <HInstruction>[]; |
| addGenericSendArgumentsToList(arguments.nodes, inputs); |
| @@ -4760,7 +4786,7 @@ class SsaBuilder extends NewResolvedVisitor { |
| return pop(); |
| } |
| - handleNewSend(ast.NewExpression node) { |
| + void handleNewSend(ast.NewExpression node) { |
| ast.Send send = node.send; |
| generateIsDeferredLoadedCheckOfSend(send); |
| @@ -5427,7 +5453,12 @@ class SsaBuilder extends NewResolvedVisitor { |
| } |
| @override |
| - handleNewExpression(ast.NewExpression node) { |
| + void bulkHandleNode(ast.Node node, String message, _) { |
| + internalError(node, "Unexpected bulk handled node: $node"); |
| + } |
| + |
| + @override |
| + void bulkHandleNew(ast.NewExpression node, [_]) { |
| Element element = elements[node.send]; |
| final bool isSymbolConstructor = element == compiler.symbolConstructor; |
| if (!Elements.isErroneous(element)) { |
| @@ -5463,6 +5494,17 @@ class SsaBuilder extends NewResolvedVisitor { |
| } |
| } |
| + @override |
| + void errorNonConstantConstructorInvoke( |
| + ast.NewExpression node, |
| + Element element, |
| + DartType type, |
| + ast.NodeList arguments, |
| + CallStructure callStructure, |
| + _) { |
| + bulkHandleNew(node); |
| + } |
| + |
| void pushInvokeDynamic(ast.Node node, |
| Selector selector, |
| TypeMask mask, |
| @@ -5690,6 +5732,342 @@ class SsaBuilder extends NewResolvedVisitor { |
| } |
| @override |
| + void handleSuperCompounds( |
| + ast.SendSet node, |
| + Element getter, |
| + CompoundGetter getterKind, |
| + Element setter, |
| + CompoundSetter setterKind, |
| + CompoundRhs rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + @override |
| + void visitFinalSuperFieldSet( |
| + ast.SendSet node, |
| + FieldElement field, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + @override |
| + void visitSuperFieldSet( |
| + ast.SendSet node, |
| + FieldElement field, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + @override |
| + void visitSuperGetterSet( |
| + ast.SendSet node, |
| + FunctionElement getter, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + @override |
| + void visitSuperIndexSet( |
| + ast.SendSet node, |
| + FunctionElement function, |
| + ast.Node index, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + @override |
| + void visitSuperMethodSet( |
| + ast.Send node, |
| + MethodElement method, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + @override |
| + void visitSuperSetterSet( |
| + ast.SendSet node, |
| + FunctionElement setter, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + @override |
| + void visitUnresolvedSuperIndexSet( |
| + ast.Send node, |
| + Element element, |
| + ast.Node index, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitSuperIndexPrefix( |
| + ast.Send node, |
| + MethodElement indexFunction, |
| + MethodElement indexSetFunction, |
| + ast.Node index, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitSuperIndexPostfix( |
| + ast.Send node, |
| + MethodElement indexFunction, |
| + MethodElement indexSetFunction, |
| + ast.Node index, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperGetterIndexPrefix( |
| + ast.Send node, |
| + Element element, |
| + MethodElement setter, |
| + ast.Node index, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperGetterIndexPostfix( |
| + ast.Send node, |
| + Element element, |
| + MethodElement setter, |
| + ast.Node index, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperSetterIndexPrefix( |
| + ast.Send node, |
| + MethodElement indexFunction, |
| + Element element, |
| + ast.Node index, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperSetterIndexPostfix( |
| + ast.Send node, |
| + MethodElement indexFunction, |
| + Element element, |
| + ast.Node index, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperIndexPrefix( |
| + ast.Send node, |
| + Element element, |
| + ast.Node index, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperIndexPostfix( |
| + ast.Send node, |
| + Element element, |
| + ast.Node index, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitSuperCompoundIndexSet( |
| + ast.SendSet node, |
| + MethodElement getter, |
| + MethodElement setter, |
| + ast.Node index, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperGetterCompoundIndexSet( |
| + ast.Send node, |
| + Element element, |
| + MethodElement setter, |
| + ast.Node index, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperSetterCompoundIndexSet( |
| + ast.Send node, |
| + MethodElement getter, |
| + Element element, |
| + ast.Node index, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperCompoundIndexSet( |
| + ast.Send node, |
| + Element element, |
| + ast.Node index, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitSuperFieldCompound( |
| + ast.Send node, |
| + FieldElement field, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitFinalSuperFieldCompound( |
| + ast.Send node, |
| + FieldElement field, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitFinalSuperFieldPrefix( |
| + ast.Send node, |
| + FieldElement field, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperPrefix( |
| + ast.Send node, |
| + Element element, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperPostfix( |
| + ast.Send node, |
| + Element element, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperCompound( |
| + ast.Send node, |
| + Element element, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitFinalSuperFieldPostfix( |
| + ast.Send node, |
| + FieldElement field, |
| + IncDecOperator operator, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitSuperFieldFieldCompound( |
| + ast.Send node, |
| + FieldElement readField, |
| + FieldElement writtenField, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitSuperGetterSetterCompound( |
| + ast.Send node, |
| + FunctionElement getter, |
| + FunctionElement setter, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitSuperMethodSetterCompound( |
| + ast.Send node, |
| + FunctionElement method, |
| + FunctionElement setter, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitSuperMethodCompound( |
| + ast.Send node, |
| + FunctionElement method, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperGetterCompound( |
| + ast.Send node, |
| + Element element, |
| + MethodElement setter, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitUnresolvedSuperSetterCompound( |
| + ast.Send node, |
| + MethodElement getter, |
| + Element element, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitSuperFieldSetterCompound( |
| + ast.Send node, |
| + FieldElement field, |
| + FunctionElement setter, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + void visitSuperGetterFieldCompound( |
| + ast.Send node, |
| + FunctionElement getter, |
| + FieldElement field, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + handleSuperSendSet(node); |
| + } |
| + |
| + @override |
| void visitIndexSet( |
| ast.SendSet node, |
| ast.Node receiver, |
| @@ -5699,6 +6077,38 @@ class SsaBuilder extends NewResolvedVisitor { |
| generateDynamicSend(node); |
| } |
| + void visitCompoundIndexSet( |
| + ast.SendSet node, |
| + ast.Node receiver, |
| + ast.Node index, |
| + AssignmentOperator operator, |
| + ast.Node rhs, |
| + _) { |
| + generateIsDeferredLoadedCheckOfSend(node); |
| + handleIndexSendSet(node); |
| + } |
| + |
| + |
| + void visitIndexPrefix( |
| + ast.Send node, |
| + ast.Node receiver, |
| + ast.Node index, |
| + IncDecOperator operator, |
| + _) { |
| + generateIsDeferredLoadedCheckOfSend(node); |
| + handleIndexSendSet(node); |
| + } |
| + |
| + void visitIndexPostfix( |
| + ast.Send node, |
| + ast.Node receiver, |
| + ast.Node index, |
| + IncDecOperator operator, |
| + _) { |
| + generateIsDeferredLoadedCheckOfSend(node); |
| + handleIndexSendSet(node); |
| + } |
| + |
| void handleIndexSendSet(ast.SendSet node) { |
| ast.Operator op = node.assignmentOperator; |
| if ("=" == op.source) { |
| @@ -6108,27 +6518,36 @@ class SsaBuilder extends NewResolvedVisitor { |
| } |
| @override |
| - handleSendSet(ast.SendSet node) { |
| - ast.Operator op = node.assignmentOperator; |
| - generateIsDeferredLoadedCheckOfSend(node); |
| - Element element = elements[node]; |
| - if (!Elements.isUnresolved(element) && element.impliesType) { |
| - ast.Identifier selector = node.selector; |
| - generateThrowNoSuchMethod(node, selector.source, |
| - argumentNodes: node.arguments); |
| - } else if (node.isSuperCall) { |
| - handleSuperSendSet(node); |
| - } else if (node.isIndex) { |
| - handleIndexSendSet(node); |
| - } else if ("=" == op.source) { |
| - internalError(node, "Unexpected assignment."); |
| - } else if (identical(op.source, "is")) { |
| - compiler.internalError(op, "is-operator as SendSet."); |
| - } else { |
| - assert("++" == op.source || "--" == op.source || |
| - node.assignmentOperator.source.endsWith("=")); |
| - handleCompoundSendSet(node); |
| - } |
| + void handleDynamicCompounds( |
| + ast.Send node, |
| + ast.Node receiver, |
| + CompoundRhs rhs, |
| + Selector getterSelector, |
| + Selector setterSelector, |
| + _) { |
| + handleCompoundSendSet(node); |
| + } |
| + |
| + @override |
| + void handleLocalCompounds( |
| + ast.SendSet node, |
| + LocalElement local, |
| + CompoundRhs rhs, |
| + _, |
| + {bool isSetterValid}) { |
| + handleCompoundSendSet(node); |
| + } |
| + |
| + @override |
| + void handleStaticCompounds( |
| + ast.SendSet node, |
| + Element getter, |
| + CompoundGetter getterKind, |
| + Element setter, |
| + CompoundSetter setterKind, |
| + CompoundRhs rhs, |
| + _) { |
| + handleCompoundSendSet(node); |
| } |
| void visitLiteralInt(ast.LiteralInt node) { |
| @@ -7571,6 +7990,80 @@ class SsaBuilder extends NewResolvedVisitor { |
| localsHandler.updateLocal(returnLocal, value); |
| } |
| } |
| + |
| + @override |
| + void handleTypeLiteralConstantCompounds( |
| + ast.SendSet node, |
| + ConstantExpression constant, |
| + CompoundRhs rhs, |
| + _) { |
| + if (rhs.operator.kind == BinaryOperatorKind.IF_NULL) { |
| + handleCompoundSendSet(node); |
| + } else { |
| + handleTypeLiteralCompound(node); |
| + } |
| + } |
| + |
| + @override |
| + void handleTypeVariableTypeLiteralCompounds( |
| + ast.SendSet node, |
| + TypeVariableElement typeVariable, |
| + CompoundRhs rhs, |
| + _) { |
| + handleTypeLiteralCompound(node); |
| + } |
| + |
| + void handleTypeLiteralCompound(ast.SendSet node) { |
| + generateIsDeferredLoadedCheckOfSend(node); |
| + ast.Identifier selector = node.selector; |
| + generateThrowNoSuchMethod(node, selector.source, |
| + argumentNodes: node.arguments); |
| + } |
| + |
| + @override |
| + visitConstantGet( |
|
sigurdm
2015/06/26 07:44:19
void return type?
Johnni Winther
2015/06/26 10:15:25
Done.
|
| + ast.Send node, |
| + ConstantExpression constant, |
| + _) { |
| + visitNode(node); |
| + } |
| + |
| + @override |
| + visitConstantInvoke( |
|
sigurdm
2015/06/26 07:44:19
void return type?
Johnni Winther
2015/06/26 10:15:25
Done.
|
| + ast.Send node, |
| + ConstantExpression constant, |
| + ast.NodeList arguments, |
| + CallStructure callStreucture, |
| + _) { |
| + visitNode(node); |
| + } |
| + |
| + @override |
| + void errorInvalidAssert( |
| + ast.Send node, |
| + ast.NodeList arguments, |
| + _) { |
| + visitNode(node); |
| + } |
| + |
| + @override |
| + void errorUndefinedBinaryExpression( |
| + ast.Send node, |
| + ast.Node left, |
| + ast.Operator operator, |
| + ast.Node right, |
| + _) { |
| + visitNode(node); |
| + } |
| + |
| + @override |
| + void errorUndefinedUnaryExpression( |
| + ast.Send node, |
| + ast.Operator operator, |
| + ast.Node expression, |
| + _) { |
| + visitNode(node); |
| + } |
| } |
| /** |