| 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 2125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2136 | 2136 |
| 2137 InterfaceType type = classElement.thisType; | 2137 InterfaceType type = classElement.thisType; |
| 2138 TypeMask ssaType = | 2138 TypeMask ssaType = |
| 2139 new TypeMask.nonNullExact(classElement.declaration, compiler.world); | 2139 new TypeMask.nonNullExact(classElement.declaration, compiler.world); |
| 2140 List<DartType> instantiatedTypes; | 2140 List<DartType> instantiatedTypes; |
| 2141 addInlinedInstantiation(type); | 2141 addInlinedInstantiation(type); |
| 2142 if (!currentInlinedInstantiations.isEmpty) { | 2142 if (!currentInlinedInstantiations.isEmpty) { |
| 2143 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); | 2143 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); |
| 2144 } | 2144 } |
| 2145 | 2145 |
| 2146 HInstruction newObject; | 2146 /// Fills [typeArguments] with the values of type arguments to be set on |
| 2147 if (!isNativeUpgradeFactory) { | 2147 /// the newly created object. Returns the source if the arguments can |
| 2148 newObject = new HForeignNew(classElement, | 2148 /// simply be copied over. |
| 2149 ssaType, | 2149 HThis computeSourceOrTypeArguments(ClassElement classElement, |
| 2150 constructorArguments, | 2150 List<HInstruction> typeArguments) { |
| 2151 instantiatedTypes); | |
| 2152 add(newObject); | |
| 2153 } else { | |
| 2154 // Bulk assign to the initialized fields. | |
| 2155 newObject = graph.explicitReceiverParameter; | |
| 2156 // Null guard ensures an error if we are being called from an explicit | |
| 2157 // 'new' of the constructor instead of via an upgrade. It is optimized out | |
| 2158 // if there are field initializers. | |
| 2159 add(new HFieldGet( | |
| 2160 null, newObject, backend.dynamicType, isAssignable: false)); | |
| 2161 for (int i = 0; i < fields.length; i++) { | |
| 2162 add(new HFieldSet(fields[i], newObject, constructorArguments[i])); | |
| 2163 } | |
| 2164 } | |
| 2165 removeInlinedInstantiation(type); | |
| 2166 // Create the runtime type information, if needed. | |
| 2167 if (backend.classNeedsRti(classElement)) { | |
| 2168 // Read the values of the type arguments and create a list to set on the | 2151 // Read the values of the type arguments and create a list to set on the |
| 2169 // newly create object. We can identify the case where the new list | 2152 // newly create object. We can identify the case where the new list |
| 2170 // would be of the form: | 2153 // would be of the form: |
| 2171 // [getTypeArgumentByIndex(this, 0), .., getTypeArgumentByIndex(this, k)] | 2154 // [getTypeArgumentByIndex(this, 0), .., getTypeArgumentByIndex(this, k)] |
| 2172 // and k is the number of type arguments of this. If this is the case, | 2155 // and k is the number of type arguments of this. If this is the case, |
| 2173 // we can simply copy the list from this. | 2156 // we can simply copy the list from this. |
| 2174 | 2157 |
| 2175 // These locals are modified by [isIndexedTypeArgumentGet]. | 2158 // These locals are modified by [isIndexedTypeArgumentGet]. |
| 2176 HThis source; // The source of the type arguments. | 2159 HThis source; // The source of the type arguments. |
| 2177 bool allIndexed = true; | 2160 bool allIndexed = true; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2211 // If there are no more type variables, then there are more type | 2194 // If there are no more type variables, then there are more type |
| 2212 // arguments for the new object than the source has, and it can't be | 2195 // arguments for the new object than the source has, and it can't be |
| 2213 // a copy. Otherwise remove one argument. | 2196 // a copy. Otherwise remove one argument. |
| 2214 if (remainingTypeVariables == 0) return false; | 2197 if (remainingTypeVariables == 0) return false; |
| 2215 remainingTypeVariables--; | 2198 remainingTypeVariables--; |
| 2216 // Check that the index is the one we expect. | 2199 // Check that the index is the one we expect. |
| 2217 IntConstantValue constant = index.constant; | 2200 IntConstantValue constant = index.constant; |
| 2218 return constant.primitiveValue == expectedIndex++; | 2201 return constant.primitiveValue == expectedIndex++; |
| 2219 } | 2202 } |
| 2220 | 2203 |
| 2221 List<HInstruction> typeArguments = <HInstruction>[]; | |
| 2222 classElement.typeVariables.forEach((TypeVariableType typeVariable) { | 2204 classElement.typeVariables.forEach((TypeVariableType typeVariable) { |
| 2223 HInstruction argument = localsHandler.readLocal( | 2205 HInstruction argument = localsHandler.readLocal( |
| 2224 localsHandler.getTypeVariableAsLocal(typeVariable)); | 2206 localsHandler.getTypeVariableAsLocal(typeVariable)); |
| 2225 if (allIndexed && !isIndexedTypeArgumentGet(argument)) { | 2207 if (allIndexed && !isIndexedTypeArgumentGet(argument)) { |
| 2226 allIndexed = false; | 2208 allIndexed = false; |
| 2227 } | 2209 } |
| 2228 typeArguments.add(argument); | 2210 typeArguments.add(argument); |
| 2229 }); | 2211 }); |
| 2230 | 2212 |
| 2231 if (source != null && allIndexed && remainingTypeVariables == 0) { | 2213 if (source != null && allIndexed && remainingTypeVariables == 0) { |
| 2232 copyRuntimeTypeInfo(source, newObject); | 2214 return source; |
| 2233 } else { | 2215 } else { |
| 2234 newObject = | 2216 return null; |
| 2235 callSetRuntimeTypeInfo(classElement, typeArguments, newObject); | |
| 2236 } | 2217 } |
| 2237 } | 2218 } |
| 2238 | 2219 |
| 2220 HInstruction newObject; |
| 2221 if (!isNativeUpgradeFactory) { |
| 2222 List<HInstruction> typeArguments = <HInstruction>[]; |
| 2223 HThis source; |
| 2224 if (backend.classNeedsRti(classElement)) { |
| 2225 source = computeSourceOrTypeArguments(classElement, typeArguments); |
| 2226 } |
| 2227 |
| 2228 // If the class needs rti and the type arguments cannot simply be copied |
| 2229 // over, we pass the type arguments to the constructor which will then set |
| 2230 // the type info on the object. |
| 2231 if (source == null && typeArguments.isNotEmpty) { |
| 2232 HInstruction typeArgumentsInstruction = buildLiteralList(typeArguments); |
| 2233 add(typeArgumentsInstruction); |
| 2234 constructorArguments..add(typeArgumentsInstruction); |
| 2235 } |
| 2236 |
| 2237 newObject = new HForeignNew(classElement, |
| 2238 ssaType, |
| 2239 constructorArguments, |
| 2240 instantiatedTypes); |
| 2241 add(newObject); |
| 2242 |
| 2243 if (source != null) { |
| 2244 copyRuntimeTypeInfo(source, newObject); |
| 2245 } |
| 2246 } else { |
| 2247 // Bulk assign to the initialized fields. |
| 2248 newObject = graph.explicitReceiverParameter; |
| 2249 // Null guard ensures an error if we are being called from an explicit |
| 2250 // 'new' of the constructor instead of via an upgrade. It is optimized out |
| 2251 // if there are field initializers. |
| 2252 add(new HFieldGet( |
| 2253 null, newObject, backend.dynamicType, isAssignable: false)); |
| 2254 for (int i = 0; i < fields.length; i++) { |
| 2255 add(new HFieldSet(fields[i], newObject, constructorArguments[i])); |
| 2256 } |
| 2257 |
| 2258 if (backend.classNeedsRti(classElement)) { |
| 2259 List<HInstruction> typeArguments = <HInstruction>[]; |
| 2260 HThis source = |
| 2261 computeSourceOrTypeArguments(classElement, typeArguments); |
| 2262 if (source != null) { |
| 2263 copyRuntimeTypeInfo(source, newObject); |
| 2264 } else { |
| 2265 newObject = callSetRuntimeTypeInfo(classElement, typeArguments, |
| 2266 newObject); |
| 2267 } |
| 2268 } |
| 2269 } |
| 2270 |
| 2271 removeInlinedInstantiation(type); |
| 2239 // Generate calls to the constructor bodies. | 2272 // Generate calls to the constructor bodies. |
| 2240 HInstruction interceptor = null; | 2273 HInstruction interceptor = null; |
| 2241 for (int index = constructors.length - 1; index >= 0; index--) { | 2274 for (int index = constructors.length - 1; index >= 0; index--) { |
| 2242 FunctionElement constructor = constructors[index]; | 2275 FunctionElement constructor = constructors[index]; |
| 2243 assert(invariant(functionElement, constructor.isImplementation)); | 2276 assert(invariant(functionElement, constructor.isImplementation)); |
| 2244 ConstructorBodyElement body = getConstructorBody(constructor); | 2277 ConstructorBodyElement body = getConstructorBody(constructor); |
| 2245 if (body == null) continue; | 2278 if (body == null) continue; |
| 2246 | 2279 |
| 2247 List bodyCallInputs = <HInstruction>[]; | 2280 List bodyCallInputs = <HInstruction>[]; |
| 2248 if (isNativeUpgradeFactory) { | 2281 if (isNativeUpgradeFactory) { |
| (...skipping 5419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7668 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 7701 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 7669 unaliased.accept(this, builder); | 7702 unaliased.accept(this, builder); |
| 7670 } | 7703 } |
| 7671 | 7704 |
| 7672 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 7705 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 7673 JavaScriptBackend backend = builder.compiler.backend; | 7706 JavaScriptBackend backend = builder.compiler.backend; |
| 7674 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 7707 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
| 7675 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 7708 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
| 7676 } | 7709 } |
| 7677 } | 7710 } |
| OLD | NEW |