Chromium Code Reviews| Index: lib/compiler/implementation/ssa/builder.dart |
| =================================================================== |
| --- lib/compiler/implementation/ssa/builder.dart (revision 12240) |
| +++ lib/compiler/implementation/ssa/builder.dart (working copy) |
| @@ -1239,16 +1239,7 @@ |
| 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])); |
| + callSetRuntimeTypeInfo(typeVariables, rtiInputs, newObject); |
| } |
| // Generate calls to the constructor bodies. |
| @@ -2627,10 +2618,43 @@ |
| } |
| } |
| + void handleListConstructor(InterfaceType type, |
| + Node currentNode, |
| + HInstruction newObject) { |
| + if (type.arguments.isEmpty()) return; |
| + List<HInstruction> inputs = <HInstruction>[]; |
| + type.arguments.forEach((DartType argument) { |
| + inputs.add(analyzeTypeArgument(argument, currentNode)); |
| + }); |
| + |
| + List<String> typeVariables = <String>[]; |
| + type.element.typeVariables.forEach((TypeVariableType typeVariable) { |
| + typeVariables.add("'$typeVariable': #"); |
| + }); |
| + |
| + callSetRuntimeTypeInfo(typeVariables, inputs, newObject); |
| + } |
| + |
| + void callSetRuntimeTypeInfo(List<String> typeVariables, |
| + List<HInstruction> inputs, |
| + HInstruction newObject) { |
| + String jsCode = '{ ${Strings.join(typeVariables, ', ')} }'; |
|
kasperl
2012/09/12 12:19:04
Somehow the decoupling of the way you turn the typ
ngeoffray
2012/09/12 12:30:39
Done.
|
| + HInstruction typeInfo = new HForeign(new LiteralDartString(jsCode), |
| + new LiteralDartString('Object'), |
| + inputs); |
| + add(typeInfo); |
| + Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo(); |
| + HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); |
| + add(typeInfoSetter); |
| + add(new HInvokeStatic(<HInstruction>[typeInfoSetter, newObject, typeInfo])); |
| + } |
| + |
| visitNewSend(Send node) { |
| + bool isListConstructor = false; |
| computeType(element) { |
| Element originalElement = elements[node]; |
| if (originalElement.getEnclosingClass() === compiler.listClass) { |
| + isListConstructor = true; |
| if (node.arguments.isEmpty()) { |
| return HType.EXTENDABLE_ARRAY; |
| } else { |
| @@ -2675,6 +2699,14 @@ |
| HType elementType = computeType(constructor); |
| HInstruction newInstance = new HInvokeStatic(inputs, elementType); |
| pushWithPosition(newInstance, node); |
| + |
| + // The List constructor forwards to a Dart static method that does |
| + // not know about the type argument. Therefore we special case |
| + // this constructor to have the setRuntimeTypeInfo called where |
| + // the 'new' is done. |
| + if (isListConstructor) { |
| + handleListConstructor(type, node, newInstance); |
| + } |
| } |
| visitStaticSend(Send node) { |