Chromium Code Reviews| 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 1cd2255ddc3b30cfbbc2a6efd1319821010383c1..f5c347a79760fe7b422c79b8a16507b43fa127ee 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| @@ -1783,6 +1783,30 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| HInstruction typeVariable = addTypeVariableReference(type); |
| return new HTypeConversion.withTypeRepresentation(type, kind, subtype, |
| original, typeVariable); |
| + } else if (type.kind == TypeKind.FUNCTION) { |
| + HType subtype = original.instructionType; |
| + bool contextIsTypeArguments = false; |
| + HInstruction context; |
| + if (type.containsTypeVariables) { |
| + if (currentElement.isInstanceMember()) { |
| + context = localsHandler.readThis(); |
| + } else { |
| + ClassElement contextClass = Types.getClassContext(type); |
| + List<HInstruction> inputs = <HInstruction>[]; |
| + for (Link<DartType> link = contextClass.typeVariables; |
| + !link.isEmpty; |
| + link = link.tail) { |
| + inputs.add(addTypeVariableReference(link.head)); |
| + } |
| + context = buildLiteralList(inputs); |
| + add(context); |
| + contextIsTypeArguments = true; |
| + } |
| + } else { |
| + context = graph.addConstantNull(compiler); |
| + } |
| + return new HTypeConversion.withContext(type, kind, subtype, |
|
karlklose
2013/06/20 07:32:55
I'd rather not create a new conversion withContext
Johnni Winther
2013/06/21 12:19:15
Done.
|
| + original, context, contextIsTypeArguments: contextIsTypeArguments); |
| } else { |
| return original.convertType(compiler, type, kind); |
| } |
| @@ -1791,8 +1815,10 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| HInstruction potentiallyCheckType(HInstruction original, DartType type, |
| { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { |
| if (!compiler.enableTypeAssertions) return original; |
| + type = type.unalias(compiler); |
| HInstruction other = buildTypeConversion(original, type, kind); |
| if (other != original) add(other); |
| + compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree); |
| return other; |
| } |
| @@ -2438,6 +2464,12 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| compiler.functionClass.computeType(compiler), |
| compiler); |
| push(new HForeignNew(closureClassElement, type, capturedVariables)); |
| + |
| + Element methodElement = nestedClosureData.closureElement; |
| + if (compiler.backend.methodNeedsRti(methodElement)) { |
| + compiler.backend.registerGenericClosure( |
| + methodElement, compiler.enqueuer.codegen, work.resolutionTree); |
| + } |
| } |
| visitFunctionDeclaration(FunctionDeclaration node) { |
| @@ -2721,7 +2753,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| } |
| } |
| - visitOperatorSend(node) { |
| + visitOperatorSend(Send node) { |
| Operator op = node.selector; |
| if (const SourceString("[]") == op.source) { |
| visitDynamicSend(node); |
| @@ -2740,6 +2772,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| Node argument = node.arguments.head; |
| TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); |
| DartType type = elements.getType(typeAnnotation); |
| + type = type.unalias(compiler); |
|
karlklose
2013/06/20 07:32:55
Move to buildTypeConversion?
Johnni Winther
2013/06/21 12:19:15
Done.
|
| HInstruction converted = buildTypeConversion( |
| expression, type, HTypeConversion.CAST_TYPE_CHECK); |
| if (converted != expression) add(converted); |
| @@ -2758,6 +2791,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| HInstruction expression = pop(); |
| bool isNot = node.isIsNotCheck; |
| DartType type = elements.getType(node.typeAnnotationFromIsCheck); |
| + type = type.unalias(compiler); |
|
karlklose
2013/06/20 07:32:55
Move to buildIsNode? isMalformed on an unaliased t
Johnni Winther
2013/06/21 12:19:15
Currently we can't. And this will be removed when
|
| if (type.isMalformed) { |
| String reasons = Types.fetchReasonsFromMalformedType(type); |
| if (compiler.enableTypeAssertions) { |
| @@ -2776,7 +2810,51 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| } |
| HInstruction buildIsNode(Node node, DartType type, HInstruction expression) { |
| - if (type.kind == TypeKind.TYPE_VARIABLE) { |
| + if (type.kind == TypeKind.FUNCTION) { |
| + Element checkFunctionSubtype = backend.getCheckFunctionSubtype(); |
| + |
| + HInstruction signatureName = graph.addConstantString( |
| + new DartString.literal(backend.namer.getFunctionTypeName(type)), |
| + node, compiler); |
| + |
| + HInstruction contextName; |
| + HInstruction context; |
| + HInstruction typeArguments; |
| + if (type.containsTypeVariables) { |
| + ClassElement contextClass = Types.getClassContext(type); |
| + contextName = graph.addConstantString( |
| + new DartString.literal(backend.namer.getName(contextClass)), |
| + node, compiler); |
| + if (currentElement.isInstanceMember()) { |
| + context = localsHandler.readThis(); |
| + typeArguments = graph.addConstantNull(compiler); |
| + } else { |
| + context = graph.addConstantNull(compiler); |
|
karlklose
2013/06/20 07:32:55
This code (and the else-branch) could be shared wi
Johnni Winther
2013/06/21 12:19:15
Added a buildTypeVariableList method used by both
|
| + List<HInstruction> inputs = <HInstruction>[]; |
| + for (Link<DartType> link = contextClass.typeVariables; |
| + !link.isEmpty; |
| + link = link.tail) { |
| + inputs.add(addTypeVariableReference(link.head)); |
| + } |
| + typeArguments = buildLiteralList(inputs); |
| + add(typeArguments); |
| + } |
| + } else { |
| + contextName = graph.addConstantNull(compiler); |
| + context = graph.addConstantNull(compiler); |
| + typeArguments = graph.addConstantNull(compiler); |
| + } |
| + |
| + List<HInstruction> inputs = <HInstruction>[expression, |
| + signatureName, |
| + contextName, |
| + context, |
| + typeArguments]; |
| + pushInvokeStatic(node, checkFunctionSubtype, inputs, HType.BOOLEAN); |
|
karlklose
2013/06/20 07:32:55
Could you move this to the codegen by creating a n
Johnni Winther
2013/06/21 12:19:15
The generation is already handle in codegen. We ju
|
| + HInstruction call = pop(); |
| + return new HIs(type, <HInstruction>[expression, call], |
| + HIs.COMPOUND_CHECK); |
| + } else if (type.kind == TypeKind.TYPE_VARIABLE) { |
| HInstruction runtimeType = addTypeVariableReference(type); |
| Element helper = backend.getCheckSubtypeOfRuntimeType(); |
| List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; |
| @@ -2974,6 +3052,18 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| } |
| } |
| + void handleForeignJsSetupObject(Send node) { |
| + if (!node.arguments.isEmpty) { |
| + compiler.cancel( |
| + 'Too many arguments to JS_SETUP_OBJECT', node: node); |
| + } |
| + |
| + String name = backend.namer.SETUP_OBJECT; |
| + push(new HForeign(new js.LiteralString(name), |
| + HType.UNKNOWN, |
| + <HInstruction>[])); |
| + } |
| + |
| void handleForeignJsCallInIsolate(Send node) { |
| Link<Node> link = node.arguments; |
| if (!compiler.hasIsolateSupport()) { |
| @@ -3085,6 +3175,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| handleForeignJs(node); |
| } else if (name == const SourceString('JS_CURRENT_ISOLATE_CONTEXT')) { |
| handleForeignJsCurrentIsolateContext(node); |
| + } else if (name == const SourceString('JS_SETUP_OBJECT')) { |
| + handleForeignJsSetupObject(node); |
| } else if (name == const SourceString('JS_CALL_IN_ISOLATE')) { |
| handleForeignJsCallInIsolate(node); |
| } else if (name == const SourceString('DART_CLOSURE_TO_JS')) { |
| @@ -3100,8 +3192,33 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| } else if (name == const SourceString('JS_OBJECT_CLASS_NAME')) { |
| String name = backend.namer.getRuntimeTypeName(compiler.objectClass); |
| stack.add(addConstantString(node, name)); |
| + } else if (name == const SourceString('JS_FUNCTION_CLASS_NAME')) { |
| + String name = backend.namer.getRuntimeTypeName(compiler.functionClass); |
| + stack.add(addConstantString(node, name)); |
| } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) { |
| stack.add(addConstantString(node, backend.namer.operatorAsPrefix())); |
| + } else if (name == const SourceString('JS_SIGNATURE_NAME')) { |
| + stack.add(addConstantString(node, backend.namer.operatorSignature())); |
| + } else if (name == const SourceString('JS_FUNCTION_TYPE_TAG')) { |
| + stack.add(addConstantString(node, backend.namer.functionTypeTag())); |
| + } else if (name == const SourceString('JS_FUNCTION_TYPE_VOID_RETURN_TAG')) { |
| + stack.add(addConstantString(node, |
| + backend.namer.functionTypeVoidReturnTag())); |
| + } else if (name == const SourceString('JS_FUNCTION_TYPE_RETURN_TYPE_TAG')) { |
| + stack.add(addConstantString(node, |
| + backend.namer.functionTypeReturnTypeTag())); |
| + } else if (name == |
| + const SourceString('JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG')) { |
| + stack.add(addConstantString(node, |
| + backend.namer.functionTypeRequiredParametersTag())); |
| + } else if (name == |
| + const SourceString('JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG')) { |
| + stack.add(addConstantString(node, |
| + backend.namer.functionTypeOptionalParametersTag())); |
| + } else if (name == |
| + const SourceString('JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG')) { |
| + stack.add(addConstantString(node, |
| + backend.namer.functionTypeNamedParametersTag())); |
| } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) { |
| handleForeignDartObjectJsConstructorFunction(node); |
| } else if (name == const SourceString('JS_IS_INDEXABLE_FIELD_NAME')) { |
| @@ -3218,17 +3335,14 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| TypeVariableElement variable) { |
| assert(currentElement.isInstanceMember()); |
| int index = RuntimeTypes.getTypeVariableIndex(variable); |
| - String substitutionNameString = backend.namer.substitutionName(cls); |
| + String substitutionNameString = backend.namer.getName(cls); |
|
karlklose
2013/06/20 07:32:55
How does this work? substitutionName contains the
Johnni Winther
2013/06/21 12:19:15
getRuntimeTypeArgument has been changed to take th
|
| HInstruction substitutionName = graph.addConstantString( |
| new LiteralDartString(substitutionNameString), null, compiler); |
| HInstruction target = localsHandler.readThis(); |
| - HInstruction substitution = createForeign('#[#]', HType.UNKNOWN, |
| - <HInstruction>[target, substitutionName]); |
| - add(substitution); |
| pushInvokeStatic(null, |
| backend.getGetRuntimeTypeArgument(), |
| [target, |
| - substitution, |
| + substitutionName, |
| graph.addConstantInt(index, compiler)], |
| HType.UNKNOWN); |
| return pop(); |