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

Unified Diff: lib/compiler/implementation/ssa/builder.dart

Issue 10888003: Change how runtime type information is being set in the backend. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 side-by-side diff with in-line comments
Download patch
Index: lib/compiler/implementation/ssa/builder.dart
===================================================================
--- lib/compiler/implementation/ssa/builder.dart (revision 11430)
+++ lib/compiler/implementation/ssa/builder.dart (working copy)
@@ -1182,6 +1182,28 @@
HForeignNew newObject = new HForeignNew(classElement, constructorArguments);
add(newObject);
+
+ // If the class has type variables, create the runtime type
+ // information with the type parameters provided.
+ if (!classElement.typeVariables.isEmpty()) {
+ List<String> typeVariables = <String>[];
+ List<HInstruction> rtiInputs = <HInstruction>[];
+ classElement.typeVariables.forEach((TypeVariableType typeVariable) {
+ typeVariables.add("'$typeVariable': #");
+ rtiInputs.add(localsHandler.directLocals[typeVariable.element]);
+ });
+ String jsCode = '{ ${Strings.join(typeVariables, ', ')} }';
+ HInstruction typeInfo = new HForeign(new LiteralDartString(jsCode),
+ new LiteralDartString('Object'),
+ rtiInputs);
+ add(typeInfo);
+ Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo();
+ HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement);
+ add(typeInfoSetter);
+ add(new HInvokeStatic(
+ <HInstruction>[typeInfoSetter, newObject, typeInfo]));
+ }
+
// Generate calls to the constructor bodies.
for (int index = constructors.length - 1; index >= 0; index--) {
FunctionElement constructor = constructors[index];
@@ -1228,6 +1250,18 @@
localsHandler.directLocals[element], element);
localsHandler.directLocals[element] = newParameter;
});
+
+ // Add the type parameters of the class as parameters of this
+ // method.
+ if (functionElement.isFactoryConstructor()
+ || functionElement.isGenerativeConstructor()) {
+ ClassElement cls = functionElement.enclosingElement;
+ cls.typeVariables.forEach((TypeVariableType typeVariable) {
+ HParameterValue param = new HParameterValue(typeVariable.element);
+ add(param);
+ localsHandler.directLocals[typeVariable.element] = param;
+ });
+ }
}
HInstruction potentiallyCheckType(HInstruction original,
@@ -2464,30 +2498,42 @@
compiler.cancel('Unimplemented non-matching static call', node: node);
}
+ TypeAnnotation annotation = getTypeAnnotationFromSend(node);
+ elements.getType(annotation).arguments.forEach((Type argument) {
+ if (argument.element.isTypeVariable()) {
kasperl 2012/08/28 09:14:15 Maybe factor this code out into a helper function.
ngeoffray 2012/08/28 10:39:45 Done.
+ if (work.element.isFactoryConstructor()) {
+ // The type variable is stored in a parameter of the
+ // factory.
+ inputs.add(localsHandler.readLocal(argument.element));
+ } else if (work.element.isInstanceMember()
+ || work.element.isGenerativeConstructor()) {
kasperl 2012/08/28 09:14:15 Aren't they also available as locals in generative
ngeoffray 2012/08/28 10:39:45 Good point. Done.
+ // The type variable is stored in [this].
+ pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(),
+ localsHandler.readThis());
+ HInstruction typeInfo = pop();
+ HInstruction foreign = new HForeign(
kasperl 2012/08/28 09:14:15 Remove extra space after =.
ngeoffray 2012/08/28 10:39:45 Done.
+ new LiteralDartString('#.$argument'),
+ new LiteralDartString('String'),
+ <HInstruction>[typeInfo]);
+ add(foreign);
+ inputs.add(foreign);
+ } else {
+ // TODO(ngeoffray): Match the VM behavior and throw an
+ // exception at runtime.
+ compiler.cancel('Unimplemented unresolved type variable', node: node);
+ }
+ } else {
+ // The type variable is a type (e.g. int).
+ inputs.add(graph.addConstantString(
+ new LiteralDartString('$argument'), node));
+ }
+ });
+
HType elementType = computeType(element);
HInstruction newInstance = new HInvokeStatic(inputs, elementType);
pushWithPosition(newInstance, node);
-
- TypeAnnotation annotation = getTypeAnnotationFromSend(node);
- Type type = elements.getType(annotation);
- generateSetRuntimeTypeInformation(newInstance, type);
}
- generateSetRuntimeTypeInformation(HInstruction instance, Type type) {
- if (compiler.codegenWorld.rti.hasTypeArguments(type)) {
- String typeString = compiler.codegenWorld.rti.asJsString(type);
- HInstruction typeInfo = new HForeign(new LiteralDartString(typeString),
- new LiteralDartString('Object'),
- <HInstruction>[]);
- add(typeInfo);
- Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo();
- HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement);
- add(typeInfoSetter);
- var inputs = <HInstruction>[typeInfoSetter, instance, typeInfo];
- add(new HInvokeStatic(inputs));
- }
- }
-
visitStaticSend(Send node) {
Selector selector = elements.getSelector(node);
Element element = elements[node];

Powered by Google App Engine
This is Rietveld 408576698