| 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 1c4f47d94d0789c989d99d01425233e144b3cde1..69de584188419b26c283747520de0ad548d0fc0d 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
|
| @@ -1813,6 +1813,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 = new HLiteralList(inputs);
|
| + add(context);
|
| + contextIsTypeArguments = true;
|
| + }
|
| + } else {
|
| + context = graph.addConstantNull(constantSystem);
|
| + }
|
| + return new HTypeConversion.withContext(type, kind, subtype,
|
| + original, context, contextIsTypeArguments: contextIsTypeArguments);
|
| } else {
|
| return original.convertType(compiler, type, kind);
|
| }
|
| @@ -1821,8 +1845,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;
|
| }
|
|
|
| @@ -2468,6 +2494,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) {
|
| @@ -2747,7 +2779,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
| }
|
| }
|
|
|
| - visitOperatorSend(node) {
|
| + visitOperatorSend(Send node) {
|
| Operator op = node.selector;
|
| if (const SourceString("[]") == op.source) {
|
| visitDynamicSend(node);
|
| @@ -2784,6 +2816,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
| HInstruction expression = pop();
|
| bool isNot = node.isIsNotCheck;
|
| DartType type = elements.getType(node.typeAnnotationFromIsCheck);
|
| + type = type.unalias(compiler);
|
| if (type.isMalformed) {
|
| String reasons = Types.fetchReasonsFromMalformedType(type);
|
| if (compiler.enableTypeAssertions) {
|
| @@ -2802,7 +2835,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, constantSystem);
|
| +
|
| + 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, constantSystem);
|
| + if (currentElement.isInstanceMember()) {
|
| + context = localsHandler.readThis();
|
| + typeArguments = graph.addConstantNull(constantSystem);
|
| + } else {
|
| + context = graph.addConstantNull(constantSystem);
|
| + List<HInstruction> inputs = <HInstruction>[];
|
| + for (Link<DartType> link = contextClass.typeVariables;
|
| + !link.isEmpty;
|
| + link = link.tail) {
|
| + inputs.add(addTypeVariableReference(link.head));
|
| + }
|
| + typeArguments = new HLiteralList(inputs);
|
| + add(typeArguments);
|
| + }
|
| + } else {
|
| + contextName = graph.addConstantNull(constantSystem);
|
| + context = graph.addConstantNull(constantSystem);
|
| + typeArguments = graph.addConstantNull(constantSystem);
|
| + }
|
| +
|
| + List<HInstruction> inputs = <HInstruction>[expression,
|
| + signatureName,
|
| + contextName,
|
| + context,
|
| + typeArguments];
|
| + pushInvokeStatic(node, checkFunctionSubtype, inputs, HType.BOOLEAN);
|
| + 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];
|
| @@ -3000,6 +3077,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()) {
|
| @@ -3111,6 +3200,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')) {
|
| @@ -3128,6 +3219,28 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
|
| 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')) {
|
| @@ -3244,17 +3357,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);
|
| HInstruction substitutionName = graph.addConstantString(
|
| new LiteralDartString(substitutionNameString), null, constantSystem);
|
| HInstruction target = localsHandler.readThis();
|
| - HInstruction substitution = createForeign('#[#]', HType.UNKNOWN,
|
| - <HInstruction>[target, substitutionName]);
|
| - add(substitution);
|
| pushInvokeStatic(null,
|
| backend.getGetRuntimeTypeArgument(),
|
| [target,
|
| - substitution,
|
| + substitutionName,
|
| graph.addConstantInt(index, constantSystem)],
|
| HType.UNKNOWN);
|
| return pop();
|
|
|