Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 30542) |
| +++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy) |
| @@ -3800,10 +3800,12 @@ |
| handleNewSend(NewExpression node) { |
| Send send = node.send; |
| bool isFixedList = false; |
| + bool isFixedListConstructorCall = |
| + Elements.isFixedListConstructorCall(elements[send], send, compiler); |
| TypeMask computeType(element) { |
| Element originalElement = elements[send]; |
| - if (Elements.isFixedListConstructorCall(originalElement, send, compiler) |
| + if (isFixedListConstructorCall |
| || Elements.isFilledListConstructorCall( |
| originalElement, send, compiler)) { |
| isFixedList = true; |
| @@ -3878,30 +3880,59 @@ |
| return; |
| } |
| - ClassElement cls = constructor.getEnclosingClass(); |
| - if (cls.isAbstract && constructor.isGenerativeConstructor()) { |
| - generateAbstractClassInstantiationError(send, cls.name); |
| - return; |
| - } |
| - if (backend.classNeedsRti(cls)) { |
| - Link<DartType> typeVariable = cls.typeVariables; |
| - expectedType.typeArguments.forEach((DartType argument) { |
| - inputs.add(analyzeTypeArgument(argument)); |
| - typeVariable = typeVariable.tail; |
| - }); |
| - assert(typeVariable.isEmpty); |
| - } |
| - |
| if (constructor.isFactoryConstructor() && |
| !expectedType.typeArguments.isEmpty) { |
| compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); |
| } |
| + |
| TypeMask elementType = computeType(constructor); |
| - addInlinedInstantiation(expectedType); |
| - pushInvokeStatic(node, constructor, inputs, elementType); |
| - removeInlinedInstantiation(expectedType); |
| + if (isFixedListConstructorCall) { |
| + if (!inputs[0].isNumber(compiler)) { |
| + HTypeConversion conversion = new HTypeConversion( |
| + null, HTypeConversion.ARGUMENT_TYPE_CHECK, backend.numType, |
| + inputs[0], null); |
| + add(conversion); |
| + inputs[0] = conversion; |
| + } |
| + js.Expression code = js.js.parseForeignJS('new Array(#)'); |
|
kasperl
2013/11/25 08:16:44
You can get rid of new here.
ngeoffray
2013/11/25 08:33:31
Done.
|
| + var behavior = new native.NativeBehavior(); |
| + behavior.typesReturned.add(expectedType); |
| + // The allocation can throw only if the given length is a double |
| + // or negative. |
| + HForeign foreign = new HForeign( |
| + code, elementType, inputs, nativeBehavior: behavior, canThrow: true); |
|
kasperl
2013/11/25 08:16:44
If you know something about the length (positive i
ngeoffray
2013/11/25 08:33:31
Done.
|
| + push(foreign); |
| + TypesInferrer inferrer = compiler.typesTask.typesInferrer; |
| + if (inferrer.isFixedArrayCheckedForGrowable(send)) { |
| + js.Expression code = js.js.parseForeignJS('#.fixed\$length = init'); |
|
kasperl
2013/11/25 08:16:44
Use raw string instead of escaping $?
Since you h
ngeoffray
2013/11/25 08:33:31
Done.
|
| + // We have to put a dummy side effect to avoid this |
| + // instruction being dead code. We need a finer grain side |
|
kasperl
2013/11/25 08:16:44
grain -> grained
ngeoffray
2013/11/25 08:33:31
Done.
|
| + // effect. |
| + SideEffects effects = new SideEffects.empty(); |
| + effects.setChangesInstanceProperty(); |
| + add(new HForeign( |
| + code, backend.nullType, [stack.last], effects: effects)); |
| + } |
| + } else { |
| + ClassElement cls = constructor.getEnclosingClass(); |
| + if (cls.isAbstract && constructor.isGenerativeConstructor()) { |
| + generateAbstractClassInstantiationError(send, cls.name); |
| + return; |
| + } |
| + if (backend.classNeedsRti(cls)) { |
| + Link<DartType> typeVariable = cls.typeVariables; |
| + expectedType.typeArguments.forEach((DartType argument) { |
| + inputs.add(analyzeTypeArgument(argument)); |
| + typeVariable = typeVariable.tail; |
| + }); |
| + assert(typeVariable.isEmpty); |
| + } |
| + |
| + addInlinedInstantiation(expectedType); |
| + pushInvokeStatic(node, constructor, inputs, elementType); |
| + removeInlinedInstantiation(expectedType); |
| + } |
| HInstruction newInstance = stack.last; |
| - |
| if (isFixedList) { |
| JavaScriptItemCompilationContext context = work.compilationContext; |
| context.allocatedFixedLists.add(newInstance); |
| @@ -3911,7 +3942,7 @@ |
| // not know about the type argument. Therefore we special case |
| // this constructor to have the setRuntimeTypeInfo called where |
| // the 'new' is done. |
| - if (isJSArrayTypedConstructor && |
| + if ((isFixedListConstructorCall || isJSArrayTypedConstructor) && |
| backend.classNeedsRti(compiler.listClass)) { |
| handleListConstructor(type, send, newInstance); |
| } |