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 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 |