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