| 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();
 | 
| 
 |