Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 12334070: Support runtime check of function types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix status files Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of ssa; 5 part of ssa;
6 6
7 /** 7 /**
8 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to override [Element.computeType] because our 9 * methods. We need to override [Element.computeType] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 1765 matching lines...) Expand 10 before | Expand all | Expand 10 after
1776 HType subtype = new HType.subtype(type, compiler); 1776 HType subtype = new HType.subtype(type, compiler);
1777 HInstruction representations = buildTypeArgumentRepresentations(type); 1777 HInstruction representations = buildTypeArgumentRepresentations(type);
1778 add(representations); 1778 add(representations);
1779 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, 1779 return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
1780 original, representations); 1780 original, representations);
1781 } else if (type.kind == TypeKind.TYPE_VARIABLE) { 1781 } else if (type.kind == TypeKind.TYPE_VARIABLE) {
1782 HType subtype = original.instructionType; 1782 HType subtype = original.instructionType;
1783 HInstruction typeVariable = addTypeVariableReference(type); 1783 HInstruction typeVariable = addTypeVariableReference(type);
1784 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, 1784 return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
1785 original, typeVariable); 1785 original, typeVariable);
1786 } else if (type.kind == TypeKind.FUNCTION) {
1787 HType subtype = original.instructionType;
1788 bool contextIsTypeArguments = false;
1789 HInstruction context;
1790 if (type.containsTypeVariables) {
1791 if (currentElement.isInstanceMember()) {
1792 context = localsHandler.readThis();
1793 } else {
1794 ClassElement contextClass = Types.getClassContext(type);
1795 List<HInstruction> inputs = <HInstruction>[];
1796 for (Link<DartType> link = contextClass.typeVariables;
1797 !link.isEmpty;
1798 link = link.tail) {
1799 inputs.add(addTypeVariableReference(link.head));
1800 }
1801 context = buildLiteralList(inputs);
1802 add(context);
1803 contextIsTypeArguments = true;
1804 }
1805 } else {
1806 context = graph.addConstantNull(compiler);
1807 }
1808 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.
1809 original, context, contextIsTypeArguments: contextIsTypeArguments);
1786 } else { 1810 } else {
1787 return original.convertType(compiler, type, kind); 1811 return original.convertType(compiler, type, kind);
1788 } 1812 }
1789 } 1813 }
1790 1814
1791 HInstruction potentiallyCheckType(HInstruction original, DartType type, 1815 HInstruction potentiallyCheckType(HInstruction original, DartType type,
1792 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { 1816 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
1793 if (!compiler.enableTypeAssertions) return original; 1817 if (!compiler.enableTypeAssertions) return original;
1818 type = type.unalias(compiler);
1794 HInstruction other = buildTypeConversion(original, type, kind); 1819 HInstruction other = buildTypeConversion(original, type, kind);
1795 if (other != original) add(other); 1820 if (other != original) add(other);
1821 compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree);
1796 return other; 1822 return other;
1797 } 1823 }
1798 1824
1799 HGraph closeFunction() { 1825 HGraph closeFunction() {
1800 // TODO(kasperl): Make this goto an implicit return. 1826 // TODO(kasperl): Make this goto an implicit return.
1801 if (!isAborted()) closeAndGotoExit(new HGoto()); 1827 if (!isAborted()) closeAndGotoExit(new HGoto());
1802 graph.finalize(); 1828 graph.finalize();
1803 return graph; 1829 return graph;
1804 } 1830 }
1805 1831
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
2431 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; 2457 Element capturedLocal = nestedClosureData.capturedFieldMapping[member];
2432 assert(capturedLocal != null); 2458 assert(capturedLocal != null);
2433 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 2459 capturedVariables.add(localsHandler.readLocal(capturedLocal));
2434 } 2460 }
2435 }); 2461 });
2436 2462
2437 HType type = new HType.nonNullExact( 2463 HType type = new HType.nonNullExact(
2438 compiler.functionClass.computeType(compiler), 2464 compiler.functionClass.computeType(compiler),
2439 compiler); 2465 compiler);
2440 push(new HForeignNew(closureClassElement, type, capturedVariables)); 2466 push(new HForeignNew(closureClassElement, type, capturedVariables));
2467
2468 Element methodElement = nestedClosureData.closureElement;
2469 if (compiler.backend.methodNeedsRti(methodElement)) {
2470 compiler.backend.registerGenericClosure(
2471 methodElement, compiler.enqueuer.codegen, work.resolutionTree);
2472 }
2441 } 2473 }
2442 2474
2443 visitFunctionDeclaration(FunctionDeclaration node) { 2475 visitFunctionDeclaration(FunctionDeclaration node) {
2444 assert(isReachable); 2476 assert(isReachable);
2445 visit(node.function); 2477 visit(node.function);
2446 localsHandler.updateLocal(elements[node], pop()); 2478 localsHandler.updateLocal(elements[node], pop());
2447 } 2479 }
2448 2480
2449 visitIdentifier(Identifier node) { 2481 visitIdentifier(Identifier node) {
2450 if (node.isThis()) { 2482 if (node.isThis()) {
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
2714 inputs.add(runtimeType); 2746 inputs.add(runtimeType);
2715 })); 2747 }));
2716 } 2748 }
2717 String template = '[${templates.join(', ')}]'; 2749 String template = '[${templates.join(', ')}]';
2718 HInstruction representation = 2750 HInstruction representation =
2719 createForeign(template, backend.readableArrayType, inputs); 2751 createForeign(template, backend.readableArrayType, inputs);
2720 return representation; 2752 return representation;
2721 } 2753 }
2722 } 2754 }
2723 2755
2724 visitOperatorSend(node) { 2756 visitOperatorSend(Send node) {
2725 Operator op = node.selector; 2757 Operator op = node.selector;
2726 if (const SourceString("[]") == op.source) { 2758 if (const SourceString("[]") == op.source) {
2727 visitDynamicSend(node); 2759 visitDynamicSend(node);
2728 } else if (const SourceString("&&") == op.source || 2760 } else if (const SourceString("&&") == op.source ||
2729 const SourceString("||") == op.source) { 2761 const SourceString("||") == op.source) {
2730 visitLogicalAndOr(node, op); 2762 visitLogicalAndOr(node, op);
2731 } else if (const SourceString("!") == op.source) { 2763 } else if (const SourceString("!") == op.source) {
2732 visitLogicalNot(node); 2764 visitLogicalNot(node);
2733 } else if (node.argumentsNode is Prefix) { 2765 } else if (node.argumentsNode is Prefix) {
2734 visitUnary(node, op); 2766 visitUnary(node, op);
2735 } else if (const SourceString("is") == op.source) { 2767 } else if (const SourceString("is") == op.source) {
2736 visitIsSend(node); 2768 visitIsSend(node);
2737 } else if (const SourceString("as") == op.source) { 2769 } else if (const SourceString("as") == op.source) {
2738 visit(node.receiver); 2770 visit(node.receiver);
2739 HInstruction expression = pop(); 2771 HInstruction expression = pop();
2740 Node argument = node.arguments.head; 2772 Node argument = node.arguments.head;
2741 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); 2773 TypeAnnotation typeAnnotation = argument.asTypeAnnotation();
2742 DartType type = elements.getType(typeAnnotation); 2774 DartType type = elements.getType(typeAnnotation);
2775 type = type.unalias(compiler);
karlklose 2013/06/20 07:32:55 Move to buildTypeConversion?
Johnni Winther 2013/06/21 12:19:15 Done.
2743 HInstruction converted = buildTypeConversion( 2776 HInstruction converted = buildTypeConversion(
2744 expression, type, HTypeConversion.CAST_TYPE_CHECK); 2777 expression, type, HTypeConversion.CAST_TYPE_CHECK);
2745 if (converted != expression) add(converted); 2778 if (converted != expression) add(converted);
2746 stack.add(converted); 2779 stack.add(converted);
2747 } else { 2780 } else {
2748 visit(node.receiver); 2781 visit(node.receiver);
2749 visit(node.argumentsNode); 2782 visit(node.argumentsNode);
2750 var right = pop(); 2783 var right = pop();
2751 var left = pop(); 2784 var left = pop();
2752 visitBinary(left, op, right, elements.getSelector(node), node); 2785 visitBinary(left, op, right, elements.getSelector(node), node);
2753 } 2786 }
2754 } 2787 }
2755 2788
2756 void visitIsSend(Send node) { 2789 void visitIsSend(Send node) {
2757 visit(node.receiver); 2790 visit(node.receiver);
2758 HInstruction expression = pop(); 2791 HInstruction expression = pop();
2759 bool isNot = node.isIsNotCheck; 2792 bool isNot = node.isIsNotCheck;
2760 DartType type = elements.getType(node.typeAnnotationFromIsCheck); 2793 DartType type = elements.getType(node.typeAnnotationFromIsCheck);
2794 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
2761 if (type.isMalformed) { 2795 if (type.isMalformed) {
2762 String reasons = Types.fetchReasonsFromMalformedType(type); 2796 String reasons = Types.fetchReasonsFromMalformedType(type);
2763 if (compiler.enableTypeAssertions) { 2797 if (compiler.enableTypeAssertions) {
2764 generateMalformedSubtypeError(node, expression, type, reasons); 2798 generateMalformedSubtypeError(node, expression, type, reasons);
2765 } else { 2799 } else {
2766 generateRuntimeError(node, '$type is malformed: $reasons'); 2800 generateRuntimeError(node, '$type is malformed: $reasons');
2767 } 2801 }
2768 } else { 2802 } else {
2769 HInstruction instruction = buildIsNode(node, type, expression); 2803 HInstruction instruction = buildIsNode(node, type, expression);
2770 if (isNot) { 2804 if (isNot) {
2771 add(instruction); 2805 add(instruction);
2772 instruction = new HNot(instruction); 2806 instruction = new HNot(instruction);
2773 } 2807 }
2774 push(instruction); 2808 push(instruction);
2775 } 2809 }
2776 } 2810 }
2777 2811
2778 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) { 2812 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) {
2779 if (type.kind == TypeKind.TYPE_VARIABLE) { 2813 if (type.kind == TypeKind.FUNCTION) {
2814 Element checkFunctionSubtype = backend.getCheckFunctionSubtype();
2815
2816 HInstruction signatureName = graph.addConstantString(
2817 new DartString.literal(backend.namer.getFunctionTypeName(type)),
2818 node, compiler);
2819
2820 HInstruction contextName;
2821 HInstruction context;
2822 HInstruction typeArguments;
2823 if (type.containsTypeVariables) {
2824 ClassElement contextClass = Types.getClassContext(type);
2825 contextName = graph.addConstantString(
2826 new DartString.literal(backend.namer.getName(contextClass)),
2827 node, compiler);
2828 if (currentElement.isInstanceMember()) {
2829 context = localsHandler.readThis();
2830 typeArguments = graph.addConstantNull(compiler);
2831 } else {
2832 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
2833 List<HInstruction> inputs = <HInstruction>[];
2834 for (Link<DartType> link = contextClass.typeVariables;
2835 !link.isEmpty;
2836 link = link.tail) {
2837 inputs.add(addTypeVariableReference(link.head));
2838 }
2839 typeArguments = buildLiteralList(inputs);
2840 add(typeArguments);
2841 }
2842 } else {
2843 contextName = graph.addConstantNull(compiler);
2844 context = graph.addConstantNull(compiler);
2845 typeArguments = graph.addConstantNull(compiler);
2846 }
2847
2848 List<HInstruction> inputs = <HInstruction>[expression,
2849 signatureName,
2850 contextName,
2851 context,
2852 typeArguments];
2853 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
2854 HInstruction call = pop();
2855 return new HIs(type, <HInstruction>[expression, call],
2856 HIs.COMPOUND_CHECK);
2857 } else if (type.kind == TypeKind.TYPE_VARIABLE) {
2780 HInstruction runtimeType = addTypeVariableReference(type); 2858 HInstruction runtimeType = addTypeVariableReference(type);
2781 Element helper = backend.getCheckSubtypeOfRuntimeType(); 2859 Element helper = backend.getCheckSubtypeOfRuntimeType();
2782 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; 2860 List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
2783 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN); 2861 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN);
2784 HInstruction call = pop(); 2862 HInstruction call = pop();
2785 return new HIs(type, <HInstruction>[expression, call], 2863 return new HIs(type, <HInstruction>[expression, call],
2786 HIs.VARIABLE_CHECK); 2864 HIs.VARIABLE_CHECK);
2787 } else if (RuntimeTypes.hasTypeArguments(type)) { 2865 } else if (RuntimeTypes.hasTypeArguments(type)) {
2788 ClassElement element = type.element; 2866 ClassElement element = type.element;
2789 Element helper = backend.getCheckSubtype(); 2867 Element helper = backend.getCheckSubtype();
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
2967 Element element = compiler.isolateHelperLibrary.find( 3045 Element element = compiler.isolateHelperLibrary.find(
2968 const SourceString('_currentIsolate')); 3046 const SourceString('_currentIsolate'));
2969 if (element == null) { 3047 if (element == null) {
2970 compiler.cancel( 3048 compiler.cancel(
2971 'Isolate library and compiler mismatch', node: node); 3049 'Isolate library and compiler mismatch', node: node);
2972 } 3050 }
2973 pushInvokeStatic(null, element, [], HType.UNKNOWN); 3051 pushInvokeStatic(null, element, [], HType.UNKNOWN);
2974 } 3052 }
2975 } 3053 }
2976 3054
3055 void handleForeignJsSetupObject(Send node) {
3056 if (!node.arguments.isEmpty) {
3057 compiler.cancel(
3058 'Too many arguments to JS_SETUP_OBJECT', node: node);
3059 }
3060
3061 String name = backend.namer.SETUP_OBJECT;
3062 push(new HForeign(new js.LiteralString(name),
3063 HType.UNKNOWN,
3064 <HInstruction>[]));
3065 }
3066
2977 void handleForeignJsCallInIsolate(Send node) { 3067 void handleForeignJsCallInIsolate(Send node) {
2978 Link<Node> link = node.arguments; 3068 Link<Node> link = node.arguments;
2979 if (!compiler.hasIsolateSupport()) { 3069 if (!compiler.hasIsolateSupport()) {
2980 // If the isolate library is not used, we just invoke the 3070 // If the isolate library is not used, we just invoke the
2981 // closure. 3071 // closure.
2982 visit(link.tail.head); 3072 visit(link.tail.head);
2983 Selector selector = new Selector.callClosure(0); 3073 Selector selector = new Selector.callClosure(0);
2984 push(new HInvokeClosure(selector, <HInstruction>[pop()])); 3074 push(new HInvokeClosure(selector, <HInstruction>[pop()]));
2985 } else { 3075 } else {
2986 // Call a helper method from the isolate library. 3076 // Call a helper method from the isolate library.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
3078 <HInstruction>[])); 3168 <HInstruction>[]));
3079 } 3169 }
3080 3170
3081 visitForeignSend(Send node) { 3171 visitForeignSend(Send node) {
3082 Selector selector = elements.getSelector(node); 3172 Selector selector = elements.getSelector(node);
3083 SourceString name = selector.name; 3173 SourceString name = selector.name;
3084 if (name == const SourceString('JS')) { 3174 if (name == const SourceString('JS')) {
3085 handleForeignJs(node); 3175 handleForeignJs(node);
3086 } else if (name == const SourceString('JS_CURRENT_ISOLATE_CONTEXT')) { 3176 } else if (name == const SourceString('JS_CURRENT_ISOLATE_CONTEXT')) {
3087 handleForeignJsCurrentIsolateContext(node); 3177 handleForeignJsCurrentIsolateContext(node);
3178 } else if (name == const SourceString('JS_SETUP_OBJECT')) {
3179 handleForeignJsSetupObject(node);
3088 } else if (name == const SourceString('JS_CALL_IN_ISOLATE')) { 3180 } else if (name == const SourceString('JS_CALL_IN_ISOLATE')) {
3089 handleForeignJsCallInIsolate(node); 3181 handleForeignJsCallInIsolate(node);
3090 } else if (name == const SourceString('DART_CLOSURE_TO_JS')) { 3182 } else if (name == const SourceString('DART_CLOSURE_TO_JS')) {
3091 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS'); 3183 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS');
3092 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) { 3184 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) {
3093 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); 3185 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF');
3094 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) { 3186 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) {
3095 handleForeignSetCurrentIsolate(node); 3187 handleForeignSetCurrentIsolate(node);
3096 } else if (name == const SourceString('JS_CREATE_ISOLATE')) { 3188 } else if (name == const SourceString('JS_CREATE_ISOLATE')) {
3097 handleForeignCreateIsolate(node); 3189 handleForeignCreateIsolate(node);
3098 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) { 3190 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) {
3099 stack.add(addConstantString(node, backend.namer.operatorIsPrefix())); 3191 stack.add(addConstantString(node, backend.namer.operatorIsPrefix()));
3100 } else if (name == const SourceString('JS_OBJECT_CLASS_NAME')) { 3192 } else if (name == const SourceString('JS_OBJECT_CLASS_NAME')) {
3101 String name = backend.namer.getRuntimeTypeName(compiler.objectClass); 3193 String name = backend.namer.getRuntimeTypeName(compiler.objectClass);
3102 stack.add(addConstantString(node, name)); 3194 stack.add(addConstantString(node, name));
3195 } else if (name == const SourceString('JS_FUNCTION_CLASS_NAME')) {
3196 String name = backend.namer.getRuntimeTypeName(compiler.functionClass);
3197 stack.add(addConstantString(node, name));
3103 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) { 3198 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
3104 stack.add(addConstantString(node, backend.namer.operatorAsPrefix())); 3199 stack.add(addConstantString(node, backend.namer.operatorAsPrefix()));
3200 } else if (name == const SourceString('JS_SIGNATURE_NAME')) {
3201 stack.add(addConstantString(node, backend.namer.operatorSignature()));
3202 } else if (name == const SourceString('JS_FUNCTION_TYPE_TAG')) {
3203 stack.add(addConstantString(node, backend.namer.functionTypeTag()));
3204 } else if (name == const SourceString('JS_FUNCTION_TYPE_VOID_RETURN_TAG')) {
3205 stack.add(addConstantString(node,
3206 backend.namer.functionTypeVoidReturnTag()));
3207 } else if (name == const SourceString('JS_FUNCTION_TYPE_RETURN_TYPE_TAG')) {
3208 stack.add(addConstantString(node,
3209 backend.namer.functionTypeReturnTypeTag()));
3210 } else if (name ==
3211 const SourceString('JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG')) {
3212 stack.add(addConstantString(node,
3213 backend.namer.functionTypeRequiredParametersTag()));
3214 } else if (name ==
3215 const SourceString('JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG')) {
3216 stack.add(addConstantString(node,
3217 backend.namer.functionTypeOptionalParametersTag()));
3218 } else if (name ==
3219 const SourceString('JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG')) {
3220 stack.add(addConstantString(node,
3221 backend.namer.functionTypeNamedParametersTag()));
3105 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) { 3222 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) {
3106 handleForeignDartObjectJsConstructorFunction(node); 3223 handleForeignDartObjectJsConstructorFunction(node);
3107 } else if (name == const SourceString('JS_IS_INDEXABLE_FIELD_NAME')) { 3224 } else if (name == const SourceString('JS_IS_INDEXABLE_FIELD_NAME')) {
3108 Element element = compiler.findHelper( 3225 Element element = compiler.findHelper(
3109 const SourceString('JavaScriptIndexingBehavior')); 3226 const SourceString('JavaScriptIndexingBehavior'));
3110 stack.add(addConstantString(node, backend.namer.operatorIs(element))); 3227 stack.add(addConstantString(node, backend.namer.operatorIs(element)));
3111 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) { 3228 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) {
3112 handleForeignJsCurrentIsolate(node); 3229 handleForeignJsCurrentIsolate(node);
3113 } else { 3230 } else {
3114 throw "Unknown foreign: ${selector}"; 3231 throw "Unknown foreign: ${selector}";
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
3211 /** 3328 /**
3212 * Generate code to extract the type arguments from the object, substitute 3329 * Generate code to extract the type arguments from the object, substitute
3213 * them as an instance of the type we are testing against (if necessary), and 3330 * them as an instance of the type we are testing against (if necessary), and
3214 * extract the type argument by the index of the variable in the list of type 3331 * extract the type argument by the index of the variable in the list of type
3215 * variables for that class. 3332 * variables for that class.
3216 */ 3333 */
3217 HInstruction readTypeVariable(ClassElement cls, 3334 HInstruction readTypeVariable(ClassElement cls,
3218 TypeVariableElement variable) { 3335 TypeVariableElement variable) {
3219 assert(currentElement.isInstanceMember()); 3336 assert(currentElement.isInstanceMember());
3220 int index = RuntimeTypes.getTypeVariableIndex(variable); 3337 int index = RuntimeTypes.getTypeVariableIndex(variable);
3221 String substitutionNameString = backend.namer.substitutionName(cls); 3338 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
3222 HInstruction substitutionName = graph.addConstantString( 3339 HInstruction substitutionName = graph.addConstantString(
3223 new LiteralDartString(substitutionNameString), null, compiler); 3340 new LiteralDartString(substitutionNameString), null, compiler);
3224 HInstruction target = localsHandler.readThis(); 3341 HInstruction target = localsHandler.readThis();
3225 HInstruction substitution = createForeign('#[#]', HType.UNKNOWN,
3226 <HInstruction>[target, substitutionName]);
3227 add(substitution);
3228 pushInvokeStatic(null, 3342 pushInvokeStatic(null,
3229 backend.getGetRuntimeTypeArgument(), 3343 backend.getGetRuntimeTypeArgument(),
3230 [target, 3344 [target,
3231 substitution, 3345 substitutionName,
3232 graph.addConstantInt(index, compiler)], 3346 graph.addConstantInt(index, compiler)],
3233 HType.UNKNOWN); 3347 HType.UNKNOWN);
3234 return pop(); 3348 return pop();
3235 } 3349 }
3236 3350
3237 /** 3351 /**
3238 * Helper to create an instruction that gets the value of a type variable. 3352 * Helper to create an instruction that gets the value of a type variable.
3239 */ 3353 */
3240 HInstruction addTypeVariableReference(TypeVariableType type) { 3354 HInstruction addTypeVariableReference(TypeVariableType type) {
3241 Element member = currentElement; 3355 Element member = currentElement;
(...skipping 2138 matching lines...) Expand 10 before | Expand all | Expand 10 after
5380 new HSubGraphBlockInformation(elseBranch.graph)); 5494 new HSubGraphBlockInformation(elseBranch.graph));
5381 5495
5382 HBasicBlock conditionStartBlock = conditionBranch.block; 5496 HBasicBlock conditionStartBlock = conditionBranch.block;
5383 conditionStartBlock.setBlockFlow(info, joinBlock); 5497 conditionStartBlock.setBlockFlow(info, joinBlock);
5384 SubGraph conditionGraph = conditionBranch.graph; 5498 SubGraph conditionGraph = conditionBranch.graph;
5385 HIf branch = conditionGraph.end.last; 5499 HIf branch = conditionGraph.end.last;
5386 assert(branch is HIf); 5500 assert(branch is HIf);
5387 branch.blockInformation = conditionStartBlock.blockFlow; 5501 branch.blockInformation = conditionStartBlock.blockFlow;
5388 } 5502 }
5389 } 5503 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698