Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
index 7ee27ee56b56183a0e46fb890bbb59897ebe116f..07f25bc8f9795c5730821acb64583872f861c3f9 100644 |
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
@@ -5039,19 +5039,61 @@ class SsaBuilder extends ResolvedVisitor { |
stack.add(addConstant(node)); |
return; |
} |
- List<HInstruction> inputs = <HInstruction>[]; |
+ List<HInstruction> listInputs = <HInstruction>[]; |
for (Link<ast.Node> link = node.entries.nodes; |
!link.isEmpty; |
link = link.tail) { |
visit(link.head); |
- inputs.add(pop()); |
- inputs.add(pop()); |
+ listInputs.add(pop()); |
+ listInputs.add(pop()); |
+ } |
+ |
+ Element constructor; |
+ List<HInstruction> inputs = <HInstruction>[]; |
+ |
+ if (listInputs.isEmpty) { |
+ constructor = backend.mapLiteralConstructorEmpty; |
+ } else { |
+ constructor = backend.mapLiteralConstructor; |
+ HLiteralList keyValuePairs = buildLiteralList(listInputs); |
+ add(keyValuePairs); |
+ inputs.add(keyValuePairs); |
+ } |
+ |
+ assert(constructor.isFactoryConstructor()); |
+ |
+ FunctionElement functionElement = constructor; |
+ constructor = functionElement.redirectionTarget; |
+ |
+ InterfaceType type = elements.getType(node); |
+ InterfaceType expectedType = functionElement.computeTargetType(type); |
+ |
+ if (constructor.isFactoryConstructor()) { |
+ compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); |
} |
- HLiteralList keyValuePairs = buildLiteralList(inputs); |
- add(keyValuePairs); |
+ |
+ ClassElement cls = constructor.getEnclosingClass(); |
+ |
+ if (backend.classNeedsRti(cls)) { |
+ Link<DartType> typeVariable = cls.typeVariables; |
+ expectedType.typeArguments.forEach((DartType argument) { |
+ inputs.add(analyzeTypeArgument(argument)); |
+ typeVariable = typeVariable.tail; |
+ }); |
+ assert(typeVariable.isEmpty); |
+ } |
+ |
+ // The instruction type will always be a subtype of the mapLiteralClass, but |
+ // type inference might discover a more specific type, or find nothing (in |
+ // dart2js unit tests). |
TypeMask mapType = new TypeMask.nonNullSubtype(backend.mapLiteralClass); |
- pushInvokeStatic(node, backend.getMapMaker(), [keyValuePairs], mapType); |
- stack.add(setRtiIfNeeded(pop(), node)); |
+ TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement( |
+ constructor, compiler); |
+ TypeMask instructionType = mapType.intersection(returnTypeMask, compiler); |
+ |
+ addInlinedInstantiation(expectedType); |
+ pushInvokeStatic(node, constructor, inputs, instructionType); |
+ removeInlinedInstantiation(expectedType); |
} |
visitLiteralMapEntry(ast.LiteralMapEntry node) { |