Index: pkg/compiler/lib/src/ssa/codegen.dart |
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart |
index e9614853658473233443fdc8f25397576fa15e8c..c23534849e2db61af309843f148fede61c7b15c5 100644 |
--- a/pkg/compiler/lib/src/ssa/codegen.dart |
+++ b/pkg/compiler/lib/src/ssa/codegen.dart |
@@ -2855,6 +2855,75 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor { |
} |
} |
+ void visitTypeInfoReadRaw(HTypeInfoReadRaw node) { |
+ use(node.inputs[0]); |
+ js.Expression receiver = pop(); |
+ push(js.js(r'#.$builtinTypeInfo', receiver)); |
+ } |
+ |
+ void visitTypeInfoReadVariable(HTypeInfoReadVariable node) { |
+ TypeVariableElement element = node.variable.element; |
+ ClassElement context = element.enclosingClass; |
+ |
+ int index = element.index; |
+ use(node.inputs[0]); |
+ js.Expression receiver = pop(); |
+ |
+ if (needsSubstitutionForTypeVariableAccess(context)) { |
+ js.Expression typeName = |
+ js.quoteName(backend.namer.runtimeTypeName(context)); |
+ Element helperElement = helpers.getRuntimeTypeArgument; |
+ registry.registerStaticUse( |
+ new StaticUse.staticInvoke(helperElement, CallStructure.THREE_ARGS)); |
+ js.Expression helper = |
+ backend.emitter.staticFunctionAccess(helperElement); |
+ push(js.js( |
+ r'#(#, #, #)', [helper, receiver, typeName, js.js.number(index)])); |
+ } else { |
+ Element helperElement = helpers.getTypeArgumentByIndex; |
+ registry.registerStaticUse( |
+ new StaticUse.staticInvoke(helperElement, CallStructure.TWO_ARGS)); |
+ js.Expression helper = |
+ backend.emitter.staticFunctionAccess(helperElement); |
+ push(js.js(r'#(#, #)', [helper, receiver, js.js.number(index)])); |
+ } |
+ } |
+ |
+ void visitTypeInfoExpression(HTypeInfoExpression node) { |
+ List<js.Expression> arguments = <js.Expression>[]; |
+ for (HInstruction input in node.inputs) { |
+ use(input); |
+ arguments.add(pop()); |
+ } |
+ |
+ switch (node.kind) { |
+ case TypeInfoExpressionKind.COMPLETE: |
+ int index = 0; |
+ js.Expression result = backend.rtiEncoder.getTypeRepresentation( |
+ node.dartType, (TypeVariableType variable) => arguments[index++]); |
+ assert(index == node.inputs.length); |
+ push(result); |
+ return; |
+ |
+ case TypeInfoExpressionKind.INSTANCE: |
+ // We expect only flat types for the INSTANCE representation. |
+ assert( |
+ node.dartType == (node.dartType.element as ClassElement).thisType); |
+ registry.registerInstantiatedClass(coreClasses.listClass); |
+ push(new js.ArrayInitializer(arguments) |
+ .withSourceInformation(node.sourceInformation)); |
+ } |
+ } |
+ |
+ bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { |
+ ClassWorld classWorld = compiler.world; |
+ if (classWorld.isUsedAsMixin(cls)) return true; |
+ |
+ return compiler.world.anyStrictSubclassOf(cls, (ClassElement subclass) { |
+ return !backend.rti.isTrivialSubstitution(subclass, cls); |
+ }); |
+ } |
+ |
void visitReadTypeVariable(HReadTypeVariable node) { |
TypeVariableElement element = node.dartType.element; |
Element helperElement = helpers.convertRtiToRuntimeType; |