| 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 2381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2392 if (element.isGetter()) { | 2392 if (element.isGetter()) { |
| 2393 Selector selector = elements.getSelector(send); | 2393 Selector selector = elements.getSelector(send); |
| 2394 if (tryInlineMethod(element, selector, const Link<Node>(), send)) { | 2394 if (tryInlineMethod(element, selector, const Link<Node>(), send)) { |
| 2395 return; | 2395 return; |
| 2396 } | 2396 } |
| 2397 } | 2397 } |
| 2398 // TODO(5346): Try to avoid the need for calling [declaration] before | 2398 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 2399 // creating an [HStatic]. | 2399 // creating an [HStatic]. |
| 2400 push(new HStatic(element.declaration)); | 2400 push(new HStatic(element.declaration)); |
| 2401 if (element.isGetter()) { | 2401 if (element.isGetter()) { |
| 2402 push(new HInvokeStatic(<HInstruction>[pop()])); | 2402 push(new HInvokeStatic(<HInstruction>[pop()], HType.UNKNOWN)); |
| 2403 } | 2403 } |
| 2404 } | 2404 } |
| 2405 } else if (Elements.isInstanceSend(send, elements)) { | 2405 } else if (Elements.isInstanceSend(send, elements)) { |
| 2406 HInstruction receiver = generateInstanceSendReceiver(send); | 2406 HInstruction receiver = generateInstanceSendReceiver(send); |
| 2407 generateInstanceGetterWithCompiledReceiver(send, receiver); | 2407 generateInstanceGetterWithCompiledReceiver(send, receiver); |
| 2408 } else if (Elements.isStaticOrTopLevelFunction(element)) { | 2408 } else if (Elements.isStaticOrTopLevelFunction(element)) { |
| 2409 // TODO(5346): Try to avoid the need for calling [declaration] before | 2409 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 2410 // creating an [HStatic]. | 2410 // creating an [HStatic]. |
| 2411 push(new HStatic(element.declaration)); | 2411 push(new HStatic(element.declaration)); |
| 2412 // TODO(ahe): This should be registered in codegen. | 2412 // TODO(ahe): This should be registered in codegen. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2448 send); | 2448 send); |
| 2449 } | 2449 } |
| 2450 stack.add(value); | 2450 stack.add(value); |
| 2451 } | 2451 } |
| 2452 | 2452 |
| 2453 void generateSetter(SendSet send, Element element, HInstruction value) { | 2453 void generateSetter(SendSet send, Element element, HInstruction value) { |
| 2454 if (Elements.isStaticOrTopLevelField(element)) { | 2454 if (Elements.isStaticOrTopLevelField(element)) { |
| 2455 if (element.isSetter()) { | 2455 if (element.isSetter()) { |
| 2456 HStatic target = new HStatic(element); | 2456 HStatic target = new HStatic(element); |
| 2457 add(target); | 2457 add(target); |
| 2458 addWithPosition(new HInvokeStatic(<HInstruction>[target, value]), send); | 2458 addWithPosition( |
| 2459 new HInvokeStatic(<HInstruction>[target, value], HType.UNKNOWN), |
| 2460 send); |
| 2459 } else { | 2461 } else { |
| 2460 value = potentiallyCheckType(value, element.computeType(compiler)); | 2462 value = potentiallyCheckType(value, element.computeType(compiler)); |
| 2461 addWithPosition(new HStaticStore(element, value), send); | 2463 addWithPosition(new HStaticStore(element, value), send); |
| 2462 } | 2464 } |
| 2463 stack.add(value); | 2465 stack.add(value); |
| 2464 } else if (element == null || Elements.isInstanceField(element)) { | 2466 } else if (element == null || Elements.isInstanceField(element)) { |
| 2465 HInstruction receiver = generateInstanceSendReceiver(send); | 2467 HInstruction receiver = generateInstanceSendReceiver(send); |
| 2466 generateInstanceSetterWithCompiledReceiver(send, receiver, value); | 2468 generateInstanceSetterWithCompiledReceiver(send, receiver, value); |
| 2467 } else if (Elements.isErroneousElement(element)) { | 2469 } else if (Elements.isErroneousElement(element)) { |
| 2468 // An erroneous element indicates an unresolved static setter. | 2470 // An erroneous element indicates an unresolved static setter. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2486 } | 2488 } |
| 2487 | 2489 |
| 2488 HInstruction invokeInterceptor(Set<ClassElement> intercepted, | 2490 HInstruction invokeInterceptor(Set<ClassElement> intercepted, |
| 2489 HInstruction receiver, | 2491 HInstruction receiver, |
| 2490 Send send) { | 2492 Send send) { |
| 2491 HInterceptor interceptor = new HInterceptor(intercepted, receiver); | 2493 HInterceptor interceptor = new HInterceptor(intercepted, receiver); |
| 2492 add(interceptor); | 2494 add(interceptor); |
| 2493 return interceptor; | 2495 return interceptor; |
| 2494 } | 2496 } |
| 2495 | 2497 |
| 2496 void pushInvokeHelper0(Element helper) { | 2498 void pushInvokeHelper0(Element helper, HType type) { |
| 2497 HInstruction reference = new HStatic(helper); | 2499 HInstruction reference = new HStatic(helper); |
| 2498 add(reference); | 2500 add(reference); |
| 2499 List<HInstruction> inputs = <HInstruction>[reference]; | 2501 List<HInstruction> inputs = <HInstruction>[reference]; |
| 2500 HInstruction result = new HInvokeStatic(inputs); | 2502 HInstruction result = new HInvokeStatic(inputs, type); |
| 2501 push(result); | 2503 push(result); |
| 2502 } | 2504 } |
| 2503 | 2505 |
| 2504 void pushInvokeHelper1(Element helper, HInstruction a0) { | 2506 void pushInvokeHelper1(Element helper, HInstruction a0, HType type) { |
| 2505 HInstruction reference = new HStatic(helper); | 2507 HInstruction reference = new HStatic(helper); |
| 2506 add(reference); | 2508 add(reference); |
| 2507 List<HInstruction> inputs = <HInstruction>[reference, a0]; | 2509 List<HInstruction> inputs = <HInstruction>[reference, a0]; |
| 2508 HInstruction result = new HInvokeStatic(inputs); | 2510 HInstruction result = new HInvokeStatic(inputs, type); |
| 2509 push(result); | 2511 push(result); |
| 2510 } | 2512 } |
| 2511 | 2513 |
| 2512 void pushInvokeHelper2(Element helper, HInstruction a0, HInstruction a1) { | 2514 void pushInvokeHelper2(Element helper, |
| 2515 HInstruction a0, |
| 2516 HInstruction a1, |
| 2517 HType type) { |
| 2513 HInstruction reference = new HStatic(helper); | 2518 HInstruction reference = new HStatic(helper); |
| 2514 add(reference); | 2519 add(reference); |
| 2515 List<HInstruction> inputs = <HInstruction>[reference, a0, a1]; | 2520 List<HInstruction> inputs = <HInstruction>[reference, a0, a1]; |
| 2516 HInstruction result = new HInvokeStatic(inputs); | 2521 HInstruction result = new HInvokeStatic(inputs, type); |
| 2517 push(result); | 2522 push(result); |
| 2518 } | 2523 } |
| 2519 | 2524 |
| 2520 void pushInvokeHelper3(Element helper, HInstruction a0, HInstruction a1, | 2525 void pushInvokeHelper3(Element helper, |
| 2521 HInstruction a2) { | 2526 HInstruction a0, |
| 2527 HInstruction a1, |
| 2528 HInstruction a2, |
| 2529 HType type) { |
| 2522 HInstruction reference = new HStatic(helper); | 2530 HInstruction reference = new HStatic(helper); |
| 2523 add(reference); | 2531 add(reference); |
| 2524 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2]; | 2532 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2]; |
| 2525 HInstruction result = new HInvokeStatic(inputs); | 2533 HInstruction result = new HInvokeStatic(inputs, type); |
| 2526 push(result); | 2534 push(result); |
| 2527 } | 2535 } |
| 2528 | 2536 |
| 2529 void pushInvokeHelper4(Element helper, HInstruction a0, HInstruction a1, | 2537 void pushInvokeHelper4(Element helper, |
| 2530 HInstruction a2, HInstruction a3) { | 2538 HInstruction a0, |
| 2539 HInstruction a1, |
| 2540 HInstruction a2, |
| 2541 HInstruction a3, |
| 2542 HType type) { |
| 2531 HInstruction reference = new HStatic(helper); | 2543 HInstruction reference = new HStatic(helper); |
| 2532 add(reference); | 2544 add(reference); |
| 2533 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3]; | 2545 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3]; |
| 2534 HInstruction result = new HInvokeStatic(inputs); | 2546 HInstruction result = new HInvokeStatic(inputs, type); |
| 2535 push(result); | 2547 push(result); |
| 2536 } | 2548 } |
| 2537 | 2549 |
| 2538 void pushInvokeHelper5(Element helper, HInstruction a0, HInstruction a1, | 2550 void pushInvokeHelper5(Element helper, |
| 2539 HInstruction a2, HInstruction a3, HInstruction a4) { | 2551 HInstruction a0, |
| 2552 HInstruction a1, |
| 2553 HInstruction a2, |
| 2554 HInstruction a3, |
| 2555 HInstruction a4, |
| 2556 HType type) { |
| 2540 HInstruction reference = new HStatic(helper); | 2557 HInstruction reference = new HStatic(helper); |
| 2541 add(reference); | 2558 add(reference); |
| 2542 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3, a4]; | 2559 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3, a4]; |
| 2543 HInstruction result = new HInvokeStatic(inputs); | 2560 HInstruction result = new HInvokeStatic(inputs, type); |
| 2544 push(result); | 2561 push(result); |
| 2545 } | 2562 } |
| 2546 | 2563 |
| 2547 HForeign createForeign(String code, HType type, List<HInstruction> inputs) { | 2564 HForeign createForeign(String code, HType type, List<HInstruction> inputs) { |
| 2548 return new HForeign(new LiteralDartString(code), type, inputs); | 2565 return new HForeign(new LiteralDartString(code), type, inputs); |
| 2549 } | 2566 } |
| 2550 | 2567 |
| 2551 HInstruction getRuntimeTypeInfo(HInstruction target) { | 2568 HInstruction getRuntimeTypeInfo(HInstruction target) { |
| 2552 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target); | 2569 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); |
| 2553 return pop(); | 2570 return pop(); |
| 2554 } | 2571 } |
| 2555 | 2572 |
| 2556 // TODO(karlklose): change construction of the representations to be GVN'able | 2573 // TODO(karlklose): change construction of the representations to be GVN'able |
| 2557 // (dartbug.com/7182). | 2574 // (dartbug.com/7182). |
| 2558 List<HInstruction> buildTypeArgumentRepresentations(DartType type) { | 2575 List<HInstruction> buildTypeArgumentRepresentations(DartType type) { |
| 2559 HInstruction createForeignArray(String code, inputs) { | 2576 HInstruction createForeignArray(String code, inputs) { |
| 2560 return createForeign(code, HType.READABLE_ARRAY, inputs); | 2577 return createForeign(code, HType.READABLE_ARRAY, inputs); |
| 2561 } | 2578 } |
| 2562 HInstruction typeInfo; | 2579 HInstruction typeInfo; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2655 int index = 0; | 2672 int index = 0; |
| 2656 representations.forEach((HInstruction representation) { | 2673 representations.forEach((HInstruction representation) { |
| 2657 HInstruction position = graph.addConstantInt(index, constantSystem); | 2674 HInstruction position = graph.addConstantInt(index, constantSystem); |
| 2658 // Get the index'th type argument from the runtime type information. | 2675 // Get the index'th type argument from the runtime type information. |
| 2659 HInstruction typeArgument = | 2676 HInstruction typeArgument = |
| 2660 createForeign('#[#]', HType.UNKNOWN, [typeInfo, position]); | 2677 createForeign('#[#]', HType.UNKNOWN, [typeInfo, position]); |
| 2661 add(typeArgument); | 2678 add(typeArgument); |
| 2662 // Create the call to isSubtype. | 2679 // Create the call to isSubtype. |
| 2663 List<HInstruction> inputs = | 2680 List<HInstruction> inputs = |
| 2664 <HInstruction>[isSubtype, typeArgument, representation]; | 2681 <HInstruction>[isSubtype, typeArgument, representation]; |
| 2665 HInstruction call = new HInvokeStatic(inputs); | 2682 HInstruction call = new HInvokeStatic(inputs, HType.BOOLEAN); |
| 2666 add(call); | 2683 add(call); |
| 2667 checks.add(call); | 2684 checks.add(call); |
| 2668 index++; | 2685 index++; |
| 2669 }); | 2686 }); |
| 2670 instruction = new HIs(type, <HInstruction>[expression]..addAll(checks)); | 2687 instruction = new HIs(type, <HInstruction>[expression]..addAll(checks)); |
| 2671 } else { | 2688 } else { |
| 2672 instruction = new HIs(type, <HInstruction>[expression]); | 2689 instruction = new HIs(type, <HInstruction>[expression]); |
| 2673 } | 2690 } |
| 2674 if (isNot) { | 2691 if (isNot) { |
| 2675 add(instruction); | 2692 add(instruction); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2899 } else { | 2916 } else { |
| 2900 // Call a helper method from the isolate library. The isolate | 2917 // Call a helper method from the isolate library. The isolate |
| 2901 // library uses its own isolate structure, that encapsulates | 2918 // library uses its own isolate structure, that encapsulates |
| 2902 // Leg's isolate. | 2919 // Leg's isolate. |
| 2903 Element element = compiler.isolateHelperLibrary.find( | 2920 Element element = compiler.isolateHelperLibrary.find( |
| 2904 const SourceString('_currentIsolate')); | 2921 const SourceString('_currentIsolate')); |
| 2905 if (element == null) { | 2922 if (element == null) { |
| 2906 compiler.cancel( | 2923 compiler.cancel( |
| 2907 'Isolate library and compiler mismatch', node: node); | 2924 'Isolate library and compiler mismatch', node: node); |
| 2908 } | 2925 } |
| 2909 pushInvokeHelper0(element); | 2926 pushInvokeHelper0(element, HType.UNKNOWN); |
| 2910 } | 2927 } |
| 2911 } | 2928 } |
| 2912 | 2929 |
| 2913 void handleForeignJsCallInIsolate(Send node) { | 2930 void handleForeignJsCallInIsolate(Send node) { |
| 2914 Link<Node> link = node.arguments; | 2931 Link<Node> link = node.arguments; |
| 2915 if (!compiler.hasIsolateSupport()) { | 2932 if (!compiler.hasIsolateSupport()) { |
| 2916 // If the isolate library is not used, we just invoke the | 2933 // If the isolate library is not used, we just invoke the |
| 2917 // closure. | 2934 // closure. |
| 2918 visit(link.tail.head); | 2935 visit(link.tail.head); |
| 2919 Selector selector = new Selector.callClosure(0); | 2936 Selector selector = new Selector.callClosure(0); |
| 2920 push(new HInvokeClosure(selector, <HInstruction>[pop()])); | 2937 push(new HInvokeClosure(selector, <HInstruction>[pop()])); |
| 2921 } else { | 2938 } else { |
| 2922 // Call a helper method from the isolate library. | 2939 // Call a helper method from the isolate library. |
| 2923 Element element = compiler.isolateHelperLibrary.find( | 2940 Element element = compiler.isolateHelperLibrary.find( |
| 2924 const SourceString('_callInIsolate')); | 2941 const SourceString('_callInIsolate')); |
| 2925 if (element == null) { | 2942 if (element == null) { |
| 2926 compiler.cancel( | 2943 compiler.cancel( |
| 2927 'Isolate library and compiler mismatch', node: node); | 2944 'Isolate library and compiler mismatch', node: node); |
| 2928 } | 2945 } |
| 2929 HStatic target = new HStatic(element); | 2946 HStatic target = new HStatic(element); |
| 2930 add(target); | 2947 add(target); |
| 2931 List<HInstruction> inputs = <HInstruction>[target]; | 2948 List<HInstruction> inputs = <HInstruction>[target]; |
| 2932 addGenericSendArgumentsToList(link, inputs); | 2949 addGenericSendArgumentsToList(link, inputs); |
| 2933 push(new HInvokeStatic(inputs)); | 2950 push(new HInvokeStatic(inputs, HType.UNKNOWN)); |
| 2934 } | 2951 } |
| 2935 } | 2952 } |
| 2936 | 2953 |
| 2937 FunctionSignature handleForeignRawFunctionRef(Send node, String name) { | 2954 FunctionSignature handleForeignRawFunctionRef(Send node, String name) { |
| 2938 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { | 2955 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { |
| 2939 compiler.cancel('"$name" requires exactly one argument', | 2956 compiler.cancel('"$name" requires exactly one argument', |
| 2940 node: node.argumentsNode); | 2957 node: node.argumentsNode); |
| 2941 } | 2958 } |
| 2942 Node closure = node.arguments.head; | 2959 Node closure = node.arguments.head; |
| 2943 Element element = elements[closure]; | 2960 Element element = elements[closure]; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3060 add(argumentNamesInstruction); | 3077 add(argumentNamesInstruction); |
| 3061 | 3078 |
| 3062 Constant kindConstant = | 3079 Constant kindConstant = |
| 3063 constantSystem.createInt(selector.invocationMirrorKind); | 3080 constantSystem.createInt(selector.invocationMirrorKind); |
| 3064 | 3081 |
| 3065 pushInvokeHelper5(createInvocationMirror, | 3082 pushInvokeHelper5(createInvocationMirror, |
| 3066 graph.addConstant(nameConstant), | 3083 graph.addConstant(nameConstant), |
| 3067 graph.addConstant(internalNameConstant), | 3084 graph.addConstant(internalNameConstant), |
| 3068 graph.addConstant(kindConstant), | 3085 graph.addConstant(kindConstant), |
| 3069 argumentsInstruction, | 3086 argumentsInstruction, |
| 3070 argumentNamesInstruction); | 3087 argumentNamesInstruction, |
| 3088 HType.UNKNOWN); |
| 3071 | 3089 |
| 3072 var inputs = <HInstruction>[ | 3090 var inputs = <HInstruction>[ |
| 3073 target, | 3091 target, |
| 3074 self, | 3092 self, |
| 3075 pop()]; | 3093 pop()]; |
| 3076 push(new HInvokeSuper(inputs)); | 3094 push(new HInvokeSuper(inputs)); |
| 3077 } | 3095 } |
| 3078 | 3096 |
| 3079 visitSend(Send node) { | 3097 visitSend(Send node) { |
| 3080 Element element = elements[node]; | 3098 Element element = elements[node]; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3146 member = member.getOutermostEnclosingMemberOrTopLevel(); | 3164 member = member.getOutermostEnclosingMemberOrTopLevel(); |
| 3147 } | 3165 } |
| 3148 if (member.isFactoryConstructor()) { | 3166 if (member.isFactoryConstructor()) { |
| 3149 // The type variable is stored in a parameter of the factory. | 3167 // The type variable is stored in a parameter of the factory. |
| 3150 inputs.add(localsHandler.readLocal(type.element)); | 3168 inputs.add(localsHandler.readLocal(type.element)); |
| 3151 } else if (member.isInstanceMember() | 3169 } else if (member.isInstanceMember() |
| 3152 || member.isGenerativeConstructor()) { | 3170 || member.isGenerativeConstructor()) { |
| 3153 // The type variable is stored in [this]. | 3171 // The type variable is stored in [this]. |
| 3154 if (typeInfo == null) { | 3172 if (typeInfo == null) { |
| 3155 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), | 3173 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), |
| 3156 localsHandler.readThis()); | 3174 localsHandler.readThis(), |
| 3175 HType.UNKNOWN); |
| 3157 typeInfo = pop(); | 3176 typeInfo = pop(); |
| 3158 } | 3177 } |
| 3159 int index = RuntimeTypeInformation.getTypeVariableIndex(type); | 3178 int index = RuntimeTypeInformation.getTypeVariableIndex(type); |
| 3160 HInstruction foreign = createForeign('#[$index]', HType.STRING, | 3179 HInstruction foreign = createForeign('#[$index]', HType.STRING, |
| 3161 <HInstruction>[typeInfo]); | 3180 <HInstruction>[typeInfo]); |
| 3162 add(foreign); | 3181 add(foreign); |
| 3163 inputs.add(foreign); | 3182 inputs.add(foreign); |
| 3164 } else { | 3183 } else { |
| 3165 // TODO(ngeoffray): Match the VM behavior and throw an | 3184 // TODO(ngeoffray): Match the VM behavior and throw an |
| 3166 // exception at runtime. | 3185 // exception at runtime. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3197 } | 3216 } |
| 3198 | 3217 |
| 3199 HInstruction typeInfo = new HLiteralList(rtiInputs); | 3218 HInstruction typeInfo = new HLiteralList(rtiInputs); |
| 3200 add(typeInfo); | 3219 add(typeInfo); |
| 3201 | 3220 |
| 3202 // Set the runtime type information on the object. | 3221 // Set the runtime type information on the object. |
| 3203 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); | 3222 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); |
| 3204 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); | 3223 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); |
| 3205 add(typeInfoSetter); | 3224 add(typeInfoSetter); |
| 3206 add(new HInvokeStatic( | 3225 add(new HInvokeStatic( |
| 3207 <HInstruction>[typeInfoSetter, newObject, typeInfo])); | 3226 <HInstruction>[typeInfoSetter, newObject, typeInfo], HType.UNKNOWN)); |
| 3208 } | 3227 } |
| 3209 | 3228 |
| 3210 /** | 3229 /** |
| 3211 * Documentation wanted -- johnniwinther | 3230 * Documentation wanted -- johnniwinther |
| 3212 * | 3231 * |
| 3213 * Invariant: [type] must not be malformed in checked mode. | 3232 * Invariant: [type] must not be malformed in checked mode. |
| 3214 */ | 3233 */ |
| 3215 visitNewSend(Send node, InterfaceType type) { | 3234 visitNewSend(Send node, InterfaceType type) { |
| 3216 assert(invariant(node, | 3235 assert(invariant(node, |
| 3217 !compiler.enableTypeAssertions || !type.isMalformed, | 3236 !compiler.enableTypeAssertions || !type.isMalformed, |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3327 if (!succeeded) { | 3346 if (!succeeded) { |
| 3328 generateWrongArgumentCountError(node, element, node.arguments); | 3347 generateWrongArgumentCountError(node, element, node.arguments); |
| 3329 return; | 3348 return; |
| 3330 } | 3349 } |
| 3331 | 3350 |
| 3332 if (isIdenticalFunction) { | 3351 if (isIdenticalFunction) { |
| 3333 pushWithPosition(new HIdentity(inputs[1], inputs[2]), node); | 3352 pushWithPosition(new HIdentity(inputs[1], inputs[2]), node); |
| 3334 return; | 3353 return; |
| 3335 } | 3354 } |
| 3336 | 3355 |
| 3337 HInvokeStatic instruction = new HInvokeStatic(inputs); | 3356 HInvokeStatic instruction = new HInvokeStatic(inputs, HType.UNKNOWN); |
| 3338 // TODO(ngeoffray): Only do this if knowing the return type is | 3357 // TODO(ngeoffray): Only do this if knowing the return type is |
| 3339 // useful. | 3358 // useful. |
| 3340 HType returnType = | 3359 HType returnType = |
| 3341 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( | 3360 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( |
| 3342 currentElement, element); | 3361 currentElement, element); |
| 3343 if (returnType != null) instruction.guaranteedType = returnType; | 3362 if (returnType != null) instruction.guaranteedType = returnType; |
| 3344 pushWithPosition(instruction, node); | 3363 pushWithPosition(instruction, node); |
| 3345 } else { | 3364 } else { |
| 3346 generateGetter(node, element); | 3365 generateGetter(node, element); |
| 3347 List<HInstruction> inputs = <HInstruction>[pop()]; | 3366 List<HInstruction> inputs = <HInstruction>[pop()]; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3388 generateGetter(node, elements[node]); | 3407 generateGetter(node, elements[node]); |
| 3389 } | 3408 } |
| 3390 | 3409 |
| 3391 // TODO(antonm): migrate rest of SsaBuilder to internalError. | 3410 // TODO(antonm): migrate rest of SsaBuilder to internalError. |
| 3392 internalError(String reason, {Node node}) { | 3411 internalError(String reason, {Node node}) { |
| 3393 compiler.internalError(reason, node: node); | 3412 compiler.internalError(reason, node: node); |
| 3394 } | 3413 } |
| 3395 | 3414 |
| 3396 void generateError(Node node, String message, Element helper) { | 3415 void generateError(Node node, String message, Element helper) { |
| 3397 HInstruction errorMessage = addConstantString(node, message); | 3416 HInstruction errorMessage = addConstantString(node, message); |
| 3398 pushInvokeHelper1(helper, errorMessage); | 3417 pushInvokeHelper1(helper, errorMessage, HType.UNKNOWN); |
| 3399 } | 3418 } |
| 3400 | 3419 |
| 3401 void generateRuntimeError(Node node, String message) { | 3420 void generateRuntimeError(Node node, String message) { |
| 3402 generateError(node, message, backend.getThrowRuntimeError()); | 3421 generateError(node, message, backend.getThrowRuntimeError()); |
| 3403 } | 3422 } |
| 3404 | 3423 |
| 3405 void generateAbstractClassInstantiationError(Node node, String message) { | 3424 void generateAbstractClassInstantiationError(Node node, String message) { |
| 3406 generateError(node, | 3425 generateError(node, |
| 3407 message, | 3426 message, |
| 3408 backend.getThrowAbstractClassInstantiationError()); | 3427 backend.getThrowAbstractClassInstantiationError()); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3439 HInstruction nameConstant = | 3458 HInstruction nameConstant = |
| 3440 graph.addConstantString(new DartString.literal(name), | 3459 graph.addConstantString(new DartString.literal(name), |
| 3441 diagnosticNode, constantSystem); | 3460 diagnosticNode, constantSystem); |
| 3442 existingNames.add(nameConstant); | 3461 existingNames.add(nameConstant); |
| 3443 } | 3462 } |
| 3444 existingNamesList = new HLiteralList(existingNames); | 3463 existingNamesList = new HLiteralList(existingNames); |
| 3445 add(existingNamesList); | 3464 add(existingNamesList); |
| 3446 } else { | 3465 } else { |
| 3447 existingNamesList = graph.addConstantNull(constantSystem); | 3466 existingNamesList = graph.addConstantNull(constantSystem); |
| 3448 } | 3467 } |
| 3449 pushInvokeHelper4(helper, receiver, name, arguments, existingNamesList); | 3468 pushInvokeHelper4( |
| 3469 helper, receiver, name, arguments, existingNamesList, HType.UNKNOWN); |
| 3450 } | 3470 } |
| 3451 | 3471 |
| 3452 /** | 3472 /** |
| 3453 * Generate code to throw a [NoSuchMethodError] exception for calling a | 3473 * Generate code to throw a [NoSuchMethodError] exception for calling a |
| 3454 * method with a wrong number of arguments or mismatching named optional | 3474 * method with a wrong number of arguments or mismatching named optional |
| 3455 * arguments. | 3475 * arguments. |
| 3456 */ | 3476 */ |
| 3457 void generateWrongArgumentCountError(Node diagnosticNode, | 3477 void generateWrongArgumentCountError(Node diagnosticNode, |
| 3458 FunctionElement function, | 3478 FunctionElement function, |
| 3459 Link<Node> argumentNodes) { | 3479 Link<Node> argumentNodes) { |
| 3460 List<String> existingArguments = <String>[]; | 3480 List<String> existingArguments = <String>[]; |
| 3461 FunctionSignature signature = function.computeSignature(compiler); | 3481 FunctionSignature signature = function.computeSignature(compiler); |
| 3462 signature.forEachParameter((Element parameter) { | 3482 signature.forEachParameter((Element parameter) { |
| 3463 existingArguments.add(parameter.name.slowToString()); | 3483 existingArguments.add(parameter.name.slowToString()); |
| 3464 }); | 3484 }); |
| 3465 generateThrowNoSuchMethod(diagnosticNode, | 3485 generateThrowNoSuchMethod(diagnosticNode, |
| 3466 function.name.slowToString(), | 3486 function.name.slowToString(), |
| 3467 argumentNodes: argumentNodes, | 3487 argumentNodes: argumentNodes, |
| 3468 existingArguments: existingArguments); | 3488 existingArguments: existingArguments); |
| 3469 } | 3489 } |
| 3470 | 3490 |
| 3471 void generateMalformedSubtypeError(Node node, HInstruction value, | 3491 void generateMalformedSubtypeError(Node node, HInstruction value, |
| 3472 DartType type, String reasons) { | 3492 DartType type, String reasons) { |
| 3473 HInstruction typeString = addConstantString(node, type.toString()); | 3493 HInstruction typeString = addConstantString(node, type.toString()); |
| 3474 HInstruction reasonsString = addConstantString(node, reasons); | 3494 HInstruction reasonsString = addConstantString(node, reasons); |
| 3475 Element helper = backend.getThrowMalformedSubtypeError(); | 3495 Element helper = backend.getThrowMalformedSubtypeError(); |
| 3476 pushInvokeHelper3(helper, value, typeString, reasonsString); | 3496 pushInvokeHelper3(helper, value, typeString, reasonsString, HType.UNKNOWN); |
| 3477 } | 3497 } |
| 3478 | 3498 |
| 3479 visitNewExpression(NewExpression node) { | 3499 visitNewExpression(NewExpression node) { |
| 3480 Element element = elements[node.send]; | 3500 Element element = elements[node.send]; |
| 3481 if (!Elements.isErroneousElement(element)) { | 3501 if (!Elements.isErroneousElement(element)) { |
| 3482 FunctionElement function = element; | 3502 FunctionElement function = element; |
| 3483 element = function.redirectionTarget; | 3503 element = function.redirectionTarget; |
| 3484 } | 3504 } |
| 3485 if (Elements.isErroneousElement(element)) { | 3505 if (Elements.isErroneousElement(element)) { |
| 3486 ErroneousElement error = element; | 3506 ErroneousElement error = element; |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3993 List<HInstruction> inputs = <HInstruction>[]; | 4013 List<HInstruction> inputs = <HInstruction>[]; |
| 3994 for (Link<Node> link = node.entries.nodes; | 4014 for (Link<Node> link = node.entries.nodes; |
| 3995 !link.isEmpty; | 4015 !link.isEmpty; |
| 3996 link = link.tail) { | 4016 link = link.tail) { |
| 3997 visit(link.head); | 4017 visit(link.head); |
| 3998 inputs.addLast(pop()); | 4018 inputs.addLast(pop()); |
| 3999 inputs.addLast(pop()); | 4019 inputs.addLast(pop()); |
| 4000 } | 4020 } |
| 4001 HLiteralList keyValuePairs = new HLiteralList(inputs); | 4021 HLiteralList keyValuePairs = new HLiteralList(inputs); |
| 4002 add(keyValuePairs); | 4022 add(keyValuePairs); |
| 4003 pushInvokeHelper1(backend.getMapMaker(), keyValuePairs); | 4023 pushInvokeHelper1(backend.getMapMaker(), keyValuePairs, |
| 4024 new HType.fromBoundedType(compiler.mapClass.computeType(compiler), |
| 4025 compiler, |
| 4026 false)); |
| 4004 } | 4027 } |
| 4005 | 4028 |
| 4006 visitLiteralMapEntry(LiteralMapEntry node) { | 4029 visitLiteralMapEntry(LiteralMapEntry node) { |
| 4007 visit(node.value); | 4030 visit(node.value); |
| 4008 visit(node.key); | 4031 visit(node.key); |
| 4009 } | 4032 } |
| 4010 | 4033 |
| 4011 visitNamedArgument(NamedArgument node) { | 4034 visitNamedArgument(NamedArgument node) { |
| 4012 visit(node.expression); | 4035 visit(node.expression); |
| 4013 } | 4036 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4154 if (switchCase.isDefaultCase) { | 4177 if (switchCase.isDefaultCase) { |
| 4155 // An HSwitch has n inputs and n+1 successors, the last being the | 4178 // An HSwitch has n inputs and n+1 successors, the last being the |
| 4156 // default case. | 4179 // default case. |
| 4157 expressionBlock.addSuccessor(block); | 4180 expressionBlock.addSuccessor(block); |
| 4158 hasDefault = true; | 4181 hasDefault = true; |
| 4159 } | 4182 } |
| 4160 open(block); | 4183 open(block); |
| 4161 localsHandler = new LocalsHandler.from(savedLocals); | 4184 localsHandler = new LocalsHandler.from(savedLocals); |
| 4162 visit(switchCase.statements); | 4185 visit(switchCase.statements); |
| 4163 if (!isAborted() && caseIterator.hasNext) { | 4186 if (!isAborted() && caseIterator.hasNext) { |
| 4164 pushInvokeHelper0(getFallThroughErrorElement); | 4187 pushInvokeHelper0(getFallThroughErrorElement, HType.UNKNOWN); |
| 4165 HInstruction error = pop(); | 4188 HInstruction error = pop(); |
| 4166 close(new HThrow(error)); | 4189 close(new HThrow(error)); |
| 4167 } | 4190 } |
| 4168 statements.add( | 4191 statements.add( |
| 4169 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock))); | 4192 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock))); |
| 4170 } | 4193 } |
| 4171 | 4194 |
| 4172 // Add a join-block if necessary. | 4195 // Add a join-block if necessary. |
| 4173 // We create [joinBlock] early, and then go through the cases that might | 4196 // We create [joinBlock] early, and then go through the cases that might |
| 4174 // want to jump to it. In each case, if we add [joinBlock] as a successor | 4197 // want to jump to it. In each case, if we add [joinBlock] as a successor |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4271 | 4294 |
| 4272 SwitchCase node = cases.head; | 4295 SwitchCase node = cases.head; |
| 4273 // Called for the statements on all but the last case block. | 4296 // Called for the statements on all but the last case block. |
| 4274 // Ensures that a user expecting a fallthrough gets an error. | 4297 // Ensures that a user expecting a fallthrough gets an error. |
| 4275 void visitStatementsAndAbort() { | 4298 void visitStatementsAndAbort() { |
| 4276 visit(node.statements); | 4299 visit(node.statements); |
| 4277 if (!isAborted()) { | 4300 if (!isAborted()) { |
| 4278 compiler.reportWarning(node, 'Missing break at end of switch case'); | 4301 compiler.reportWarning(node, 'Missing break at end of switch case'); |
| 4279 Element element = | 4302 Element element = |
| 4280 compiler.findHelper(const SourceString("getFallThroughError")); | 4303 compiler.findHelper(const SourceString("getFallThroughError")); |
| 4281 pushInvokeHelper0(element); | 4304 pushInvokeHelper0(element, HType.UNKNOWN); |
| 4282 HInstruction error = pop(); | 4305 HInstruction error = pop(); |
| 4283 close(new HThrow(error)); | 4306 close(new HThrow(error)); |
| 4284 } | 4307 } |
| 4285 } | 4308 } |
| 4286 | 4309 |
| 4287 Link<Node> skipLabels(Link<Node> labelsAndCases) { | 4310 Link<Node> skipLabels(Link<Node> labelsAndCases) { |
| 4288 while (!labelsAndCases.isEmpty && labelsAndCases.head is Label) { | 4311 while (!labelsAndCases.isEmpty && labelsAndCases.head is Label) { |
| 4289 labelsAndCases = labelsAndCases.tail; | 4312 labelsAndCases = labelsAndCases.tail; |
| 4290 } | 4313 } |
| 4291 return labelsAndCases; | 4314 return labelsAndCases; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4408 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. | 4431 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. |
| 4409 // Note that the name of this element is irrelevant. | 4432 // Note that the name of this element is irrelevant. |
| 4410 Element element = new ElementX(const SourceString('exception'), | 4433 Element element = new ElementX(const SourceString('exception'), |
| 4411 ElementKind.PARAMETER, | 4434 ElementKind.PARAMETER, |
| 4412 currentElement); | 4435 currentElement); |
| 4413 exception = new HLocalValue(element); | 4436 exception = new HLocalValue(element); |
| 4414 add(exception); | 4437 add(exception); |
| 4415 HInstruction oldRethrowableException = rethrowableException; | 4438 HInstruction oldRethrowableException = rethrowableException; |
| 4416 rethrowableException = exception; | 4439 rethrowableException = exception; |
| 4417 | 4440 |
| 4418 pushInvokeHelper1(backend.getExceptionUnwrapper(), exception); | 4441 pushInvokeHelper1( |
| 4442 backend.getExceptionUnwrapper(), exception, HType.UNKNOWN); |
| 4419 HInvokeStatic unwrappedException = pop(); | 4443 HInvokeStatic unwrappedException = pop(); |
| 4420 tryInstruction.exception = exception; | 4444 tryInstruction.exception = exception; |
| 4421 Link<Node> link = node.catchBlocks.nodes; | 4445 Link<Node> link = node.catchBlocks.nodes; |
| 4422 | 4446 |
| 4423 void pushCondition(CatchBlock catchBlock) { | 4447 void pushCondition(CatchBlock catchBlock) { |
| 4424 if (catchBlock.onKeyword != null) { | 4448 if (catchBlock.onKeyword != null) { |
| 4425 DartType type = elements.getType(catchBlock.type); | 4449 DartType type = elements.getType(catchBlock.type); |
| 4426 if (type == null) { | 4450 if (type == null) { |
| 4427 compiler.cancel('On with unresolved type', | 4451 compiler.cancel('On with unresolved type', |
| 4428 node: catchBlock.type); | 4452 node: catchBlock.type); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 4455 | 4479 |
| 4456 void visitThen() { | 4480 void visitThen() { |
| 4457 CatchBlock catchBlock = link.head; | 4481 CatchBlock catchBlock = link.head; |
| 4458 link = link.tail; | 4482 link = link.tail; |
| 4459 if (catchBlock.exception != null) { | 4483 if (catchBlock.exception != null) { |
| 4460 localsHandler.updateLocal(elements[catchBlock.exception], | 4484 localsHandler.updateLocal(elements[catchBlock.exception], |
| 4461 unwrappedException); | 4485 unwrappedException); |
| 4462 } | 4486 } |
| 4463 Node trace = catchBlock.trace; | 4487 Node trace = catchBlock.trace; |
| 4464 if (trace != null) { | 4488 if (trace != null) { |
| 4465 pushInvokeHelper1(backend.getTraceFromException(), exception); | 4489 pushInvokeHelper1( |
| 4490 backend.getTraceFromException(), exception, HType.UNKNOWN); |
| 4466 HInstruction traceInstruction = pop(); | 4491 HInstruction traceInstruction = pop(); |
| 4467 localsHandler.updateLocal(elements[trace], traceInstruction); | 4492 localsHandler.updateLocal(elements[trace], traceInstruction); |
| 4468 } | 4493 } |
| 4469 visit(catchBlock); | 4494 visit(catchBlock); |
| 4470 } | 4495 } |
| 4471 | 4496 |
| 4472 void visitElse() { | 4497 void visitElse() { |
| 4473 if (link.isEmpty) { | 4498 if (link.isEmpty) { |
| 4474 close(new HThrow(exception, isRethrow: true)); | 4499 close(new HThrow(exception, isRethrow: true)); |
| 4475 } else { | 4500 } else { |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5000 new HSubGraphBlockInformation(elseBranch.graph)); | 5025 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5001 | 5026 |
| 5002 HBasicBlock conditionStartBlock = conditionBranch.block; | 5027 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5003 conditionStartBlock.setBlockFlow(info, joinBlock); | 5028 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5004 SubGraph conditionGraph = conditionBranch.graph; | 5029 SubGraph conditionGraph = conditionBranch.graph; |
| 5005 HIf branch = conditionGraph.end.last; | 5030 HIf branch = conditionGraph.end.last; |
| 5006 assert(branch is HIf); | 5031 assert(branch is HIf); |
| 5007 branch.blockInformation = conditionStartBlock.blockFlow; | 5032 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5008 } | 5033 } |
| 5009 } | 5034 } |
| OLD | NEW |