Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 1913033002: dart2js: Pass type information to constructor rather than add later. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: rebase Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698