Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
| 9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
| 10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
| (...skipping 3782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3793 null, | 3793 null, |
| 3794 typeInfoSetterElement, | 3794 typeInfoSetterElement, |
| 3795 <HInstruction>[newObject, typeInfo], | 3795 <HInstruction>[newObject, typeInfo], |
| 3796 backend.dynamicType); | 3796 backend.dynamicType); |
| 3797 pop(); | 3797 pop(); |
| 3798 } | 3798 } |
| 3799 | 3799 |
| 3800 handleNewSend(NewExpression node) { | 3800 handleNewSend(NewExpression node) { |
| 3801 Send send = node.send; | 3801 Send send = node.send; |
| 3802 bool isFixedList = false; | 3802 bool isFixedList = false; |
| 3803 bool isFixedListConstructorCall = | |
| 3804 Elements.isFixedListConstructorCall(elements[send], send, compiler); | |
| 3803 | 3805 |
| 3804 TypeMask computeType(element) { | 3806 TypeMask computeType(element) { |
| 3805 Element originalElement = elements[send]; | 3807 Element originalElement = elements[send]; |
| 3806 if (Elements.isFixedListConstructorCall(originalElement, send, compiler) | 3808 if (isFixedListConstructorCall |
| 3807 || Elements.isFilledListConstructorCall( | 3809 || Elements.isFilledListConstructorCall( |
| 3808 originalElement, send, compiler)) { | 3810 originalElement, send, compiler)) { |
| 3809 isFixedList = true; | 3811 isFixedList = true; |
| 3810 TypeMask inferred = | 3812 TypeMask inferred = |
| 3811 TypeMaskFactory.inferredForNode(currentElement, send, compiler); | 3813 TypeMaskFactory.inferredForNode(currentElement, send, compiler); |
| 3812 return inferred.containsAll(compiler) | 3814 return inferred.containsAll(compiler) |
| 3813 ? backend.fixedArrayType | 3815 ? backend.fixedArrayType |
| 3814 : inferred; | 3816 : inferred; |
| 3815 } else if (Elements.isGrowableListConstructorCall( | 3817 } else if (Elements.isGrowableListConstructorCall( |
| 3816 originalElement, send, compiler)) { | 3818 originalElement, send, compiler)) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3871 // TODO(5347): Try to avoid the need for calling [implementation] before | 3873 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 3872 // calling [addStaticSendArgumentsToList]. | 3874 // calling [addStaticSendArgumentsToList]. |
| 3873 bool succeeded = addStaticSendArgumentsToList(selector, send.arguments, | 3875 bool succeeded = addStaticSendArgumentsToList(selector, send.arguments, |
| 3874 constructor.implementation, | 3876 constructor.implementation, |
| 3875 inputs); | 3877 inputs); |
| 3876 if (!succeeded) { | 3878 if (!succeeded) { |
| 3877 generateWrongArgumentCountError(send, constructor, send.arguments); | 3879 generateWrongArgumentCountError(send, constructor, send.arguments); |
| 3878 return; | 3880 return; |
| 3879 } | 3881 } |
| 3880 | 3882 |
| 3881 ClassElement cls = constructor.getEnclosingClass(); | |
| 3882 if (cls.isAbstract && constructor.isGenerativeConstructor()) { | |
| 3883 generateAbstractClassInstantiationError(send, cls.name); | |
| 3884 return; | |
| 3885 } | |
| 3886 if (backend.classNeedsRti(cls)) { | |
| 3887 Link<DartType> typeVariable = cls.typeVariables; | |
| 3888 expectedType.typeArguments.forEach((DartType argument) { | |
| 3889 inputs.add(analyzeTypeArgument(argument)); | |
| 3890 typeVariable = typeVariable.tail; | |
| 3891 }); | |
| 3892 assert(typeVariable.isEmpty); | |
| 3893 } | |
| 3894 | |
| 3895 if (constructor.isFactoryConstructor() && | 3883 if (constructor.isFactoryConstructor() && |
| 3896 !expectedType.typeArguments.isEmpty) { | 3884 !expectedType.typeArguments.isEmpty) { |
| 3897 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); | 3885 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); |
| 3898 } | 3886 } |
| 3887 | |
| 3899 TypeMask elementType = computeType(constructor); | 3888 TypeMask elementType = computeType(constructor); |
| 3900 addInlinedInstantiation(expectedType); | 3889 if (isFixedListConstructorCall) { |
| 3901 pushInvokeStatic(node, constructor, inputs, elementType); | 3890 if (!inputs[0].isNumber(compiler)) { |
| 3902 removeInlinedInstantiation(expectedType); | 3891 HTypeConversion conversion = new HTypeConversion( |
| 3892 null, HTypeConversion.ARGUMENT_TYPE_CHECK, backend.numType, | |
| 3893 inputs[0], null); | |
| 3894 add(conversion); | |
| 3895 inputs[0] = conversion; | |
| 3896 } | |
| 3897 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.
| |
| 3898 var behavior = new native.NativeBehavior(); | |
| 3899 behavior.typesReturned.add(expectedType); | |
| 3900 // The allocation can throw only if the given length is a double | |
| 3901 // or negative. | |
| 3902 HForeign foreign = new HForeign( | |
| 3903 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.
| |
| 3904 push(foreign); | |
| 3905 TypesInferrer inferrer = compiler.typesTask.typesInferrer; | |
| 3906 if (inferrer.isFixedArrayCheckedForGrowable(send)) { | |
| 3907 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.
| |
| 3908 // We have to put a dummy side effect to avoid this | |
| 3909 // 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.
| |
| 3910 // effect. | |
| 3911 SideEffects effects = new SideEffects.empty(); | |
| 3912 effects.setChangesInstanceProperty(); | |
| 3913 add(new HForeign( | |
| 3914 code, backend.nullType, [stack.last], effects: effects)); | |
| 3915 } | |
| 3916 } else { | |
| 3917 ClassElement cls = constructor.getEnclosingClass(); | |
| 3918 if (cls.isAbstract && constructor.isGenerativeConstructor()) { | |
| 3919 generateAbstractClassInstantiationError(send, cls.name); | |
| 3920 return; | |
| 3921 } | |
| 3922 if (backend.classNeedsRti(cls)) { | |
| 3923 Link<DartType> typeVariable = cls.typeVariables; | |
| 3924 expectedType.typeArguments.forEach((DartType argument) { | |
| 3925 inputs.add(analyzeTypeArgument(argument)); | |
| 3926 typeVariable = typeVariable.tail; | |
| 3927 }); | |
| 3928 assert(typeVariable.isEmpty); | |
| 3929 } | |
| 3930 | |
| 3931 addInlinedInstantiation(expectedType); | |
| 3932 pushInvokeStatic(node, constructor, inputs, elementType); | |
| 3933 removeInlinedInstantiation(expectedType); | |
| 3934 } | |
| 3903 HInstruction newInstance = stack.last; | 3935 HInstruction newInstance = stack.last; |
| 3904 | |
| 3905 if (isFixedList) { | 3936 if (isFixedList) { |
| 3906 JavaScriptItemCompilationContext context = work.compilationContext; | 3937 JavaScriptItemCompilationContext context = work.compilationContext; |
| 3907 context.allocatedFixedLists.add(newInstance); | 3938 context.allocatedFixedLists.add(newInstance); |
| 3908 } | 3939 } |
| 3909 | 3940 |
| 3910 // The List constructor forwards to a Dart static method that does | 3941 // The List constructor forwards to a Dart static method that does |
| 3911 // not know about the type argument. Therefore we special case | 3942 // not know about the type argument. Therefore we special case |
| 3912 // this constructor to have the setRuntimeTypeInfo called where | 3943 // this constructor to have the setRuntimeTypeInfo called where |
| 3913 // the 'new' is done. | 3944 // the 'new' is done. |
| 3914 if (isJSArrayTypedConstructor && | 3945 if ((isFixedListConstructorCall || isJSArrayTypedConstructor) && |
| 3915 backend.classNeedsRti(compiler.listClass)) { | 3946 backend.classNeedsRti(compiler.listClass)) { |
| 3916 handleListConstructor(type, send, newInstance); | 3947 handleListConstructor(type, send, newInstance); |
| 3917 } | 3948 } |
| 3918 | 3949 |
| 3919 // Finally, if we called a redirecting factory constructor, check the type. | 3950 // Finally, if we called a redirecting factory constructor, check the type. |
| 3920 if (isRedirected) { | 3951 if (isRedirected) { |
| 3921 HInstruction checked = potentiallyCheckType(newInstance, type); | 3952 HInstruction checked = potentiallyCheckType(newInstance, type); |
| 3922 if (checked != newInstance) { | 3953 if (checked != newInstance) { |
| 3923 pop(); | 3954 pop(); |
| 3924 stack.add(checked); | 3955 stack.add(checked); |
| (...skipping 1979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5904 new HSubGraphBlockInformation(elseBranch.graph)); | 5935 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5905 | 5936 |
| 5906 HBasicBlock conditionStartBlock = conditionBranch.block; | 5937 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5907 conditionStartBlock.setBlockFlow(info, joinBlock); | 5938 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5908 SubGraph conditionGraph = conditionBranch.graph; | 5939 SubGraph conditionGraph = conditionBranch.graph; |
| 5909 HIf branch = conditionGraph.end.last; | 5940 HIf branch = conditionGraph.end.last; |
| 5910 assert(branch is HIf); | 5941 assert(branch is HIf); |
| 5911 branch.blockInformation = conditionStartBlock.blockFlow; | 5942 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5912 } | 5943 } |
| 5913 } | 5944 } |
| OLD | NEW |