Chromium Code Reviews| Index: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
| index 1510315ede7eaabeb732eeebadcf722b4dd8ab3a..49d94ea2fef66cb83cf2ad665e9b968034d0702f 100644 |
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
| @@ -361,10 +361,14 @@ class InvokeMethodDirectly extends Expression implements Invoke { |
| /// Non-const call to a constructor. The [target] may be a generative |
| /// constructor, factory, or redirecting factory. |
| class InvokeConstructor extends Expression implements Invoke { |
|
karlklose
2015/03/18 08:44:51
Alternatively, we could split this into two backen
asgerf
2015/03/18 10:18:06
Following my comment in codegen, I think construct
|
| + /// [type] encodes the instantiated type for the [DartBackend]; it must be |
| + /// `null` in the [JavaScriptBackend]. |
| final DartType type; |
| final FunctionElement target; |
| final Reference<Continuation> continuation; |
| final List<Reference<Primitive>> arguments; |
| + /// The type arguments are used in the [JavaScriptBackend]. |
| + final List<Reference<Primitive>> typeArguments; |
| final Selector selector; |
| /// The class being instantiated. This is the same as `target.enclosingClass` |
| @@ -374,23 +378,35 @@ class InvokeConstructor extends Expression implements Invoke { |
| /// True if this is an invocation of a factory constructor. |
| bool get isFactory => target.isFactoryConstructor; |
| - InvokeConstructor(this.type, |
| - this.target, |
| - this.selector, |
| - Continuation cont, |
| - List<Primitive> args) |
| + InvokeConstructor.byType(this.type, |
| + this.target, |
| + this.selector, |
| + Continuation cont, |
| + List<Primitive> args) |
| : continuation = new Reference<Continuation>(cont), |
| - arguments = _referenceList(args) { |
| - assert(dart2js.invariant(target, |
| - target.isErroneous || target.isConstructor, |
| - message: "Constructor invocation target is not a constructor: " |
| - "$target.")); |
| + arguments = _referenceList(args), |
| + typeArguments = const <Reference<Primitive>>[] { |
| assert(dart2js.invariant(target, |
| target.isErroneous || |
| type.isDynamic || |
| type.element == target.enclosingClass.declaration, |
| - message: "Constructor invocation type ${type} does not match enclosing " |
| - "class of target ${target}.")); |
| + message: "Constructor invocation target is not a constructor: " |
| + "$target.")); |
| + } |
| + |
| + InvokeConstructor.withTypeArguments(this.target, |
| + this.selector, |
| + Continuation cont, |
| + List<Primitive> args, |
| + List<Primitive> typeArguments) |
| + : type = null, |
| + continuation = new Reference<Continuation>(cont), |
| + arguments = _referenceList(args), |
| + typeArguments = _referenceList(typeArguments) { |
| + assert(dart2js.invariant(target, |
| + target.isErroneous || target.isConstructor, |
| + message: "Constructor invocation target is not a constructor: " |
| + "$target.")); |
| } |
| accept(Visitor visitor) => visitor.visitInvokeConstructor(this); |
| @@ -898,6 +914,22 @@ class ReadTypeVariable extends Primitive implements JsSpecificNode { |
| accept(Visitor visitor) => visitor.visitReadTypeVariable(this); |
| } |
|
asgerf
2015/03/18 10:18:06
It's not clear to me what dartType should be.
If
|
| +/// Denotes the internal representation of [dartType], where all type variables |
| +/// are replaced by the values in [arguments]. |
| +class TypeExpression extends Primitive implements JsSpecificNode { |
| + final DartType dartType; |
| + final List<Reference<Primitive>> arguments; |
| + |
| + TypeExpression(this.dartType, |
| + [List<Primitive> arguments = const <Primitive>[]]) |
| + : this.arguments = _referenceList(arguments); |
| + |
| + @override |
| + accept(Visitor visitor) { |
| + return visitor.visitTypeExpression(this); |
| + } |
| +} |
| + |
| List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { |
| return definitions.map((e) => new Reference<Primitive>(e)).toList(); |
| } |
| @@ -961,6 +993,7 @@ abstract class Visitor<T> { |
| T visitCreateBox(CreateBox node); |
| T visitReifyRuntimeType(ReifyRuntimeType node); |
| T visitReadTypeVariable(ReadTypeVariable node); |
| + T visitTypeExpression(TypeExpression node); |
| } |
| /// Recursively visits the entire CPS term, and calls abstract `process*` |
| @@ -1082,6 +1115,7 @@ class RecursiveVisitor implements Visitor { |
| processInvokeConstructor(node); |
| processReference(node.continuation); |
| node.arguments.forEach(processReference); |
| + node.typeArguments.forEach(processReference); |
| } |
| processConcatenateStrings(ConcatenateStrings node) {} |
| @@ -1233,6 +1267,13 @@ class RecursiveVisitor implements Visitor { |
| processReadTypeVariable(node); |
| processReference(node.target); |
| } |
| + |
| + processTypeExpression(TypeExpression node) {} |
| + @override |
| + visitTypeExpression(TypeExpression node) { |
| + processTypeExpression(node); |
| + node.arguments.forEach(processReference); |
| + } |
| } |
| /// Keeps track of currently unused register indices. |
| @@ -1393,6 +1434,7 @@ class RegisterAllocator implements Visitor { |
| void visitInvokeConstructor(InvokeConstructor node) { |
| node.arguments.forEach(visitReference); |
| + node.typeArguments.forEach(visitReference); |
| } |
| void visitConcatenateStrings(ConcatenateStrings node) { |
| @@ -1505,4 +1547,9 @@ class RegisterAllocator implements Visitor { |
| void visitReadTypeVariable(ReadTypeVariable node) { |
| visitReference(node.target); |
| } |
| + |
| + @override |
| + visitTypeExpression(TypeExpression node) { |
| + node.arguments.forEach(visitReference); |
| + } |
| } |