| 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 class SsaFunctionCompiler implements FunctionCompiler { | 7 class SsaFunctionCompiler implements FunctionCompiler { |
| 8 SsaCodeGeneratorTask generator; | 8 SsaCodeGeneratorTask generator; |
| 9 SsaBuilderTask builder; | 9 SsaBuilderTask builder; |
| 10 SsaOptimizerTask optimizer; | 10 SsaOptimizerTask optimizer; |
| (...skipping 2086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2097 | 2097 |
| 2098 InterfaceType type = classElement.thisType; | 2098 InterfaceType type = classElement.thisType; |
| 2099 TypeMask ssaType = | 2099 TypeMask ssaType = |
| 2100 new TypeMask.nonNullExact(classElement.declaration, compiler.world); | 2100 new TypeMask.nonNullExact(classElement.declaration, compiler.world); |
| 2101 List<DartType> instantiatedTypes; | 2101 List<DartType> instantiatedTypes; |
| 2102 addInlinedInstantiation(type); | 2102 addInlinedInstantiation(type); |
| 2103 if (!currentInlinedInstantiations.isEmpty) { | 2103 if (!currentInlinedInstantiations.isEmpty) { |
| 2104 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); | 2104 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); |
| 2105 } | 2105 } |
| 2106 | 2106 |
| 2107 /// Fills [typeArguments] with the values of type arguments to be set on | 2107 HInstruction newObject; |
| 2108 /// the newly created object. Returns the source if the arguments can | 2108 if (!isNativeUpgradeFactory) { |
| 2109 /// simply be copied over. | 2109 newObject = new HForeignNew(classElement, |
| 2110 HThis computeSourceOrTypeArguments(ClassElement classElement, | 2110 ssaType, |
| 2111 List<HInstruction> typeArguments) { | 2111 constructorArguments, |
| 2112 instantiatedTypes); |
| 2113 add(newObject); |
| 2114 } else { |
| 2115 // Bulk assign to the initialized fields. |
| 2116 newObject = graph.explicitReceiverParameter; |
| 2117 // Null guard ensures an error if we are being called from an explicit |
| 2118 // 'new' of the constructor instead of via an upgrade. It is optimized out |
| 2119 // if there are field initializers. |
| 2120 add(new HFieldGet( |
| 2121 null, newObject, backend.dynamicType, isAssignable: false)); |
| 2122 for (int i = 0; i < fields.length; i++) { |
| 2123 add(new HFieldSet(fields[i], newObject, constructorArguments[i])); |
| 2124 } |
| 2125 } |
| 2126 removeInlinedInstantiation(type); |
| 2127 // Create the runtime type information, if needed. |
| 2128 if (backend.classNeedsRti(classElement)) { |
| 2112 // Read the values of the type arguments and create a list to set on the | 2129 // Read the values of the type arguments and create a list to set on the |
| 2113 // newly create object. We can identify the case where the new list | 2130 // newly create object. We can identify the case where the new list |
| 2114 // would be of the form: | 2131 // would be of the form: |
| 2115 // [getTypeArgumentByIndex(this, 0), .., getTypeArgumentByIndex(this, k)] | 2132 // [getTypeArgumentByIndex(this, 0), .., getTypeArgumentByIndex(this, k)] |
| 2116 // and k is the number of type arguments of this. If this is the case, | 2133 // and k is the number of type arguments of this. If this is the case, |
| 2117 // we can simply copy the list from this. | 2134 // we can simply copy the list from this. |
| 2118 | 2135 |
| 2119 // These locals are modified by [isIndexedTypeArgumentGet]. | 2136 // These locals are modified by [isIndexedTypeArgumentGet]. |
| 2120 HThis source; // The source of the type arguments. | 2137 HThis source; // The source of the type arguments. |
| 2121 bool allIndexed = true; | 2138 bool allIndexed = true; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2155 // If there are no more type variables, then there are more type | 2172 // If there are no more type variables, then there are more type |
| 2156 // arguments for the new object than the source has, and it can't be | 2173 // arguments for the new object than the source has, and it can't be |
| 2157 // a copy. Otherwise remove one argument. | 2174 // a copy. Otherwise remove one argument. |
| 2158 if (remainingTypeVariables == 0) return false; | 2175 if (remainingTypeVariables == 0) return false; |
| 2159 remainingTypeVariables--; | 2176 remainingTypeVariables--; |
| 2160 // Check that the index is the one we expect. | 2177 // Check that the index is the one we expect. |
| 2161 IntConstantValue constant = index.constant; | 2178 IntConstantValue constant = index.constant; |
| 2162 return constant.primitiveValue == expectedIndex++; | 2179 return constant.primitiveValue == expectedIndex++; |
| 2163 } | 2180 } |
| 2164 | 2181 |
| 2182 List<HInstruction> typeArguments = <HInstruction>[]; |
| 2165 classElement.typeVariables.forEach((TypeVariableType typeVariable) { | 2183 classElement.typeVariables.forEach((TypeVariableType typeVariable) { |
| 2166 HInstruction argument = localsHandler.readLocal( | 2184 HInstruction argument = localsHandler.readLocal( |
| 2167 localsHandler.getTypeVariableAsLocal(typeVariable)); | 2185 localsHandler.getTypeVariableAsLocal(typeVariable)); |
| 2168 if (allIndexed && !isIndexedTypeArgumentGet(argument)) { | 2186 if (allIndexed && !isIndexedTypeArgumentGet(argument)) { |
| 2169 allIndexed = false; | 2187 allIndexed = false; |
| 2170 } | 2188 } |
| 2171 typeArguments.add(argument); | 2189 typeArguments.add(argument); |
| 2172 }); | 2190 }); |
| 2173 | 2191 |
| 2174 if (source != null && allIndexed && remainingTypeVariables == 0) { | 2192 if (source != null && allIndexed && remainingTypeVariables == 0) { |
| 2175 return source; | 2193 copyRuntimeTypeInfo(source, newObject); |
| 2176 } else { | 2194 } else { |
| 2177 return null; | 2195 newObject = |
| 2196 callSetRuntimeTypeInfo(classElement, typeArguments, newObject); |
| 2178 } | 2197 } |
| 2179 } | 2198 } |
| 2180 | 2199 |
| 2181 HInstruction newObject; | |
| 2182 if (!isNativeUpgradeFactory) { | |
| 2183 List<HInstruction> typeArguments = <HInstruction>[]; | |
| 2184 HThis source; | |
| 2185 if (backend.classNeedsRti(classElement)) { | |
| 2186 source = computeSourceOrTypeArguments(classElement, typeArguments); | |
| 2187 } | |
| 2188 | |
| 2189 // If the class needs rti and the type arguments cannot simply be copied | |
| 2190 // over, we pass the type arguments to the constructor which will then set | |
| 2191 // the type info on the object. | |
| 2192 if (source == null && typeArguments.isNotEmpty) { | |
| 2193 HInstruction typeArgumentsInstruction = buildLiteralList(typeArguments); | |
| 2194 add(typeArgumentsInstruction); | |
| 2195 constructorArguments..add(typeArgumentsInstruction); | |
| 2196 } | |
| 2197 | |
| 2198 newObject = new HForeignNew(classElement, | |
| 2199 ssaType, | |
| 2200 constructorArguments, | |
| 2201 instantiatedTypes); | |
| 2202 add(newObject); | |
| 2203 | |
| 2204 if (source != null) { | |
| 2205 copyRuntimeTypeInfo(source, newObject); | |
| 2206 } | |
| 2207 } else { | |
| 2208 // Bulk assign to the initialized fields. | |
| 2209 newObject = graph.explicitReceiverParameter; | |
| 2210 // Null guard ensures an error if we are being called from an explicit | |
| 2211 // 'new' of the constructor instead of via an upgrade. It is optimized out | |
| 2212 // if there are field initializers. | |
| 2213 add(new HFieldGet( | |
| 2214 null, newObject, backend.dynamicType, isAssignable: false)); | |
| 2215 for (int i = 0; i < fields.length; i++) { | |
| 2216 add(new HFieldSet(fields[i], newObject, constructorArguments[i])); | |
| 2217 } | |
| 2218 | |
| 2219 if (backend.classNeedsRti(classElement)) { | |
| 2220 List<HInstruction> typeArguments = <HInstruction>[]; | |
| 2221 HThis source = | |
| 2222 computeSourceOrTypeArguments(classElement, typeArguments); | |
| 2223 if (source != null) { | |
| 2224 copyRuntimeTypeInfo(source, newObject); | |
| 2225 } else { | |
| 2226 newObject = callSetRuntimeTypeInfo(classElement, typeArguments, | |
| 2227 newObject); | |
| 2228 } | |
| 2229 } | |
| 2230 } | |
| 2231 | |
| 2232 removeInlinedInstantiation(type); | |
| 2233 // Generate calls to the constructor bodies. | 2200 // Generate calls to the constructor bodies. |
| 2234 HInstruction interceptor = null; | 2201 HInstruction interceptor = null; |
| 2235 for (int index = constructors.length - 1; index >= 0; index--) { | 2202 for (int index = constructors.length - 1; index >= 0; index--) { |
| 2236 FunctionElement constructor = constructors[index]; | 2203 FunctionElement constructor = constructors[index]; |
| 2237 assert(invariant(functionElement, constructor.isImplementation)); | 2204 assert(invariant(functionElement, constructor.isImplementation)); |
| 2238 ConstructorBodyElement body = getConstructorBody(constructor); | 2205 ConstructorBodyElement body = getConstructorBody(constructor); |
| 2239 if (body == null) continue; | 2206 if (body == null) continue; |
| 2240 | 2207 |
| 2241 List bodyCallInputs = <HInstruction>[]; | 2208 List bodyCallInputs = <HInstruction>[]; |
| 2242 if (isNativeUpgradeFactory) { | 2209 if (isNativeUpgradeFactory) { |
| (...skipping 5396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7639 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 7606 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 7640 unaliased.accept(this, builder); | 7607 unaliased.accept(this, builder); |
| 7641 } | 7608 } |
| 7642 | 7609 |
| 7643 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 7610 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 7644 JavaScriptBackend backend = builder.compiler.backend; | 7611 JavaScriptBackend backend = builder.compiler.backend; |
| 7645 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 7612 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
| 7646 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 7613 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
| 7647 } | 7614 } |
| 7648 } | 7615 } |
| OLD | NEW |