Chromium Code Reviews| Index: lib/compiler/implementation/ssa/builder.dart |
| diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart |
| index 961d1081d3df829add1b569632d8f23911e588af..c9c167c223ca5e21649418ae121265577135d429 100644 |
| --- a/lib/compiler/implementation/ssa/builder.dart |
| +++ b/lib/compiler/implementation/ssa/builder.dart |
| @@ -123,6 +123,15 @@ class Interceptors { |
| Element getMapMaker() { |
| return compiler.findHelper(const SourceString('makeLiteralMap')); |
| } |
| + |
| + // TODO(karlklose): move these to different class or rename class? |
| + Element getSetRuntimeTypeInfo() { |
| + return compiler.findHelper(const SourceString('setRuntimeTypeInfo')); |
| + } |
| + |
| + Element getGetRuntimeTypeInfo() { |
| + return compiler.findHelper(const SourceString('getRuntimeTypeInfo')); |
| + } |
| } |
| class SsaBuilderTask extends CompilerTask { |
| @@ -1790,7 +1799,17 @@ class SsaBuilder implements Visitor { |
| typeAnnotation = argument.asSend().receiver; |
| isNot = true; |
| } |
| + |
| Type type = elements.getType(typeAnnotation); |
| + HInstruction typeInfo = null; |
| + if (compiler.universe.rti.hasTypeArguments(type)) { |
| + HInstruction typeInfoGetter = |
| + new HStatic(interceptors.getGetRuntimeTypeInfo()); |
| + add(typeInfoGetter); |
| + typeInfo = new HInvokeStatic(Selector.INVOCATION_1, |
| + <HInstruction>[typeInfoGetter, expression]); |
|
kasperl
2012/04/30 08:48:32
Line too long.
ngeoffray
2012/04/30 08:51:12
line too long
karlklose
2012/05/01 11:20:55
Done.
karlklose
2012/05/01 11:20:55
Done.
|
| + add(typeInfo); |
| + } |
| if (type.element.kind === ElementKind.TYPE_VARIABLE) { |
| // TODO(karlklose): We emulate the frog behavior and answer |
| // true to any is check involving a type variable -- both is T |
| @@ -1798,7 +1817,12 @@ class SsaBuilder implements Visitor { |
| // reified generics. |
| stack.add(graph.addConstantBool(true)); |
| } else { |
| - HInstruction instruction = new HIs(type, expression); |
| + HInstruction instruction; |
| + if (compiler.universe.rti.hasTypeArguments(type)) { |
|
kasperl
2012/04/30 08:48:32
Change this check to typeInfo != null?
karlklose
2012/05/01 11:20:55
Done.
|
| + instruction = new HIs.withTypeInfo(type, expression, typeInfo); |
| + } else { |
| + instruction = new HIs(type, expression); |
| + } |
| if (isNot) { |
| add(instruction); |
| instruction = new HNot(instruction); |
| @@ -2153,20 +2177,68 @@ class SsaBuilder implements Visitor { |
| } |
| } |
| - visitStaticSend(Send node) { |
| + visitNewSend(Send node) { |
| Selector selector = elements.getSelector(node); |
| Element element = elements[node]; |
| - if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR) { |
| - compiler.resolver.resolveMethodElement(element); |
| - FunctionElement functionElement = element; |
| - element = functionElement.defaultImplementation; |
| + compiler.resolver.resolveMethodElement(element); |
| + FunctionElement functionElement = element; |
| + element = functionElement.defaultImplementation; |
| + HInstruction target = new HStatic(element); |
| + add(target); |
| + var inputs = <HInstruction>[]; |
| + inputs.add(target); |
| + bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| + element, inputs); |
| + if (!succeeded) { |
| + // TODO(ngeoffray): Match the VM behavior and throw an |
| + // exception at runtime. |
| + compiler.cancel('Unimplemented non-matching static call', node: node); |
| } |
| + |
| + HType elementType = HType.UNKNOWN; |
|
kasperl
2012/04/30 08:48:32
Factor out the computation of elementType?
karlklose
2012/05/01 11:20:55
Done.
|
| + Element originalElement = elements[node]; |
| + if (originalElement.enclosingElement === compiler.listClass) { |
| + if (node.arguments.isEmpty()) { |
| + elementType = HType.EXTENDABLE_ARRAY; |
| + } else { |
| + elementType = HType.MUTABLE_ARRAY; |
| + } |
| + } else if (element.isGenerativeConstructor()) { |
| + ClassElement cls = element.enclosingElement; |
| + elementType = new HNonPrimitiveType(cls.type); |
| + } |
| + HInstruction newInstance = new HInvokeStatic(selector, inputs, elementType); |
| + push(newInstance); |
| + |
| + TypeAnnotation annotation = getTypeAnnotationFromSend(node); |
| + Type type = elements.getType(annotation); |
| + |
| + if (compiler.universe.rti.hasTypeArguments(type)) { |
|
kasperl
2012/04/30 08:48:32
Factor out the code in this if?
karlklose
2012/05/01 11:20:55
Done.
|
| + String typeString = compiler.universe.rti.asJsString(type); |
| + HInstruction typeInfo = new HForeign(new LiteralDartString(typeString), |
| + new LiteralDartString('Object'), |
| + <HInstruction>[]); |
| + add(typeInfo); |
| + |
| + HInstruction typeInfoSetter = |
| + new HStatic(interceptors.getSetRuntimeTypeInfo()); |
| + add(typeInfoSetter); |
| + Selector setSelector = Selector.INVOCATION_2; |
| + add(new HInvokeStatic(setSelector, |
| + <HInstruction>[typeInfoSetter, newInstance, |
| + typeInfo])); |
| + } |
| + } |
| + |
| + visitStaticSend(Send node) { |
| + Selector selector = elements.getSelector(node); |
| + Element element = elements[node]; |
| + compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR); |
| HInstruction target = new HStatic(element); |
| add(target); |
| var inputs = <HInstruction>[]; |
| inputs.add(target); |
| - if (element.kind == ElementKind.FUNCTION || |
| - element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { |
| + if (element.kind == ElementKind.FUNCTION) { |
| bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| element, inputs); |
| if (!succeeded) { |
| @@ -2174,20 +2246,7 @@ class SsaBuilder implements Visitor { |
| // exception at runtime. |
| compiler.cancel('Unimplemented non-matching static call', node: node); |
| } |
| - HType type = HType.UNKNOWN; |
| - Element originalElement = elements[node]; |
| - if (originalElement.isGenerativeConstructor() |
| - && originalElement.enclosingElement === compiler.listClass) { |
| - if (node.arguments.isEmpty()) { |
| - type = HType.EXTENDABLE_ARRAY; |
| - } else { |
| - type = HType.MUTABLE_ARRAY; |
| - } |
| - } else if (element.isGenerativeConstructor()) { |
| - ClassElement cls = element.enclosingElement; |
| - type = new HNonPrimitiveType(cls.type); |
| - } |
| - push(new HInvokeStatic(selector, inputs, type)); |
| + push(new HInvokeStatic(selector, inputs)); |
| } else { |
| if (element.kind == ElementKind.GETTER) { |
| target = new HInvokeStatic(Selector.GETTER, inputs); |
| @@ -2235,13 +2294,28 @@ class SsaBuilder implements Visitor { |
| } |
| } |
| + // TODO(karlklose): share with resolver. |
| + TypeAnnotation getTypeAnnotationFromSend(Send send) { |
| + if (send.selector.asTypeAnnotation() !== null) { |
|
kasperl
2012/04/30 08:48:32
I wonder if it wouldn't be cleaner with is checks
karlklose
2012/05/01 11:20:55
Changed to is-checks.
|
| + return send.selector; |
| + } else if (send.selector.asSend() !== null) { |
| + Send selector = send.selector; |
| + if (selector.receiver.asTypeAnnotation() !== null) { |
| + return selector.receiver; |
| + } |
| + } else { |
| + compiler.internalError("malformed send in new expression"); |
|
kasperl
2012/04/30 08:48:32
Do we usually start our error messages with a capi
karlklose
2012/05/01 11:20:55
We use both variants.
|
| + } |
| + } |
| + |
| visitNewExpression(NewExpression node) { |
| if (node.isConst()) { |
| + // TODO(karlklose): add type representation |
| ConstantHandler handler = compiler.constantHandler; |
| Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| stack.add(graph.addConstant(constant)); |
| } else { |
| - visitSend(node.send); |
| + visitNewSend(node.send); |
| } |
| } |