OLD | NEW |
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 1795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1806 HType subtype = new HType.subtype(type, compiler); | 1806 HType subtype = new HType.subtype(type, compiler); |
1807 HInstruction representations = buildTypeArgumentRepresentations(type); | 1807 HInstruction representations = buildTypeArgumentRepresentations(type); |
1808 add(representations); | 1808 add(representations); |
1809 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | 1809 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, |
1810 original, representations); | 1810 original, representations); |
1811 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | 1811 } else if (type.kind == TypeKind.TYPE_VARIABLE) { |
1812 HType subtype = original.instructionType; | 1812 HType subtype = original.instructionType; |
1813 HInstruction typeVariable = addTypeVariableReference(type); | 1813 HInstruction typeVariable = addTypeVariableReference(type); |
1814 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | 1814 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, |
1815 original, typeVariable); | 1815 original, typeVariable); |
| 1816 } else if (type.kind == TypeKind.FUNCTION) { |
| 1817 HType subtype = original.instructionType; |
| 1818 bool contextIsTypeArguments = false; |
| 1819 HInstruction context; |
| 1820 if (type.containsTypeVariables) { |
| 1821 if (currentElement.isInstanceMember()) { |
| 1822 context = localsHandler.readThis(); |
| 1823 } else { |
| 1824 ClassElement contextClass = Types.getClassContext(type); |
| 1825 List<HInstruction> inputs = <HInstruction>[]; |
| 1826 for (Link<DartType> link = contextClass.typeVariables; |
| 1827 !link.isEmpty; |
| 1828 link = link.tail) { |
| 1829 inputs.add(addTypeVariableReference(link.head)); |
| 1830 } |
| 1831 context = new HLiteralList(inputs); |
| 1832 add(context); |
| 1833 contextIsTypeArguments = true; |
| 1834 } |
| 1835 } else { |
| 1836 context = graph.addConstantNull(constantSystem); |
| 1837 } |
| 1838 return new HTypeConversion.withContext(type, kind, subtype, |
| 1839 original, context, contextIsTypeArguments: contextIsTypeArguments); |
1816 } else { | 1840 } else { |
1817 return original.convertType(compiler, type, kind); | 1841 return original.convertType(compiler, type, kind); |
1818 } | 1842 } |
1819 } | 1843 } |
1820 | 1844 |
1821 HInstruction potentiallyCheckType(HInstruction original, DartType type, | 1845 HInstruction potentiallyCheckType(HInstruction original, DartType type, |
1822 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { | 1846 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { |
1823 if (!compiler.enableTypeAssertions) return original; | 1847 if (!compiler.enableTypeAssertions) return original; |
| 1848 type = type.unalias(compiler); |
1824 HInstruction other = buildTypeConversion(original, type, kind); | 1849 HInstruction other = buildTypeConversion(original, type, kind); |
1825 if (other != original) add(other); | 1850 if (other != original) add(other); |
| 1851 compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree); |
1826 return other; | 1852 return other; |
1827 } | 1853 } |
1828 | 1854 |
1829 HGraph closeFunction() { | 1855 HGraph closeFunction() { |
1830 // TODO(kasperl): Make this goto an implicit return. | 1856 // TODO(kasperl): Make this goto an implicit return. |
1831 if (!isAborted()) closeAndGotoExit(new HGoto()); | 1857 if (!isAborted()) closeAndGotoExit(new HGoto()); |
1832 graph.finalize(); | 1858 graph.finalize(); |
1833 return graph; | 1859 return graph; |
1834 } | 1860 } |
1835 | 1861 |
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2461 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; | 2487 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; |
2462 assert(capturedLocal != null); | 2488 assert(capturedLocal != null); |
2463 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 2489 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
2464 } | 2490 } |
2465 }); | 2491 }); |
2466 | 2492 |
2467 HType type = new HType.nonNullExact( | 2493 HType type = new HType.nonNullExact( |
2468 compiler.functionClass.computeType(compiler), | 2494 compiler.functionClass.computeType(compiler), |
2469 compiler); | 2495 compiler); |
2470 push(new HForeignNew(closureClassElement, type, capturedVariables)); | 2496 push(new HForeignNew(closureClassElement, type, capturedVariables)); |
| 2497 |
| 2498 Element methodElement = nestedClosureData.closureElement; |
| 2499 if (compiler.backend.methodNeedsRti(methodElement)) { |
| 2500 compiler.backend.registerGenericClosure( |
| 2501 methodElement, compiler.enqueuer.codegen, work.resolutionTree); |
| 2502 } |
2471 } | 2503 } |
2472 | 2504 |
2473 visitFunctionDeclaration(FunctionDeclaration node) { | 2505 visitFunctionDeclaration(FunctionDeclaration node) { |
2474 assert(isReachable); | 2506 assert(isReachable); |
2475 visit(node.function); | 2507 visit(node.function); |
2476 localsHandler.updateLocal(elements[node], pop()); | 2508 localsHandler.updateLocal(elements[node], pop()); |
2477 } | 2509 } |
2478 | 2510 |
2479 visitIdentifier(Identifier node) { | 2511 visitIdentifier(Identifier node) { |
2480 if (node.isThis()) { | 2512 if (node.isThis()) { |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2740 inputs.add(runtimeType); | 2772 inputs.add(runtimeType); |
2741 })); | 2773 })); |
2742 } | 2774 } |
2743 String template = '[${templates.join(', ')}]'; | 2775 String template = '[${templates.join(', ')}]'; |
2744 HInstruction representation = | 2776 HInstruction representation = |
2745 createForeign(template, HType.READABLE_ARRAY, inputs); | 2777 createForeign(template, HType.READABLE_ARRAY, inputs); |
2746 return representation; | 2778 return representation; |
2747 } | 2779 } |
2748 } | 2780 } |
2749 | 2781 |
2750 visitOperatorSend(node) { | 2782 visitOperatorSend(Send node) { |
2751 Operator op = node.selector; | 2783 Operator op = node.selector; |
2752 if (const SourceString("[]") == op.source) { | 2784 if (const SourceString("[]") == op.source) { |
2753 visitDynamicSend(node); | 2785 visitDynamicSend(node); |
2754 } else if (const SourceString("&&") == op.source || | 2786 } else if (const SourceString("&&") == op.source || |
2755 const SourceString("||") == op.source) { | 2787 const SourceString("||") == op.source) { |
2756 visitLogicalAndOr(node, op); | 2788 visitLogicalAndOr(node, op); |
2757 } else if (const SourceString("!") == op.source) { | 2789 } else if (const SourceString("!") == op.source) { |
2758 visitLogicalNot(node); | 2790 visitLogicalNot(node); |
2759 } else if (node.argumentsNode is Prefix) { | 2791 } else if (node.argumentsNode is Prefix) { |
2760 visitUnary(node, op); | 2792 visitUnary(node, op); |
(...skipping 16 matching lines...) Expand all Loading... |
2777 var left = pop(); | 2809 var left = pop(); |
2778 visitBinary(left, op, right, elements.getSelector(node), node); | 2810 visitBinary(left, op, right, elements.getSelector(node), node); |
2779 } | 2811 } |
2780 } | 2812 } |
2781 | 2813 |
2782 void visitIsSend(Send node) { | 2814 void visitIsSend(Send node) { |
2783 visit(node.receiver); | 2815 visit(node.receiver); |
2784 HInstruction expression = pop(); | 2816 HInstruction expression = pop(); |
2785 bool isNot = node.isIsNotCheck; | 2817 bool isNot = node.isIsNotCheck; |
2786 DartType type = elements.getType(node.typeAnnotationFromIsCheck); | 2818 DartType type = elements.getType(node.typeAnnotationFromIsCheck); |
| 2819 type = type.unalias(compiler); |
2787 if (type.isMalformed) { | 2820 if (type.isMalformed) { |
2788 String reasons = Types.fetchReasonsFromMalformedType(type); | 2821 String reasons = Types.fetchReasonsFromMalformedType(type); |
2789 if (compiler.enableTypeAssertions) { | 2822 if (compiler.enableTypeAssertions) { |
2790 generateMalformedSubtypeError(node, expression, type, reasons); | 2823 generateMalformedSubtypeError(node, expression, type, reasons); |
2791 } else { | 2824 } else { |
2792 generateRuntimeError(node, '$type is malformed: $reasons'); | 2825 generateRuntimeError(node, '$type is malformed: $reasons'); |
2793 } | 2826 } |
2794 } else { | 2827 } else { |
2795 HInstruction instruction = buildIsNode(node, type, expression); | 2828 HInstruction instruction = buildIsNode(node, type, expression); |
2796 if (isNot) { | 2829 if (isNot) { |
2797 add(instruction); | 2830 add(instruction); |
2798 instruction = new HNot(instruction); | 2831 instruction = new HNot(instruction); |
2799 } | 2832 } |
2800 push(instruction); | 2833 push(instruction); |
2801 } | 2834 } |
2802 } | 2835 } |
2803 | 2836 |
2804 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) { | 2837 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) { |
2805 if (type.kind == TypeKind.TYPE_VARIABLE) { | 2838 if (type.kind == TypeKind.FUNCTION) { |
| 2839 Element checkFunctionSubtype = backend.getCheckFunctionSubtype(); |
| 2840 |
| 2841 HInstruction signatureName = graph.addConstantString( |
| 2842 new DartString.literal(backend.namer.getFunctionTypeName(type)), |
| 2843 node, constantSystem); |
| 2844 |
| 2845 HInstruction contextName; |
| 2846 HInstruction context; |
| 2847 HInstruction typeArguments; |
| 2848 if (type.containsTypeVariables) { |
| 2849 ClassElement contextClass = Types.getClassContext(type); |
| 2850 contextName = graph.addConstantString( |
| 2851 new DartString.literal(backend.namer.getName(contextClass)), |
| 2852 node, constantSystem); |
| 2853 if (currentElement.isInstanceMember()) { |
| 2854 context = localsHandler.readThis(); |
| 2855 typeArguments = graph.addConstantNull(constantSystem); |
| 2856 } else { |
| 2857 context = graph.addConstantNull(constantSystem); |
| 2858 List<HInstruction> inputs = <HInstruction>[]; |
| 2859 for (Link<DartType> link = contextClass.typeVariables; |
| 2860 !link.isEmpty; |
| 2861 link = link.tail) { |
| 2862 inputs.add(addTypeVariableReference(link.head)); |
| 2863 } |
| 2864 typeArguments = new HLiteralList(inputs); |
| 2865 add(typeArguments); |
| 2866 } |
| 2867 } else { |
| 2868 contextName = graph.addConstantNull(constantSystem); |
| 2869 context = graph.addConstantNull(constantSystem); |
| 2870 typeArguments = graph.addConstantNull(constantSystem); |
| 2871 } |
| 2872 |
| 2873 List<HInstruction> inputs = <HInstruction>[expression, |
| 2874 signatureName, |
| 2875 contextName, |
| 2876 context, |
| 2877 typeArguments]; |
| 2878 pushInvokeStatic(node, checkFunctionSubtype, inputs, HType.BOOLEAN); |
| 2879 HInstruction call = pop(); |
| 2880 return new HIs(type, <HInstruction>[expression, call], |
| 2881 HIs.COMPOUND_CHECK); |
| 2882 } else if (type.kind == TypeKind.TYPE_VARIABLE) { |
2806 HInstruction runtimeType = addTypeVariableReference(type); | 2883 HInstruction runtimeType = addTypeVariableReference(type); |
2807 Element helper = backend.getCheckSubtypeOfRuntimeType(); | 2884 Element helper = backend.getCheckSubtypeOfRuntimeType(); |
2808 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; | 2885 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; |
2809 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN); | 2886 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN); |
2810 HInstruction call = pop(); | 2887 HInstruction call = pop(); |
2811 return new HIs(type, <HInstruction>[expression, call], | 2888 return new HIs(type, <HInstruction>[expression, call], |
2812 HIs.VARIABLE_CHECK); | 2889 HIs.VARIABLE_CHECK); |
2813 } else if (RuntimeTypes.hasTypeArguments(type)) { | 2890 } else if (RuntimeTypes.hasTypeArguments(type)) { |
2814 ClassElement element = type.element; | 2891 ClassElement element = type.element; |
2815 Element helper = backend.getCheckSubtype(); | 2892 Element helper = backend.getCheckSubtype(); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2993 Element element = compiler.isolateHelperLibrary.find( | 3070 Element element = compiler.isolateHelperLibrary.find( |
2994 const SourceString('_currentIsolate')); | 3071 const SourceString('_currentIsolate')); |
2995 if (element == null) { | 3072 if (element == null) { |
2996 compiler.cancel( | 3073 compiler.cancel( |
2997 'Isolate library and compiler mismatch', node: node); | 3074 'Isolate library and compiler mismatch', node: node); |
2998 } | 3075 } |
2999 pushInvokeStatic(null, element, [], HType.UNKNOWN); | 3076 pushInvokeStatic(null, element, [], HType.UNKNOWN); |
3000 } | 3077 } |
3001 } | 3078 } |
3002 | 3079 |
| 3080 void handleForeignJsSetupObject(Send node) { |
| 3081 if (!node.arguments.isEmpty) { |
| 3082 compiler.cancel( |
| 3083 'Too many arguments to JS_SETUP_OBJECT', node: node); |
| 3084 } |
| 3085 |
| 3086 String name = backend.namer.SETUP_OBJECT; |
| 3087 push(new HForeign(new js.LiteralString(name), |
| 3088 HType.UNKNOWN, |
| 3089 <HInstruction>[])); |
| 3090 } |
| 3091 |
3003 void handleForeignJsCallInIsolate(Send node) { | 3092 void handleForeignJsCallInIsolate(Send node) { |
3004 Link<Node> link = node.arguments; | 3093 Link<Node> link = node.arguments; |
3005 if (!compiler.hasIsolateSupport()) { | 3094 if (!compiler.hasIsolateSupport()) { |
3006 // If the isolate library is not used, we just invoke the | 3095 // If the isolate library is not used, we just invoke the |
3007 // closure. | 3096 // closure. |
3008 visit(link.tail.head); | 3097 visit(link.tail.head); |
3009 Selector selector = new Selector.callClosure(0); | 3098 Selector selector = new Selector.callClosure(0); |
3010 push(new HInvokeClosure(selector, <HInstruction>[pop()])); | 3099 push(new HInvokeClosure(selector, <HInstruction>[pop()])); |
3011 } else { | 3100 } else { |
3012 // Call a helper method from the isolate library. | 3101 // Call a helper method from the isolate library. |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3104 <HInstruction>[])); | 3193 <HInstruction>[])); |
3105 } | 3194 } |
3106 | 3195 |
3107 visitForeignSend(Send node) { | 3196 visitForeignSend(Send node) { |
3108 Selector selector = elements.getSelector(node); | 3197 Selector selector = elements.getSelector(node); |
3109 SourceString name = selector.name; | 3198 SourceString name = selector.name; |
3110 if (name == const SourceString('JS')) { | 3199 if (name == const SourceString('JS')) { |
3111 handleForeignJs(node); | 3200 handleForeignJs(node); |
3112 } else if (name == const SourceString('JS_CURRENT_ISOLATE_CONTEXT')) { | 3201 } else if (name == const SourceString('JS_CURRENT_ISOLATE_CONTEXT')) { |
3113 handleForeignJsCurrentIsolateContext(node); | 3202 handleForeignJsCurrentIsolateContext(node); |
| 3203 } else if (name == const SourceString('JS_SETUP_OBJECT')) { |
| 3204 handleForeignJsSetupObject(node); |
3114 } else if (name == const SourceString('JS_CALL_IN_ISOLATE')) { | 3205 } else if (name == const SourceString('JS_CALL_IN_ISOLATE')) { |
3115 handleForeignJsCallInIsolate(node); | 3206 handleForeignJsCallInIsolate(node); |
3116 } else if (name == const SourceString('DART_CLOSURE_TO_JS')) { | 3207 } else if (name == const SourceString('DART_CLOSURE_TO_JS')) { |
3117 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS'); | 3208 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS'); |
3118 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) { | 3209 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) { |
3119 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); | 3210 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); |
3120 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) { | 3211 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) { |
3121 handleForeignSetCurrentIsolate(node); | 3212 handleForeignSetCurrentIsolate(node); |
3122 } else if (name == const SourceString('JS_CREATE_ISOLATE')) { | 3213 } else if (name == const SourceString('JS_CREATE_ISOLATE')) { |
3123 handleForeignCreateIsolate(node); | 3214 handleForeignCreateIsolate(node); |
3124 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) { | 3215 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) { |
3125 stack.add(addConstantString(node, backend.namer.operatorIsPrefix())); | 3216 stack.add(addConstantString(node, backend.namer.operatorIsPrefix())); |
3126 } else if (name == const SourceString('JS_OBJECT_CLASS_NAME')) { | 3217 } else if (name == const SourceString('JS_OBJECT_CLASS_NAME')) { |
3127 String name = backend.namer.getRuntimeTypeName(compiler.objectClass); | 3218 String name = backend.namer.getRuntimeTypeName(compiler.objectClass); |
3128 stack.add(addConstantString(node, name)); | 3219 stack.add(addConstantString(node, name)); |
3129 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) { | 3220 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) { |
3130 stack.add(addConstantString(node, backend.namer.operatorAsPrefix())); | 3221 stack.add(addConstantString(node, backend.namer.operatorAsPrefix())); |
| 3222 } else if (name == const SourceString('JS_SIGNATURE_NAME')) { |
| 3223 stack.add(addConstantString(node, backend.namer.operatorSignature())); |
| 3224 } else if (name == const SourceString('JS_FUNCTION_TYPE_TAG')) { |
| 3225 stack.add(addConstantString(node, backend.namer.functionTypeTag())); |
| 3226 } else if (name == const SourceString('JS_FUNCTION_TYPE_VOID_RETURN_TAG')) { |
| 3227 stack.add(addConstantString(node, |
| 3228 backend.namer.functionTypeVoidReturnTag())); |
| 3229 } else if (name == const SourceString('JS_FUNCTION_TYPE_RETURN_TYPE_TAG')) { |
| 3230 stack.add(addConstantString(node, |
| 3231 backend.namer.functionTypeReturnTypeTag())); |
| 3232 } else if (name == |
| 3233 const SourceString('JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG')) { |
| 3234 stack.add(addConstantString(node, |
| 3235 backend.namer.functionTypeRequiredParametersTag())); |
| 3236 } else if (name == |
| 3237 const SourceString('JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG')) { |
| 3238 stack.add(addConstantString(node, |
| 3239 backend.namer.functionTypeOptionalParametersTag())); |
| 3240 } else if (name == |
| 3241 const SourceString('JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG')) { |
| 3242 stack.add(addConstantString(node, |
| 3243 backend.namer.functionTypeNamedParametersTag())); |
3131 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) { | 3244 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) { |
3132 handleForeignDartObjectJsConstructorFunction(node); | 3245 handleForeignDartObjectJsConstructorFunction(node); |
3133 } else if (name == const SourceString('JS_IS_INDEXABLE_FIELD_NAME')) { | 3246 } else if (name == const SourceString('JS_IS_INDEXABLE_FIELD_NAME')) { |
3134 Element element = compiler.findHelper( | 3247 Element element = compiler.findHelper( |
3135 const SourceString('JavaScriptIndexingBehavior')); | 3248 const SourceString('JavaScriptIndexingBehavior')); |
3136 stack.add(addConstantString(node, backend.namer.operatorIs(element))); | 3249 stack.add(addConstantString(node, backend.namer.operatorIs(element))); |
3137 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) { | 3250 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) { |
3138 handleForeignJsCurrentIsolate(node); | 3251 handleForeignJsCurrentIsolate(node); |
3139 } else { | 3252 } else { |
3140 throw "Unknown foreign: ${selector}"; | 3253 throw "Unknown foreign: ${selector}"; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3237 /** | 3350 /** |
3238 * Generate code to extract the type arguments from the object, substitute | 3351 * Generate code to extract the type arguments from the object, substitute |
3239 * them as an instance of the type we are testing against (if necessary), and | 3352 * them as an instance of the type we are testing against (if necessary), and |
3240 * extract the type argument by the index of the variable in the list of type | 3353 * extract the type argument by the index of the variable in the list of type |
3241 * variables for that class. | 3354 * variables for that class. |
3242 */ | 3355 */ |
3243 HInstruction readTypeVariable(ClassElement cls, | 3356 HInstruction readTypeVariable(ClassElement cls, |
3244 TypeVariableElement variable) { | 3357 TypeVariableElement variable) { |
3245 assert(currentElement.isInstanceMember()); | 3358 assert(currentElement.isInstanceMember()); |
3246 int index = RuntimeTypes.getTypeVariableIndex(variable); | 3359 int index = RuntimeTypes.getTypeVariableIndex(variable); |
3247 String substitutionNameString = backend.namer.substitutionName(cls); | 3360 String substitutionNameString = backend.namer.getName(cls); |
3248 HInstruction substitutionName = graph.addConstantString( | 3361 HInstruction substitutionName = graph.addConstantString( |
3249 new LiteralDartString(substitutionNameString), null, constantSystem); | 3362 new LiteralDartString(substitutionNameString), null, constantSystem); |
3250 HInstruction target = localsHandler.readThis(); | 3363 HInstruction target = localsHandler.readThis(); |
3251 HInstruction substitution = createForeign('#[#]', HType.UNKNOWN, | |
3252 <HInstruction>[target, substitutionName]); | |
3253 add(substitution); | |
3254 pushInvokeStatic(null, | 3364 pushInvokeStatic(null, |
3255 backend.getGetRuntimeTypeArgument(), | 3365 backend.getGetRuntimeTypeArgument(), |
3256 [target, | 3366 [target, |
3257 substitution, | 3367 substitutionName, |
3258 graph.addConstantInt(index, constantSystem)], | 3368 graph.addConstantInt(index, constantSystem)], |
3259 HType.UNKNOWN); | 3369 HType.UNKNOWN); |
3260 return pop(); | 3370 return pop(); |
3261 } | 3371 } |
3262 | 3372 |
3263 /** | 3373 /** |
3264 * Helper to create an instruction that gets the value of a type variable. | 3374 * Helper to create an instruction that gets the value of a type variable. |
3265 */ | 3375 */ |
3266 HInstruction addTypeVariableReference(TypeVariableType type) { | 3376 HInstruction addTypeVariableReference(TypeVariableType type) { |
3267 Element member = currentElement; | 3377 Element member = currentElement; |
(...skipping 2145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5413 new HSubGraphBlockInformation(elseBranch.graph)); | 5523 new HSubGraphBlockInformation(elseBranch.graph)); |
5414 | 5524 |
5415 HBasicBlock conditionStartBlock = conditionBranch.block; | 5525 HBasicBlock conditionStartBlock = conditionBranch.block; |
5416 conditionStartBlock.setBlockFlow(info, joinBlock); | 5526 conditionStartBlock.setBlockFlow(info, joinBlock); |
5417 SubGraph conditionGraph = conditionBranch.graph; | 5527 SubGraph conditionGraph = conditionBranch.graph; |
5418 HIf branch = conditionGraph.end.last; | 5528 HIf branch = conditionGraph.end.last; |
5419 assert(branch is HIf); | 5529 assert(branch is HIf); |
5420 branch.blockInformation = conditionStartBlock.blockFlow; | 5530 branch.blockInformation = conditionStartBlock.blockFlow; |
5421 } | 5531 } |
5422 } | 5532 } |
OLD | NEW |