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 import 'dart:collection'; | 5 import 'dart:collection'; |
6 | 6 |
7 import 'package:js_runtime/shared/embedded_names.dart'; | 7 import 'package:js_runtime/shared/embedded_names.dart'; |
8 | 8 |
9 import '../closure.dart'; | 9 import '../closure.dart'; |
10 import '../common.dart'; | 10 import '../common.dart'; |
(...skipping 2274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2285 // implementation. | 2285 // implementation. |
2286 assert(invariant( | 2286 assert(invariant( |
2287 member, isNativeUpgradeFactory || compiler.compilationFailed)); | 2287 member, isNativeUpgradeFactory || compiler.compilationFailed)); |
2288 } else { | 2288 } else { |
2289 fields.add(member); | 2289 fields.add(member); |
2290 DartType type = localsHandler.substInContext(member.type); | 2290 DartType type = localsHandler.substInContext(member.type); |
2291 constructorArguments.add(potentiallyCheckOrTrustType(value, type)); | 2291 constructorArguments.add(potentiallyCheckOrTrustType(value, type)); |
2292 } | 2292 } |
2293 }, includeSuperAndInjectedMembers: true); | 2293 }, includeSuperAndInjectedMembers: true); |
2294 | 2294 |
2295 InterfaceType type = classElement.thisType; | |
2296 TypeMask ssaType = | |
2297 new TypeMask.nonNullExact(classElement.declaration, compiler.world); | |
2298 List<DartType> instantiatedTypes; | |
2299 addInlinedInstantiation(type); | |
2300 if (!currentInlinedInstantiations.isEmpty) { | |
2301 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); | |
2302 } | |
2303 | 2295 |
2304 HInstruction newObject; | |
2305 if (!isNativeUpgradeFactory) { | |
2306 newObject = new HForeignNew( | |
2307 classElement, ssaType, constructorArguments, instantiatedTypes); | |
2308 if (function != null) { | |
2309 // TODO(johnniwinther): Provide source information for creation | |
2310 // through synthetic constructors. | |
2311 newObject.sourceInformation = | |
2312 sourceInformationBuilder.buildCreate(function); | |
2313 } | |
2314 add(newObject); | |
2315 } else { | |
2316 // Bulk assign to the initialized fields. | |
2317 newObject = graph.explicitReceiverParameter; | |
2318 // Null guard ensures an error if we are being called from an explicit | |
2319 // 'new' of the constructor instead of via an upgrade. It is optimized out | |
2320 // if there are field initializers. | |
2321 add(new HFieldGet(null, newObject, backend.dynamicType, | |
2322 isAssignable: false)); | |
2323 for (int i = 0; i < fields.length; i++) { | |
2324 add(new HFieldSet(fields[i], newObject, constructorArguments[i])); | |
2325 } | |
2326 } | |
2327 removeInlinedInstantiation(type); | |
2328 // Create the runtime type information, if needed. | 2296 // Create the runtime type information, if needed. |
2329 if (backend.classNeedsRti(classElement)) { | 2297 if (backend.classNeedsRti(classElement)) { |
2330 // Read the values of the type arguments and create a list to set on the | 2298 // Read the values of the type arguments and create a list to set on the |
2331 // newly create object. We can identify the case where the new list | 2299 // newly create object. We can identify the case where the new list |
2332 // would be of the form: | 2300 // would be of the form: |
2333 // [getTypeArgumentByIndex(this, 0), .., getTypeArgumentByIndex(this, k)] | 2301 // [getTypeArgumentByIndex(this, 0), .., getTypeArgumentByIndex(this, k)] |
2334 // and k is the number of type arguments of this. If this is the case, | 2302 // and k is the number of type arguments of this. If this is the case, |
2335 // we can simply copy the list from this. | 2303 // we can simply copy the list from this. |
2336 | 2304 |
2337 // These locals are modified by [isIndexedTypeArgumentGet]. | 2305 // These locals are modified by [isIndexedTypeArgumentGet]. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2384 classElement.typeVariables.forEach((TypeVariableType typeVariable) { | 2352 classElement.typeVariables.forEach((TypeVariableType typeVariable) { |
2385 HInstruction argument = localsHandler | 2353 HInstruction argument = localsHandler |
2386 .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable)); | 2354 .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable)); |
2387 if (allIndexed && !isIndexedTypeArgumentGet(argument)) { | 2355 if (allIndexed && !isIndexedTypeArgumentGet(argument)) { |
2388 allIndexed = false; | 2356 allIndexed = false; |
2389 } | 2357 } |
2390 typeArguments.add(argument); | 2358 typeArguments.add(argument); |
2391 }); | 2359 }); |
2392 | 2360 |
2393 if (source != null && allIndexed && remainingTypeVariables == 0) { | 2361 if (source != null && allIndexed && remainingTypeVariables == 0) { |
2394 copyRuntimeTypeInfo(source, newObject); | 2362 // TODO(sra): Make this an instruction. |
2363 js.Template code = js.js.parseForeignJS(r'#.$ti'); | |
2364 HInstruction typeInfo = new HForeignCode( | |
2365 code, backend.stringType, | |
2366 <HInstruction>[source], | |
2367 nativeBehavior: native.NativeBehavior.PURE); | |
2368 add(typeInfo); | |
2369 constructorArguments.add(typeInfo); | |
2395 } else { | 2370 } else { |
2396 newObject = | 2371 HInstruction typeInfo = buildLiteralList(typeArguments); |
2397 callSetRuntimeTypeInfo(classElement, typeArguments, newObject); | 2372 add(typeInfo); |
2373 constructorArguments.add(typeInfo); | |
2398 } | 2374 } |
2399 } | 2375 } |
2400 | 2376 |
2377 InterfaceType type = classElement.thisType; | |
Siggi Cherem (dart-lang)
2016/08/19 16:39:46
just to make sure I didn't miss anything: this cod
sra1
2017/02/23 23:46:41
Yes. Since the type arguments are now a parameter,
| |
2378 TypeMask ssaType = | |
2379 new TypeMask.nonNullExact(classElement.declaration, compiler.world); | |
2380 List<DartType> instantiatedTypes; | |
2381 addInlinedInstantiation(type); | |
2382 if (!currentInlinedInstantiations.isEmpty) { | |
2383 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); | |
2384 } | |
2385 | |
2386 HInstruction newObject; | |
2387 if (!isNativeUpgradeFactory) { | |
2388 newObject = new HForeignNew( | |
2389 classElement, ssaType, constructorArguments, instantiatedTypes); | |
2390 if (function != null) { | |
2391 // TODO(johnniwinther): Provide source information for creation | |
2392 // through synthetic constructors. | |
2393 newObject.sourceInformation = | |
2394 sourceInformationBuilder.buildCreate(function); | |
2395 } | |
2396 add(newObject); | |
2397 } else { | |
2398 // Bulk assign to the initialized fields. | |
2399 newObject = graph.explicitReceiverParameter; | |
2400 // Null guard ensures an error if we are being called from an explicit | |
2401 // 'new' of the constructor instead of via an upgrade. It is optimized out | |
2402 // if there are field initializers. | |
2403 add(new HFieldGet(null, newObject, backend.dynamicType, | |
2404 isAssignable: false)); | |
2405 for (int i = 0; i < fields.length; i++) { | |
2406 add(new HFieldSet(fields[i], newObject, constructorArguments[i])); | |
2407 } | |
2408 } | |
2409 removeInlinedInstantiation(type); | |
2410 | |
2411 | |
2401 // Generate calls to the constructor bodies. | 2412 // Generate calls to the constructor bodies. |
2402 HInstruction interceptor = null; | 2413 HInstruction interceptor = null; |
2403 for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) { | 2414 for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) { |
2404 ResolvedAst constructorResolvedAst = constructorResolvedAsts[index]; | 2415 ResolvedAst constructorResolvedAst = constructorResolvedAsts[index]; |
2405 ConstructorBodyElement body = getConstructorBody(constructorResolvedAst); | 2416 ConstructorBodyElement body = getConstructorBody(constructorResolvedAst); |
2406 if (body == null) continue; | 2417 if (body == null) continue; |
2407 | 2418 |
2408 List bodyCallInputs = <HInstruction>[]; | 2419 List bodyCallInputs = <HInstruction>[]; |
2409 if (isNativeUpgradeFactory) { | 2420 if (isNativeUpgradeFactory) { |
2410 if (interceptor == null) { | 2421 if (interceptor == null) { |
(...skipping 2438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4849 | 4860 |
4850 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) { | 4861 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) { |
4851 Element copyHelper = helpers.copyTypeArguments; | 4862 Element copyHelper = helpers.copyTypeArguments; |
4852 pushInvokeStatic(null, copyHelper, [source, target], | 4863 pushInvokeStatic(null, copyHelper, [source, target], |
4853 sourceInformation: target.sourceInformation); | 4864 sourceInformation: target.sourceInformation); |
4854 pop(); | 4865 pop(); |
4855 } | 4866 } |
4856 | 4867 |
4857 HInstruction callSetRuntimeTypeInfo(ClassElement element, | 4868 HInstruction callSetRuntimeTypeInfo(ClassElement element, |
4858 List<HInstruction> rtiInputs, HInstruction newObject) { | 4869 List<HInstruction> rtiInputs, HInstruction newObject) { |
4859 if (!backend.classNeedsRti(element) || element.typeVariables.isEmpty) { | 4870 if (!backend.classNeedsRti(element)) { |
4860 return newObject; | 4871 return newObject; |
4861 } | 4872 } |
4862 | 4873 |
4863 HInstruction typeInfo = buildLiteralList(rtiInputs); | 4874 HInstruction typeInfo = buildLiteralList(rtiInputs); |
4864 add(typeInfo); | 4875 add(typeInfo); |
4865 | 4876 |
4866 // Set the runtime type information on the object. | 4877 // Set the runtime type information on the object. |
4867 Element typeInfoSetterElement = helpers.setRuntimeTypeInfo; | 4878 Element typeInfoSetterElement = helpers.setRuntimeTypeInfo; |
4868 pushInvokeStatic( | 4879 pushInvokeStatic( |
4869 null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo], | 4880 null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo], |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5096 pop(); | 5107 pop(); |
5097 stack.add(checked); | 5108 stack.add(checked); |
5098 } | 5109 } |
5099 } | 5110 } |
5100 } | 5111 } |
5101 | 5112 |
5102 void potentiallyAddTypeArguments( | 5113 void potentiallyAddTypeArguments( |
5103 List<HInstruction> inputs, ClassElement cls, InterfaceType expectedType, | 5114 List<HInstruction> inputs, ClassElement cls, InterfaceType expectedType, |
5104 {SourceInformation sourceInformation}) { | 5115 {SourceInformation sourceInformation}) { |
5105 if (!backend.classNeedsRti(cls)) return; | 5116 if (!backend.classNeedsRti(cls)) return; |
5106 assert(expectedType.typeArguments.isEmpty || | 5117 assert(cls.typeVariables.length == expectedType.typeArguments.length); |
5107 cls.typeVariables.length == expectedType.typeArguments.length); | |
5108 expectedType.typeArguments.forEach((DartType argument) { | 5118 expectedType.typeArguments.forEach((DartType argument) { |
5109 inputs.add( | 5119 inputs.add( |
5110 analyzeTypeArgument(argument, sourceInformation: sourceInformation)); | 5120 analyzeTypeArgument(argument, sourceInformation: sourceInformation)); |
5111 }); | 5121 }); |
5112 } | 5122 } |
5113 | 5123 |
5114 /// In checked mode checks the [type] of [node] to be well-bounded. The method | 5124 /// In checked mode checks the [type] of [node] to be well-bounded. The method |
5115 /// returns [:true:] if an error can be statically determined. | 5125 /// returns [:true:] if an error can be statically determined. |
5116 bool checkTypeVariableBounds(ast.NewExpression node, InterfaceType type) { | 5126 bool checkTypeVariableBounds(ast.NewExpression node, InterfaceType type) { |
5117 if (!compiler.options.enableTypeAssertions) return false; | 5127 if (!compiler.options.enableTypeAssertions) return false; |
(...skipping 3541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8659 const _LoopTypeVisitor(); | 8669 const _LoopTypeVisitor(); |
8660 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; | 8670 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; |
8661 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; | 8671 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; |
8662 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; | 8672 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; |
8663 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; | 8673 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; |
8664 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 8674 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
8665 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 8675 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
8666 int visitSwitchStatement(ast.SwitchStatement node) => | 8676 int visitSwitchStatement(ast.SwitchStatement node) => |
8667 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; | 8677 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; |
8668 } | 8678 } |
OLD | NEW |