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 2501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2512 new HType.inferredTypeForElement(element, compiler); | 2512 new HType.inferredTypeForElement(element, compiler); |
2513 push(instruction); | 2513 push(instruction); |
2514 } else { | 2514 } else { |
2515 if (element.isGetter()) { | 2515 if (element.isGetter()) { |
2516 Selector selector = elements.getSelector(send); | 2516 Selector selector = elements.getSelector(send); |
2517 if (tryInlineMethod( | 2517 if (tryInlineMethod( |
2518 element, selector, const Link<Node>(), null, send)) { | 2518 element, selector, const Link<Node>(), null, send)) { |
2519 return; | 2519 return; |
2520 } | 2520 } |
2521 } | 2521 } |
2522 // TODO(5346): Try to avoid the need for calling [declaration] before | |
2523 // creating an [HStatic]. | |
2524 HInstruction instruction = new HStatic(element.declaration); | |
2525 if (element.isGetter()) { | 2522 if (element.isGetter()) { |
2526 add(instruction); | 2523 push(buildInvokeStatic(element, <HInstruction>[])); |
2527 instruction = buildInvokeStatic(<HInstruction>[instruction]); | |
2528 push(instruction); | |
2529 } else { | 2524 } else { |
| 2525 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 2526 // creating an [HStatic]. |
| 2527 HInstruction instruction = new HStatic(element.declaration); |
2530 instruction.instructionType = | 2528 instruction.instructionType = |
2531 new HType.inferredTypeForElement(element, compiler); | 2529 new HType.inferredTypeForElement(element, compiler); |
2532 push(instruction); | 2530 push(instruction); |
2533 } | 2531 } |
2534 } | 2532 } |
2535 } else if (Elements.isInstanceSend(send, elements)) { | 2533 } else if (Elements.isInstanceSend(send, elements)) { |
2536 HInstruction receiver = generateInstanceSendReceiver(send); | 2534 HInstruction receiver = generateInstanceSendReceiver(send); |
2537 generateInstanceGetterWithCompiledReceiver( | 2535 generateInstanceGetterWithCompiledReceiver( |
2538 send, elements.getSelector(send), receiver); | 2536 send, elements.getSelector(send), receiver); |
2539 } else if (Elements.isStaticOrTopLevelFunction(element)) { | 2537 } else if (Elements.isStaticOrTopLevelFunction(element)) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2576 Element element, | 2574 Element element, |
2577 HInstruction value, | 2575 HInstruction value, |
2578 {Node location}) { | 2576 {Node location}) { |
2579 assert(send == null || !Elements.isInstanceSend(send, elements)); | 2577 assert(send == null || !Elements.isInstanceSend(send, elements)); |
2580 if (location == null) { | 2578 if (location == null) { |
2581 assert(send != null); | 2579 assert(send != null); |
2582 location = send; | 2580 location = send; |
2583 } | 2581 } |
2584 if (Elements.isStaticOrTopLevelField(element)) { | 2582 if (Elements.isStaticOrTopLevelField(element)) { |
2585 if (element.isSetter()) { | 2583 if (element.isSetter()) { |
2586 HStatic target = new HStatic(element); | 2584 var instruction = buildInvokeStatic(element, |
2587 add(target); | 2585 <HInstruction>[value], HType.UNKNOWN); |
2588 var instruction = buildInvokeStatic( | |
2589 <HInstruction>[target, value], HType.UNKNOWN); | |
2590 addWithPosition(instruction, location); | 2586 addWithPosition(instruction, location); |
2591 } else { | 2587 } else { |
2592 value = potentiallyCheckType(value, element.computeType(compiler)); | 2588 value = potentiallyCheckType(value, element.computeType(compiler)); |
2593 addWithPosition(new HStaticStore(element, value), location); | 2589 addWithPosition(new HStaticStore(element, value), location); |
2594 } | 2590 } |
2595 stack.add(value); | 2591 stack.add(value); |
2596 } else if (Elements.isErroneousElement(element)) { | 2592 } else if (Elements.isErroneousElement(element)) { |
2597 // An erroneous element indicates an unresolved static setter. | 2593 // An erroneous element indicates an unresolved static setter. |
2598 generateThrowNoSuchMethod( | 2594 generateThrowNoSuchMethod( |
2599 location, | 2595 location, |
(...skipping 16 matching lines...) Expand all Loading... |
2616 } | 2612 } |
2617 | 2613 |
2618 HInstruction invokeInterceptor(Set<ClassElement> intercepted, | 2614 HInstruction invokeInterceptor(Set<ClassElement> intercepted, |
2619 HInstruction receiver) { | 2615 HInstruction receiver) { |
2620 HInterceptor interceptor = new HInterceptor(intercepted, receiver); | 2616 HInterceptor interceptor = new HInterceptor(intercepted, receiver); |
2621 add(interceptor); | 2617 add(interceptor); |
2622 return interceptor; | 2618 return interceptor; |
2623 } | 2619 } |
2624 | 2620 |
2625 void pushInvokeHelper0(Element helper, HType type) { | 2621 void pushInvokeHelper0(Element helper, HType type) { |
2626 HInstruction reference = new HStatic(helper); | 2622 List<HInstruction> inputs = <HInstruction>[]; |
2627 add(reference); | 2623 push(buildInvokeStatic(helper, inputs, type)); |
2628 List<HInstruction> inputs = <HInstruction>[reference]; | |
2629 push(buildInvokeStatic(inputs, type)); | |
2630 } | 2624 } |
2631 | 2625 |
2632 void pushInvokeHelper1(Element helper, HInstruction a0, HType type) { | 2626 void pushInvokeHelper1(Element helper, HInstruction a0, HType type) { |
2633 HInstruction reference = new HStatic(helper); | 2627 List<HInstruction> inputs = <HInstruction>[a0]; |
2634 add(reference); | 2628 push(buildInvokeStatic(helper, inputs, type)); |
2635 List<HInstruction> inputs = <HInstruction>[reference, a0]; | |
2636 push(buildInvokeStatic(inputs, type)); | |
2637 } | 2629 } |
2638 | 2630 |
2639 void pushInvokeHelper2(Element helper, | 2631 void pushInvokeHelper2(Element helper, |
2640 HInstruction a0, | 2632 HInstruction a0, |
2641 HInstruction a1, | 2633 HInstruction a1, |
2642 HType type) { | 2634 HType type) { |
2643 HInstruction reference = new HStatic(helper); | 2635 List<HInstruction> inputs = <HInstruction>[a0, a1]; |
2644 add(reference); | 2636 push(buildInvokeStatic(helper, inputs, type)); |
2645 List<HInstruction> inputs = <HInstruction>[reference, a0, a1]; | |
2646 push(buildInvokeStatic(inputs, type)); | |
2647 } | 2637 } |
2648 | 2638 |
2649 void pushInvokeHelper3(Element helper, | 2639 void pushInvokeHelper3(Element helper, |
2650 HInstruction a0, | 2640 HInstruction a0, |
2651 HInstruction a1, | 2641 HInstruction a1, |
2652 HInstruction a2, | 2642 HInstruction a2, |
2653 HType type) { | 2643 HType type) { |
2654 HInstruction reference = new HStatic(helper); | 2644 List<HInstruction> inputs = <HInstruction>[a0, a1, a2]; |
2655 add(reference); | 2645 push(buildInvokeStatic(helper, inputs, type)); |
2656 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2]; | |
2657 push(buildInvokeStatic(inputs, type)); | |
2658 } | 2646 } |
2659 | 2647 |
2660 void pushInvokeHelper4(Element helper, | 2648 void pushInvokeHelper4(Element helper, |
2661 HInstruction a0, | 2649 HInstruction a0, |
2662 HInstruction a1, | 2650 HInstruction a1, |
2663 HInstruction a2, | 2651 HInstruction a2, |
2664 HInstruction a3, | 2652 HInstruction a3, |
2665 HType type) { | 2653 HType type) { |
2666 HInstruction reference = new HStatic(helper); | 2654 List<HInstruction> inputs = <HInstruction>[a0, a1, a2, a3]; |
2667 add(reference); | 2655 push(buildInvokeStatic(helper, inputs, type)); |
2668 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3]; | |
2669 push(buildInvokeStatic(inputs, type)); | |
2670 } | 2656 } |
2671 | 2657 |
2672 void pushInvokeHelper5(Element helper, | 2658 void pushInvokeHelper5(Element helper, |
2673 HInstruction a0, | 2659 HInstruction a0, |
2674 HInstruction a1, | 2660 HInstruction a1, |
2675 HInstruction a2, | 2661 HInstruction a2, |
2676 HInstruction a3, | 2662 HInstruction a3, |
2677 HInstruction a4, | 2663 HInstruction a4, |
2678 HType type) { | 2664 HType type) { |
2679 HInstruction reference = new HStatic(helper); | 2665 List<HInstruction> inputs = <HInstruction>[a0, a1, a2, a3, a4]; |
2680 add(reference); | 2666 push(buildInvokeStatic(helper, inputs, type)); |
2681 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3, a4]; | |
2682 push(buildInvokeStatic(inputs, type)); | |
2683 } | 2667 } |
2684 | 2668 |
2685 HForeign createForeign(String code, | 2669 HForeign createForeign(String code, |
2686 HType type, | 2670 HType type, |
2687 List<HInstruction> inputs) { | 2671 List<HInstruction> inputs) { |
2688 return new HForeign(js.js.parseForeignJS(code), type, inputs); | 2672 return new HForeign(js.js.parseForeignJS(code), type, inputs); |
2689 } | 2673 } |
2690 | 2674 |
2691 HInstruction getRuntimeTypeInfo(HInstruction target) { | 2675 HInstruction getRuntimeTypeInfo(HInstruction target) { |
2692 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); | 2676 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2771 } else { | 2755 } else { |
2772 generateRuntimeError(node, '$type is malformed: $reasons'); | 2756 generateRuntimeError(node, '$type is malformed: $reasons'); |
2773 } | 2757 } |
2774 return; | 2758 return; |
2775 } | 2759 } |
2776 | 2760 |
2777 HInstruction instruction; | 2761 HInstruction instruction; |
2778 if (type.kind == TypeKind.TYPE_VARIABLE) { | 2762 if (type.kind == TypeKind.TYPE_VARIABLE) { |
2779 HInstruction runtimeType = addTypeVariableReference(type); | 2763 HInstruction runtimeType = addTypeVariableReference(type); |
2780 Element helper = backend.getGetObjectIsSubtype(); | 2764 Element helper = backend.getGetObjectIsSubtype(); |
2781 HInstruction helperCall = new HStatic(helper); | 2765 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; |
2782 add(helperCall); | 2766 HInstruction call = buildInvokeStatic(helper, inputs, HType.BOOLEAN); |
2783 List<HInstruction> inputs = <HInstruction>[helperCall, expression, | |
2784 runtimeType]; | |
2785 HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN); | |
2786 add(call); | 2767 add(call); |
2787 instruction = new HIs(type, <HInstruction>[expression, call], | 2768 instruction = new HIs(type, <HInstruction>[expression, call], |
2788 HIs.VARIABLE_CHECK); | 2769 HIs.VARIABLE_CHECK); |
2789 } else if (RuntimeTypes.hasTypeArguments(type)) { | 2770 } else if (RuntimeTypes.hasTypeArguments(type)) { |
2790 Element element = type.element; | 2771 Element element = type.element; |
2791 Element helper = backend.getCheckSubtype(); | 2772 Element helper = backend.getCheckSubtype(); |
2792 HInstruction helperCall = new HStatic(helper); | |
2793 add(helperCall); | |
2794 HInstruction representations = | 2773 HInstruction representations = |
2795 buildTypeArgumentRepresentations(type); | 2774 buildTypeArgumentRepresentations(type); |
2796 add(representations); | 2775 add(representations); |
2797 String operator = | 2776 String operator = |
2798 backend.namer.operatorIs(backend.getImplementationClass(element)); | 2777 backend.namer.operatorIs(backend.getImplementationClass(element)); |
2799 HInstruction isFieldName = addConstantString(node, operator); | 2778 HInstruction isFieldName = addConstantString(node, operator); |
2800 // TODO(karlklose): use [:null:] for [asField] if [element] does not | 2779 // TODO(karlklose): use [:null:] for [asField] if [element] does not |
2801 // have a subclass. | 2780 // have a subclass. |
2802 HInstruction asFieldName = | 2781 HInstruction asFieldName = |
2803 addConstantString(node, backend.namer.substitutionName(element)); | 2782 addConstantString(node, backend.namer.substitutionName(element)); |
2804 List<HInstruction> inputs = <HInstruction>[helperCall, | 2783 List<HInstruction> inputs = <HInstruction>[expression, |
2805 expression, | |
2806 isFieldName, | 2784 isFieldName, |
2807 representations, | 2785 representations, |
2808 asFieldName]; | 2786 asFieldName]; |
2809 HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN); | 2787 HInstruction call = buildInvokeStatic(helper, inputs, HType.BOOLEAN); |
2810 add(call); | 2788 add(call); |
2811 instruction = new HIs(type, <HInstruction>[expression, call], | 2789 instruction = new HIs(type, <HInstruction>[expression, call], |
2812 HIs.COMPOUND_CHECK); | 2790 HIs.COMPOUND_CHECK); |
2813 } else { | 2791 } else { |
2814 instruction = new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); | 2792 instruction = new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); |
2815 } | 2793 } |
2816 if (isNot) { | 2794 if (isNot) { |
2817 add(instruction); | 2795 add(instruction); |
2818 instruction = new HNot(instruction); | 2796 instruction = new HNot(instruction); |
2819 } | 2797 } |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2994 Selector selector = new Selector.callClosure(0); | 2972 Selector selector = new Selector.callClosure(0); |
2995 push(new HInvokeClosure(selector, <HInstruction>[pop()])); | 2973 push(new HInvokeClosure(selector, <HInstruction>[pop()])); |
2996 } else { | 2974 } else { |
2997 // Call a helper method from the isolate library. | 2975 // Call a helper method from the isolate library. |
2998 Element element = compiler.isolateHelperLibrary.find( | 2976 Element element = compiler.isolateHelperLibrary.find( |
2999 const SourceString('_callInIsolate')); | 2977 const SourceString('_callInIsolate')); |
3000 if (element == null) { | 2978 if (element == null) { |
3001 compiler.cancel( | 2979 compiler.cancel( |
3002 'Isolate library and compiler mismatch', node: node); | 2980 'Isolate library and compiler mismatch', node: node); |
3003 } | 2981 } |
3004 HStatic target = new HStatic(element); | 2982 List<HInstruction> inputs = <HInstruction>[]; |
3005 add(target); | |
3006 List<HInstruction> inputs = <HInstruction>[target]; | |
3007 addGenericSendArgumentsToList(link, inputs); | 2983 addGenericSendArgumentsToList(link, inputs); |
3008 push(buildInvokeStatic(inputs, HType.UNKNOWN)); | 2984 push(buildInvokeStatic(element, inputs, HType.UNKNOWN)); |
3009 } | 2985 } |
3010 } | 2986 } |
3011 | 2987 |
3012 FunctionSignature handleForeignRawFunctionRef(Send node, String name) { | 2988 FunctionSignature handleForeignRawFunctionRef(Send node, String name) { |
3013 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { | 2989 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { |
3014 compiler.cancel('"$name" requires exactly one argument', | 2990 compiler.cancel('"$name" requires exactly one argument', |
3015 node: node.argumentsNode); | 2991 node: node.argumentsNode); |
3016 } | 2992 } |
3017 Node closure = node.arguments.head; | 2993 Node closure = node.arguments.head; |
3018 Element element = elements[closure]; | 2994 Element element = elements[closure]; |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3297 HInstruction newObject) { | 3273 HInstruction newObject) { |
3298 if (!backend.needsRti(element) || element.typeVariables.isEmpty) { | 3274 if (!backend.needsRti(element) || element.typeVariables.isEmpty) { |
3299 return; | 3275 return; |
3300 } | 3276 } |
3301 | 3277 |
3302 HInstruction typeInfo = new HLiteralList(rtiInputs); | 3278 HInstruction typeInfo = new HLiteralList(rtiInputs); |
3303 add(typeInfo); | 3279 add(typeInfo); |
3304 | 3280 |
3305 // Set the runtime type information on the object. | 3281 // Set the runtime type information on the object. |
3306 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); | 3282 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); |
3307 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); | 3283 add(buildInvokeStatic(typeInfoSetterElement, |
3308 add(typeInfoSetter); | 3284 <HInstruction>[newObject, typeInfo], HType.UNKNOWN)); |
3309 add(buildInvokeStatic( | |
3310 <HInstruction>[typeInfoSetter, newObject, typeInfo], HType.UNKNOWN)); | |
3311 } | 3285 } |
3312 | 3286 |
3313 /** | 3287 /** |
3314 * Documentation wanted -- johnniwinther | 3288 * Documentation wanted -- johnniwinther |
3315 * | 3289 * |
3316 * Invariant: [type] must not be malformed in checked mode. | 3290 * Invariant: [type] must not be malformed in checked mode. |
3317 */ | 3291 */ |
3318 visitNewSend(Send node, InterfaceType type) { | 3292 visitNewSend(Send node, InterfaceType type) { |
3319 assert(invariant(node, | 3293 assert(invariant(node, |
3320 !compiler.enableTypeAssertions || !type.isMalformed, | 3294 !compiler.enableTypeAssertions || !type.isMalformed, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3354 | 3328 |
3355 if (isSymbolConstructor) { | 3329 if (isSymbolConstructor) { |
3356 constructor = compiler.symbolValidatedConstructor; | 3330 constructor = compiler.symbolValidatedConstructor; |
3357 assert(invariant(node, constructor != null, | 3331 assert(invariant(node, constructor != null, |
3358 message: 'Constructor Symbol.validated is missing')); | 3332 message: 'Constructor Symbol.validated is missing')); |
3359 selector = compiler.symbolValidatedConstructorSelector; | 3333 selector = compiler.symbolValidatedConstructorSelector; |
3360 assert(invariant(node, selector != null, | 3334 assert(invariant(node, selector != null, |
3361 message: 'Constructor Symbol.validated is missing')); | 3335 message: 'Constructor Symbol.validated is missing')); |
3362 } | 3336 } |
3363 | 3337 |
3364 // TODO(5346): Try to avoid the need for calling [declaration] before | |
3365 // creating an [HStatic]. | |
3366 HInstruction target = new HStatic(constructor.declaration); | |
3367 add(target); | |
3368 var inputs = <HInstruction>[]; | 3338 var inputs = <HInstruction>[]; |
3369 inputs.add(target); | |
3370 // TODO(5347): Try to avoid the need for calling [implementation] before | 3339 // TODO(5347): Try to avoid the need for calling [implementation] before |
3371 // calling [addStaticSendArgumentsToList]. | 3340 // calling [addStaticSendArgumentsToList]. |
3372 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 3341 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
3373 constructor.implementation, | 3342 constructor.implementation, |
3374 inputs); | 3343 inputs); |
3375 if (!succeeded) { | 3344 if (!succeeded) { |
3376 generateWrongArgumentCountError(node, constructor, node.arguments); | 3345 generateWrongArgumentCountError(node, constructor, node.arguments); |
3377 return; | 3346 return; |
3378 } | 3347 } |
3379 | 3348 |
(...skipping 13 matching lines...) Expand all Loading... |
3393 while (!typeVariable.isEmpty) { | 3362 while (!typeVariable.isEmpty) { |
3394 inputs.add(graph.addConstantNull(constantSystem)); | 3363 inputs.add(graph.addConstantNull(constantSystem)); |
3395 typeVariable = typeVariable.tail; | 3364 typeVariable = typeVariable.tail; |
3396 } | 3365 } |
3397 } | 3366 } |
3398 | 3367 |
3399 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { | 3368 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { |
3400 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); | 3369 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); |
3401 } | 3370 } |
3402 HType elementType = computeType(constructor); | 3371 HType elementType = computeType(constructor); |
3403 HInstruction newInstance = buildInvokeStatic(inputs, elementType); | 3372 HInstruction newInstance = |
| 3373 buildInvokeStatic(constructor, inputs, elementType); |
3404 pushWithPosition(newInstance, node); | 3374 pushWithPosition(newInstance, node); |
3405 | 3375 |
3406 // The List constructor forwards to a Dart static method that does | 3376 // The List constructor forwards to a Dart static method that does |
3407 // not know about the type argument. Therefore we special case | 3377 // not know about the type argument. Therefore we special case |
3408 // this constructor to have the setRuntimeTypeInfo called where | 3378 // this constructor to have the setRuntimeTypeInfo called where |
3409 // the 'new' is done. | 3379 // the 'new' is done. |
3410 if (isListConstructor && backend.needsRti(compiler.listClass)) { | 3380 if (isListConstructor && backend.needsRti(compiler.listClass)) { |
3411 handleListConstructor(type, node, newInstance); | 3381 handleListConstructor(type, node, newInstance); |
3412 } | 3382 } |
3413 } | 3383 } |
(...skipping 18 matching lines...) Expand all Loading... |
3432 } | 3402 } |
3433 compiler.ensure(!element.isGenerativeConstructor()); | 3403 compiler.ensure(!element.isGenerativeConstructor()); |
3434 if (element.isFunction()) { | 3404 if (element.isFunction()) { |
3435 bool isIdenticalFunction = element == compiler.identicalFunction; | 3405 bool isIdenticalFunction = element == compiler.identicalFunction; |
3436 | 3406 |
3437 if (!isIdenticalFunction | 3407 if (!isIdenticalFunction |
3438 && tryInlineMethod(element, selector, node.arguments, null, node)) { | 3408 && tryInlineMethod(element, selector, node.arguments, null, node)) { |
3439 return; | 3409 return; |
3440 } | 3410 } |
3441 | 3411 |
3442 HInstruction target = new HStatic(element); | 3412 var inputs = <HInstruction>[]; |
3443 add(target); | |
3444 var inputs = <HInstruction>[target]; | |
3445 // TODO(5347): Try to avoid the need for calling [implementation] before | 3413 // TODO(5347): Try to avoid the need for calling [implementation] before |
3446 // calling [addStaticSendArgumentsToList]. | 3414 // calling [addStaticSendArgumentsToList]. |
3447 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 3415 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
3448 element.implementation, | 3416 element.implementation, |
3449 inputs); | 3417 inputs); |
3450 if (!succeeded) { | 3418 if (!succeeded) { |
3451 generateWrongArgumentCountError(node, element, node.arguments); | 3419 generateWrongArgumentCountError(node, element, node.arguments); |
3452 return; | 3420 return; |
3453 } | 3421 } |
3454 | 3422 |
3455 if (isIdenticalFunction) { | 3423 if (isIdenticalFunction) { |
3456 pushWithPosition(new HIdentity(inputs[1], inputs[2]), node); | 3424 pushWithPosition(new HIdentity(inputs[0], inputs[1]), node); |
3457 return; | 3425 return; |
3458 } | 3426 } |
3459 | 3427 |
3460 HInvokeStatic instruction = buildInvokeStatic(inputs, HType.UNKNOWN); | 3428 HInvokeStatic instruction = |
| 3429 buildInvokeStatic(element, inputs, HType.UNKNOWN); |
3461 HType returnType = | 3430 HType returnType = |
3462 new HType.inferredReturnTypeForElement(element, compiler); | 3431 new HType.inferredReturnTypeForElement(element, compiler); |
3463 if (returnType.isUnknown()) { | 3432 if (returnType.isUnknown()) { |
3464 // TODO(ngeoffray): Only do this if knowing the return type is | 3433 // TODO(ngeoffray): Only do this if knowing the return type is |
3465 // useful. | 3434 // useful. |
3466 returnType = | 3435 returnType = |
3467 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( | 3436 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( |
3468 currentElement, element); | 3437 currentElement, element); |
3469 } | 3438 } |
3470 if (returnType != null) instruction.instructionType = returnType; | 3439 if (returnType != null) instruction.instructionType = returnType; |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3725 pushWithPosition( | 3694 pushWithPosition( |
3726 new HInvokeDynamicSetter(selector, null, inputs, !hasSetter), | 3695 new HInvokeDynamicSetter(selector, null, inputs, !hasSetter), |
3727 location); | 3696 location); |
3728 } else { | 3697 } else { |
3729 pushWithPosition( | 3698 pushWithPosition( |
3730 new HInvokeDynamicMethod(selector, inputs, isIntercepted), | 3699 new HInvokeDynamicMethod(selector, inputs, isIntercepted), |
3731 location); | 3700 location); |
3732 } | 3701 } |
3733 } | 3702 } |
3734 | 3703 |
3735 HInstruction buildInvokeStatic(List<HInstruction> inputs, | 3704 HInstruction buildInvokeStatic(Element element, |
| 3705 List<HInstruction> inputs, |
3736 [HType type = null]) { | 3706 [HType type = null]) { |
3737 HStatic staticInstruction = inputs[0]; | |
3738 Element element = staticInstruction.element; | |
3739 if (type == null) { | 3707 if (type == null) { |
3740 type = new HType.inferredReturnTypeForElement(element, compiler); | 3708 type = new HType.inferredReturnTypeForElement(element, compiler); |
3741 } | 3709 } |
3742 HInstruction instruction = new HInvokeStatic(inputs, type); | 3710 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 3711 // creating an [HInvokeStatic]. |
| 3712 HInstruction instruction = |
| 3713 new HInvokeStatic(element.declaration, inputs, type); |
3743 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); | 3714 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); |
3744 return instruction; | 3715 return instruction; |
3745 } | 3716 } |
3746 | 3717 |
3747 HInstruction buildInvokeSuper(Selector selector, | 3718 HInstruction buildInvokeSuper(Selector selector, |
3748 Element element, | 3719 Element element, |
3749 List<HInstruction> arguments) { | 3720 List<HInstruction> arguments) { |
3750 HInstruction receiver = localsHandler.readThis(); | 3721 HInstruction receiver = localsHandler.readThis(); |
3751 // TODO(5346): Try to avoid the need for calling [declaration] before | 3722 // TODO(5346): Try to avoid the need for calling [declaration] before |
3752 // creating an [HStatic]. | 3723 // creating an [HStatic]. |
3753 HInstruction target = new HStatic(element.declaration); | 3724 List<HInstruction> inputs = <HInstruction>[]; |
3754 add(target); | |
3755 List<HInstruction> inputs = <HInstruction>[target]; | |
3756 Set<ClassElement> interceptedClasses = | 3725 Set<ClassElement> interceptedClasses = |
3757 backend.getInterceptedClassesOn(selector.name); | 3726 backend.getInterceptedClassesOn(selector.name); |
3758 if (interceptedClasses != null) { | 3727 if (interceptedClasses != null) { |
3759 inputs.add(invokeInterceptor(interceptedClasses, receiver)); | 3728 inputs.add(invokeInterceptor(interceptedClasses, receiver)); |
3760 } | 3729 } |
3761 inputs.add(receiver); | 3730 inputs.add(receiver); |
3762 inputs.addAll(arguments); | 3731 inputs.addAll(arguments); |
3763 HInstruction instruction = new HInvokeSuper( | 3732 HInstruction instruction = new HInvokeSuper( |
| 3733 element, |
3764 currentNonClosureClass, | 3734 currentNonClosureClass, |
3765 inputs, | 3735 inputs, |
3766 isSetter: selector.isSetter() || selector.isIndexSet()); | 3736 isSetter: selector.isSetter() || selector.isIndexSet()); |
3767 instruction.instructionType = | 3737 instruction.instructionType = |
3768 new HType.inferredReturnTypeForElement(element, compiler); | 3738 new HType.inferredReturnTypeForElement(element, compiler); |
3769 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); | 3739 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); |
3770 return instruction; | 3740 return instruction; |
3771 } | 3741 } |
3772 | 3742 |
3773 void handleComplexOperatorSend(SendSet node, | 3743 void handleComplexOperatorSend(SendSet node, |
(...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5291 new HSubGraphBlockInformation(elseBranch.graph)); | 5261 new HSubGraphBlockInformation(elseBranch.graph)); |
5292 | 5262 |
5293 HBasicBlock conditionStartBlock = conditionBranch.block; | 5263 HBasicBlock conditionStartBlock = conditionBranch.block; |
5294 conditionStartBlock.setBlockFlow(info, joinBlock); | 5264 conditionStartBlock.setBlockFlow(info, joinBlock); |
5295 SubGraph conditionGraph = conditionBranch.graph; | 5265 SubGraph conditionGraph = conditionBranch.graph; |
5296 HIf branch = conditionGraph.end.last; | 5266 HIf branch = conditionGraph.end.last; |
5297 assert(branch is HIf); | 5267 assert(branch is HIf); |
5298 branch.blockInformation = conditionStartBlock.blockFlow; | 5268 branch.blockInformation = conditionStartBlock.blockFlow; |
5299 } | 5269 } |
5300 } | 5270 } |
OLD | NEW |