Index: dart/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart |
diff --git a/dart/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/dart/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart |
index 3916ed9bfb72ca483fc8a0b2883d07e5caf63cc3..a0388cb173adf790f46e395bd905486554cf2b46 100644 |
--- a/dart/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart |
+++ b/dart/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart |
@@ -2576,6 +2576,148 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor { |
void visitTypeKnown(HTypeKnown node) { |
use(node.checkedInput); |
} |
+ |
+ void visitFunctionType(HFunctionType node) { |
+ node.dartType.accept(new TypeBuilder(node.inputs), this); |
+ } |
+ |
+ void visitReadTypeVariable(HReadTypeVariable node) { |
+ TypeVariableElement element = node.dartType.element; |
+ Element helperElement = compiler.findHelper('convertRtiToRuntimeType'); |
+ world.registerStaticUse(helperElement); |
+ |
+ use(node.inputs[0]); |
+ if (node.hasReceiver) { |
+ if (backend.isInterceptorClass(element.getEnclosingClass())) { |
+ int index = RuntimeTypes.getTypeVariableIndex(element); |
+ js.Expression receiver = pop(); |
+ js.Expression helper = backend.namer.elementAccess(helperElement); |
+ push(helper(js.js(r'#.$builtinTypeInfo && #.$builtinTypeInfo[#]', |
+ [receiver, receiver, js.js.toExpression(index)]))); |
+ } else { |
+ backend.emitter.registerReadTypeVariable(element); |
+ push(js.js('#.${backend.namer.readTypeVariableName(element)}()', pop())); |
+ } |
+ } else { |
+ push( |
+ backend.namer.elementAccess( |
+ compiler.findHelper('convertRtiToRuntimeType'))(pop())); |
+ } |
+ } |
+} |
+ |
+class TypeBuilder implements DartTypeVisitor<dynamic, SsaCodeGenerator> { |
+ final List<HInstruction> typeVariables; |
+ int lastUsedTypeVariable = -1; |
+ |
+ TypeBuilder(this.typeVariables); |
+ |
+ HReadTypeVariable nextTypeVariable(TypeVariableType type) { |
+ HReadTypeVariable instruction = typeVariables[++lastUsedTypeVariable]; |
+ assert(instruction.dartType == type); |
+ return instruction; |
+ } |
+ |
+ void visitType(DartType type, A argument) { |
+ throw 'Internal error $type'; |
+ } |
+ |
+ void visitVoidType(VoidType type, SsaCodeGenerator generator) { |
+ generator.push(accessHelper('getVoidRuntimeType', generator)()); |
+ } |
+ |
+ void visitTypeVariableType(TypeVariableType type, |
+ SsaCodeGenerator generator) { |
+ generator.use(nextTypeVariable(type)); |
+ } |
+ |
+ void visitFunctionType(FunctionType type, SsaCodeGenerator generator) { |
+ type.returnType.accept(this, generator); |
+ js.Node returnType = generator.pop(); |
+ |
+ List<js.Expression> parameterTypes = <js.Expression>[]; |
+ for (DartType parameter in type.parameterTypes) { |
+ parameter.accept(this, generator); |
+ parameterTypes.add(generator.pop()); |
+ } |
+ |
+ List<js.Expression> optionalParameterTypes = <js.Expression>[]; |
+ for (DartType parameter in type.optionalParameterTypes) { |
+ parameter.accept(this, generator); |
+ optionalParameterTypes.add(generator.pop()); |
+ } |
+ |
+ Link<DartType> namedParameterTypes = type.namedParameterTypes; |
+ List<js.Property> namedParameters = <js.Property>[]; |
+ for (String name in type.namedParameters) { |
+ namedParameterTypes.head.accept(this, generator); |
+ namedParameters.add(new js.Property(js.string(name), generator.pop())); |
+ namedParameterTypes = namedParameterTypes.tail; |
+ } |
+ |
+ if (namedParameters.isEmpty) { |
+ var arguments = [ |
+ returnType, |
+ new js.ArrayInitializer.from(parameterTypes)]; |
+ if (!optionalParameterTypes.isEmpty) { |
+ arguments.add(optionalParameterTypes); |
+ } |
+ generator.push(accessHelper('buildFunctionType', generator)(arguments)); |
+ } else { |
+ var arguments = [ |
+ returnType, |
+ new js.ArrayInitializer.from(parameterTypes), |
+ new js.ObjectInitializer(namedParameters)]; |
+ generator.push( |
+ accessHelper('buildNamedFunctionType', generator)(arguments)); |
+ } |
+ } |
+ |
+ void visitMalformedType(MalformedType type, SsaCodeGenerator generator) { |
+ // TODO(ahe): Discard type variables. |
+ generator.push(accessHelper('getDynamicRuntimeType', generator)()); |
+ } |
+ |
+ void visitStatementType(StatementType type, SsaCodeGenerator generator) { |
+ throw 'not implemented visitStatementType($type)'; |
+ } |
+ |
+ void visitGenericType(GenericType type, SsaCodeGenerator generator) { |
+ throw 'not implemented visitGenericType($type)'; |
+ } |
+ |
+ void visitInterfaceType(InterfaceType type, SsaCodeGenerator generator) { |
+ List<js.Expression> typeArguments = <js.Expression>[]; |
+ for (DartType typeArgument in type.typeArguments) { |
+ typeArgument.accept(this, generator); |
+ typeArguments.add(generator.pop()); |
+ } |
+ |
+ final JavaScriptBackend backend = generator.backend; |
+ final Namer namer = backend.namer; |
+ |
+ var arguments = [ |
+ namer.elementAccess(backend.getImplementationClass(type.element)), |
+ new js.ArrayInitializer.from(typeArguments)]; |
+ generator.push(accessHelper('buildInterfaceType', generator)(arguments)); |
+ } |
+ |
+ void visitTypedefType(TypedefType type, SsaCodeGenerator generator) { |
+ // TODO(ahe): This doesn't work for type variables. |
+ DartType unaliased = type.unalias(generator.compiler); |
+ if (unaliased is TypedefType) throw 'unable to unalias $type'; |
+ unaliased.accept(this, generator); |
+ } |
+ |
+ void visitDynamicType(DynamicType type, SsaCodeGenerator generator) { |
+ generator.push(accessHelper('getDynamicRuntimeType', generator)()); |
+ } |
+ |
+ js.PropertyAccess accessHelper(String name, SsaCodeGenerator generator) { |
+ Element helper = generator.compiler.findHelper(name); |
+ generator.world.registerStaticUse(helper); |
+ return generator.backend.namer.elementAccess(helper); |
+ } |
} |
String singleIdentityComparison(HInstruction left, |