Chromium Code Reviews| Index: lib/compiler/implementation/ssa/builder.dart |
| =================================================================== |
| --- lib/compiler/implementation/ssa/builder.dart (revision 11430) |
| +++ lib/compiler/implementation/ssa/builder.dart (working copy) |
| @@ -1182,6 +1182,28 @@ |
| HForeignNew newObject = new HForeignNew(classElement, constructorArguments); |
| add(newObject); |
| + |
| + // If the class has type variables, create the runtime type |
| + // information with the type parameters provided. |
| + if (!classElement.typeVariables.isEmpty()) { |
| + List<String> typeVariables = <String>[]; |
| + List<HInstruction> rtiInputs = <HInstruction>[]; |
| + classElement.typeVariables.forEach((TypeVariableType typeVariable) { |
| + typeVariables.add("'$typeVariable': #"); |
| + rtiInputs.add(localsHandler.directLocals[typeVariable.element]); |
| + }); |
| + String jsCode = '{ ${Strings.join(typeVariables, ', ')} }'; |
| + HInstruction typeInfo = new HForeign(new LiteralDartString(jsCode), |
| + new LiteralDartString('Object'), |
| + rtiInputs); |
| + add(typeInfo); |
| + Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo(); |
| + HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); |
| + add(typeInfoSetter); |
| + add(new HInvokeStatic( |
| + <HInstruction>[typeInfoSetter, newObject, typeInfo])); |
| + } |
| + |
| // Generate calls to the constructor bodies. |
| for (int index = constructors.length - 1; index >= 0; index--) { |
| FunctionElement constructor = constructors[index]; |
| @@ -1228,6 +1250,18 @@ |
| localsHandler.directLocals[element], element); |
| localsHandler.directLocals[element] = newParameter; |
| }); |
| + |
| + // Add the type parameters of the class as parameters of this |
| + // method. |
| + if (functionElement.isFactoryConstructor() |
| + || functionElement.isGenerativeConstructor()) { |
| + ClassElement cls = functionElement.enclosingElement; |
| + cls.typeVariables.forEach((TypeVariableType typeVariable) { |
| + HParameterValue param = new HParameterValue(typeVariable.element); |
| + add(param); |
| + localsHandler.directLocals[typeVariable.element] = param; |
| + }); |
| + } |
| } |
| HInstruction potentiallyCheckType(HInstruction original, |
| @@ -2464,30 +2498,42 @@ |
| compiler.cancel('Unimplemented non-matching static call', node: node); |
| } |
| + TypeAnnotation annotation = getTypeAnnotationFromSend(node); |
| + elements.getType(annotation).arguments.forEach((Type argument) { |
| + if (argument.element.isTypeVariable()) { |
|
kasperl
2012/08/28 09:14:15
Maybe factor this code out into a helper function.
ngeoffray
2012/08/28 10:39:45
Done.
|
| + if (work.element.isFactoryConstructor()) { |
| + // The type variable is stored in a parameter of the |
| + // factory. |
| + inputs.add(localsHandler.readLocal(argument.element)); |
| + } else if (work.element.isInstanceMember() |
| + || work.element.isGenerativeConstructor()) { |
|
kasperl
2012/08/28 09:14:15
Aren't they also available as locals in generative
ngeoffray
2012/08/28 10:39:45
Good point. Done.
|
| + // The type variable is stored in [this]. |
| + pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), |
| + localsHandler.readThis()); |
| + HInstruction typeInfo = pop(); |
| + HInstruction foreign = new HForeign( |
|
kasperl
2012/08/28 09:14:15
Remove extra space after =.
ngeoffray
2012/08/28 10:39:45
Done.
|
| + new LiteralDartString('#.$argument'), |
| + new LiteralDartString('String'), |
| + <HInstruction>[typeInfo]); |
| + add(foreign); |
| + inputs.add(foreign); |
| + } else { |
| + // TODO(ngeoffray): Match the VM behavior and throw an |
| + // exception at runtime. |
| + compiler.cancel('Unimplemented unresolved type variable', node: node); |
| + } |
| + } else { |
| + // The type variable is a type (e.g. int). |
| + inputs.add(graph.addConstantString( |
| + new LiteralDartString('$argument'), node)); |
| + } |
| + }); |
| + |
| HType elementType = computeType(element); |
| HInstruction newInstance = new HInvokeStatic(inputs, elementType); |
| pushWithPosition(newInstance, node); |
| - |
| - TypeAnnotation annotation = getTypeAnnotationFromSend(node); |
| - Type type = elements.getType(annotation); |
| - generateSetRuntimeTypeInformation(newInstance, type); |
| } |
| - generateSetRuntimeTypeInformation(HInstruction instance, Type type) { |
| - if (compiler.codegenWorld.rti.hasTypeArguments(type)) { |
| - String typeString = compiler.codegenWorld.rti.asJsString(type); |
| - HInstruction typeInfo = new HForeign(new LiteralDartString(typeString), |
| - new LiteralDartString('Object'), |
| - <HInstruction>[]); |
| - add(typeInfo); |
| - Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo(); |
| - HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); |
| - add(typeInfoSetter); |
| - var inputs = <HInstruction>[typeInfoSetter, instance, typeInfo]; |
| - add(new HInvokeStatic(inputs)); |
| - } |
| - } |
| - |
| visitStaticSend(Send node) { |
| Selector selector = elements.getSelector(node); |
| Element element = elements[node]; |