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

Unified Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 1092263002: dart2js: add type arguments to constructor in case the class needs rti. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 5 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/type_test_registry.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/ssa/builder.dart
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 2dca5031067a69d05063bccad4a974cf8654d439..259e510dfad89face15e162b11cf7c00ca72c6ab 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -2143,28 +2143,11 @@ class SsaBuilder extends NewResolvedVisitor {
instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations);
}
- HInstruction newObject;
- if (!isNativeUpgradeFactory) {
- newObject = new HForeignNew(classElement,
- ssaType,
- constructorArguments,
- instantiatedTypes);
- add(newObject);
- } else {
- // Bulk assign to the initialized fields.
- newObject = graph.explicitReceiverParameter;
- // Null guard ensures an error if we are being called from an explicit
- // 'new' of the constructor instead of via an upgrade. It is optimized out
- // if there are field initializers.
- add(new HFieldGet(
- null, newObject, backend.dynamicType, isAssignable: false));
- for (int i = 0; i < fields.length; i++) {
- add(new HFieldSet(fields[i], newObject, constructorArguments[i]));
- }
- }
- removeInlinedInstantiation(type);
- // Create the runtime type information, if needed.
- if (backend.classNeedsRti(classElement)) {
+ /// Fills [typeArguments] with the values of type arguments to be set on
+ /// the newly created object. Returns the source if the arguments can
+ /// simply be copied over.
+ HThis computeSourceOrTypeArguments(ClassElement classElement,
+ List<HInstruction> typeArguments) {
// Read the values of the type arguments and create a list to set on the
// newly create object. We can identify the case where the new list
// would be of the form:
@@ -2218,7 +2201,6 @@ class SsaBuilder extends NewResolvedVisitor {
return constant.primitiveValue == expectedIndex++;
}
- List<HInstruction> typeArguments = <HInstruction>[];
classElement.typeVariables.forEach((TypeVariableType typeVariable) {
HInstruction argument = localsHandler.readLocal(
localsHandler.getTypeVariableAsLocal(typeVariable));
@@ -2229,13 +2211,64 @@ class SsaBuilder extends NewResolvedVisitor {
});
if (source != null && allIndexed && remainingTypeVariables == 0) {
- copyRuntimeTypeInfo(source, newObject);
+ return source;
} else {
- newObject =
- callSetRuntimeTypeInfo(classElement, typeArguments, newObject);
+ return null;
}
}
+ HInstruction newObject;
+ if (!isNativeUpgradeFactory) {
+ List<HInstruction> typeArguments = <HInstruction>[];
+ HThis source;
+ if (backend.classNeedsRti(classElement)) {
+ source = computeSourceOrTypeArguments(classElement, typeArguments);
+ }
+
+ // If the class needs rti and the type arguments cannot simply be copied
+ // over, we pass the type arguments to the constructor which will then set
+ // the type info on the object.
+ if (source == null && typeArguments.isNotEmpty) {
+ HInstruction typeArgumentsInstruction = buildLiteralList(typeArguments);
+ add(typeArgumentsInstruction);
+ constructorArguments..add(typeArgumentsInstruction);
+ }
+
+ newObject = new HForeignNew(classElement,
+ ssaType,
+ constructorArguments,
+ instantiatedTypes);
+ add(newObject);
+
+ if (source != null) {
+ copyRuntimeTypeInfo(source, newObject);
+ }
+ } else {
+ // Bulk assign to the initialized fields.
+ newObject = graph.explicitReceiverParameter;
+ // Null guard ensures an error if we are being called from an explicit
+ // 'new' of the constructor instead of via an upgrade. It is optimized out
+ // if there are field initializers.
+ add(new HFieldGet(
+ null, newObject, backend.dynamicType, isAssignable: false));
+ for (int i = 0; i < fields.length; i++) {
+ add(new HFieldSet(fields[i], newObject, constructorArguments[i]));
+ }
+
+ if (backend.classNeedsRti(classElement)) {
+ List<HInstruction> typeArguments = <HInstruction>[];
+ HThis source =
+ computeSourceOrTypeArguments(classElement, typeArguments);
+ if (source != null) {
+ copyRuntimeTypeInfo(source, newObject);
+ } else {
+ newObject = callSetRuntimeTypeInfo(classElement, typeArguments,
+ newObject);
+ }
+ }
+ }
+
+ removeInlinedInstantiation(type);
// Generate calls to the constructor bodies.
HInstruction interceptor = null;
for (int index = constructors.length - 1; index >= 0; index--) {
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/type_test_registry.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698