Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
index 95197e6455a29af55fe454e89a8bfb1f54c22fcf..87e2b591a964041fde1c0ec60129582475f7cfa6 100644 |
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
@@ -2248,7 +2248,34 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
HType type = new HType.nonNullExact( |
compiler.functionClass.computeType(compiler), |
compiler); |
- push(new HForeignNew(closureClassElement, type, capturedVariables)); |
+ HInstruction newClosure = |
+ new HForeignNew(closureClassElement, type, capturedVariables); |
+ ClassElement thisClass = work.element.getEnclosingClass(); |
ngeoffray
2013/03/13 09:30:46
thisClass can be null right? Don't you need to che
Johnni Winther
2013/03/22 07:30:24
Stale
|
+ if (compiler.world.needsRti(thisClass) && |
+ callElement.computeType(compiler).containsTypeVariables) { |
+ add(newClosure); |
+ |
+ Element forwardRuntimeTypeInfo = backend.getForwardRuntimeTypeInfo(); |
+ HInstruction forwardRuntimeTypeInfoCall = |
+ new HStatic(forwardRuntimeTypeInfo); |
+ add(forwardRuntimeTypeInfoCall); |
+ |
+ String substitutionName = backend.namer.substitutionName(thisClass); |
+ HInstruction substitution = |
+ createForeign('this.$substitutionName', HType.UNKNOWN, []); |
ngeoffray
2013/03/13 09:30:46
Change "this" to use #.
Johnni Winther
2013/03/22 07:30:24
Stale
|
+ add(substitution); |
+ |
+ HInstruction context = new HThis(thisClass, HType.UNKNOWN); |
+ add(context); |
+ |
+ List<HInstruction> inputs = <HInstruction>[forwardRuntimeTypeInfoCall, |
+ newClosure, |
+ substitution, |
+ context]; |
+ push(new HInvokeStatic(inputs, HType.UNKNOWN)); |
+ } else { |
+ push(newClosure); |
+ } |
} |
visitFunctionDeclaration(FunctionDeclaration node) { |
@@ -2645,6 +2672,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
isNot = true; |
} |
DartType type = elements.getType(typeAnnotation); |
+ type = type.unalias(compiler); |
if (type.isMalformed) { |
String reasons = Types.fetchReasonsFromMalformedType(type); |
if (compiler.enableTypeAssertions) { |
@@ -2656,7 +2684,43 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
} |
HInstruction instruction; |
- if (type.kind == TypeKind.TYPE_VARIABLE) { |
+ if (type is FunctionType) { |
ngeoffray
2013/03/13 09:30:46
Use the kind instead?
Johnni Winther
2013/03/22 07:30:24
Done.
|
+ compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree); |
ngeoffray
2013/03/13 09:30:46
Add a TODO that this should be done in codegen.
Johnni Winther
2013/06/21 12:19:14
Stale.
|
+ |
+ void functionTypeCheck() { |
+ Element checkFunctionSubtype = backend.getCheckFunctionSubtype(); |
+ HInstruction isFuncSubtypeCall = new HStatic(checkFunctionSubtype); |
+ add(isFuncSubtypeCall); |
+ |
+ String typeSignatureName; |
+ HInstruction context; |
+ ClassElement contextClass = Types.getClassContext(type); |
ngeoffray
2013/03/13 09:30:46
What is this?
Johnni Winther
2013/03/22 07:30:24
The class which declared the used type variables,
|
+ if (contextClass != null) { |
+ typeSignatureName = backend.namer.signatureName(type); |
+ context = new HThis(contextClass, HType.UNKNOWN); |
ngeoffray
2013/03/13 09:30:46
What's this HThis? Why isn't it the one of the bui
Johnni Winther
2013/03/22 07:30:24
Changed.
|
+ add(context); |
+ } else { |
+ typeSignatureName = backend.namer.signatureName(type); |
+ context = graph.addConstantNull(constantSystem); |
+ } |
+ HInstruction typeSignature = |
+ createForeign('$typeSignatureName', HType.UNKNOWN, []); |
+ add(typeSignature); |
+ |
+ List<HInstruction> inputs = <HInstruction>[isFuncSubtypeCall, |
+ expression, |
+ typeSignature, |
+ context]; |
+ push(new HInvokeStatic(inputs, HType.UNKNOWN)); |
+ } |
+ |
+ void classCheck() { push(new HIs(type, <HInstruction>[expression])); } |
+ |
+ SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); |
+ branchBuilder.handleLogicalAndOr( |
+ classCheck, functionTypeCheck, isAnd: true); |
+ instruction = pop(); |
+ } else if (type.kind == TypeKind.TYPE_VARIABLE) { |
HInstruction runtimeType = addTypeVariableReference(type); |
Element helper = backend.getGetObjectIsSubtype(); |
HInstruction helperCall = new HStatic(helper); |