Chromium Code Reviews| 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..957b56a3df4c9a5faac72abd15e7e6d680c2d670 100644 |
| --- a/dart/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart |
| +++ b/dart/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart |
| @@ -2576,6 +2576,139 @@ 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; |
| + world.registerStaticUse(compiler.findHelper('convertRtiToRuntimeType')); |
| + |
| + use(node.inputs[0]); |
| + if (node.hasReceiver) { |
| + 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> { |
|
ngeoffray
2013/11/01 13:54:02
Doing this at codegen time prevents doing all pote
ahe
2013/11/04 17:23:45
That is a good point. We talked about this earlier
|
| + 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) { |
|
Johnni Winther
2013/10/30 12:02:19
'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, |