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 2497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2508 new HType.inferredTypeForElement(element, compiler); | 2508 new HType.inferredTypeForElement(element, compiler); |
2509 push(instruction); | 2509 push(instruction); |
2510 } else { | 2510 } else { |
2511 if (element.isGetter()) { | 2511 if (element.isGetter()) { |
2512 Selector selector = elements.getSelector(send); | 2512 Selector selector = elements.getSelector(send); |
2513 if (tryInlineMethod( | 2513 if (tryInlineMethod( |
2514 element, selector, const Link<Node>(), null, send)) { | 2514 element, selector, const Link<Node>(), null, send)) { |
2515 return; | 2515 return; |
2516 } | 2516 } |
2517 } | 2517 } |
2518 // TODO(5346): Try to avoid the need for calling [declaration] before | |
2519 // creating an [HStatic]. | |
2520 HInstruction instruction = new HStatic(element.declaration); | |
2521 if (element.isGetter()) { | 2518 if (element.isGetter()) { |
2522 add(instruction); | 2519 push(buildInvokeStatic(element, <HInstruction>[])); |
2523 instruction = buildInvokeStatic(<HInstruction>[instruction]); | |
2524 push(instruction); | |
2525 } else { | 2520 } else { |
| 2521 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 2522 // creating an [HStatic]. |
| 2523 HInstruction instruction = new HStatic(element.declaration); |
2526 instruction.instructionType = | 2524 instruction.instructionType = |
2527 new HType.inferredTypeForElement(element, compiler); | 2525 new HType.inferredTypeForElement(element, compiler); |
2528 push(instruction); | 2526 push(instruction); |
2529 } | 2527 } |
2530 } | 2528 } |
2531 } else if (Elements.isInstanceSend(send, elements)) { | 2529 } else if (Elements.isInstanceSend(send, elements)) { |
2532 HInstruction receiver = generateInstanceSendReceiver(send); | 2530 HInstruction receiver = generateInstanceSendReceiver(send); |
2533 generateInstanceGetterWithCompiledReceiver( | 2531 generateInstanceGetterWithCompiledReceiver( |
2534 send, elements.getSelector(send), receiver); | 2532 send, elements.getSelector(send), receiver); |
2535 } else if (Elements.isStaticOrTopLevelFunction(element)) { | 2533 } else if (Elements.isStaticOrTopLevelFunction(element)) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2573 Element element, | 2571 Element element, |
2574 HInstruction value, | 2572 HInstruction value, |
2575 {Node location}) { | 2573 {Node location}) { |
2576 assert(send == null || !Elements.isInstanceSend(send, elements)); | 2574 assert(send == null || !Elements.isInstanceSend(send, elements)); |
2577 if (location == null) { | 2575 if (location == null) { |
2578 assert(send != null); | 2576 assert(send != null); |
2579 location = send; | 2577 location = send; |
2580 } | 2578 } |
2581 if (Elements.isStaticOrTopLevelField(element)) { | 2579 if (Elements.isStaticOrTopLevelField(element)) { |
2582 if (element.isSetter()) { | 2580 if (element.isSetter()) { |
2583 HStatic target = new HStatic(element); | 2581 var instruction = buildInvokeStatic(element, |
2584 add(target); | 2582 <HInstruction>[value], HType.UNKNOWN); |
2585 var instruction = buildInvokeStatic( | |
2586 <HInstruction>[target, value], HType.UNKNOWN); | |
2587 addWithPosition(instruction, location); | 2583 addWithPosition(instruction, location); |
2588 } else { | 2584 } else { |
2589 value = potentiallyCheckType(value, element.computeType(compiler)); | 2585 value = potentiallyCheckType(value, element.computeType(compiler)); |
2590 addWithPosition(new HStaticStore(element, value), location); | 2586 addWithPosition(new HStaticStore(element, value), location); |
2591 } | 2587 } |
2592 stack.add(value); | 2588 stack.add(value); |
2593 } else if (Elements.isErroneousElement(element)) { | 2589 } else if (Elements.isErroneousElement(element)) { |
2594 // An erroneous element indicates an unresolved static setter. | 2590 // An erroneous element indicates an unresolved static setter. |
2595 generateThrowNoSuchMethod( | 2591 generateThrowNoSuchMethod( |
2596 location, | 2592 location, |
(...skipping 16 matching lines...) Expand all Loading... |
2613 } | 2609 } |
2614 | 2610 |
2615 HInstruction invokeInterceptor(Set<ClassElement> intercepted, | 2611 HInstruction invokeInterceptor(Set<ClassElement> intercepted, |
2616 HInstruction receiver) { | 2612 HInstruction receiver) { |
2617 HInterceptor interceptor = new HInterceptor(intercepted, receiver); | 2613 HInterceptor interceptor = new HInterceptor(intercepted, receiver); |
2618 add(interceptor); | 2614 add(interceptor); |
2619 return interceptor; | 2615 return interceptor; |
2620 } | 2616 } |
2621 | 2617 |
2622 void pushInvokeHelper0(Element helper, HType type) { | 2618 void pushInvokeHelper0(Element helper, HType type) { |
2623 HInstruction reference = new HStatic(helper); | 2619 List<HInstruction> inputs = <HInstruction>[]; |
2624 add(reference); | 2620 push(buildInvokeStatic(helper, inputs, type)); |
2625 List<HInstruction> inputs = <HInstruction>[reference]; | |
2626 push(buildInvokeStatic(inputs, type)); | |
2627 } | 2621 } |
2628 | 2622 |
2629 void pushInvokeHelper1(Element helper, HInstruction a0, HType type) { | 2623 void pushInvokeHelper1(Element helper, HInstruction a0, HType type) { |
2630 HInstruction reference = new HStatic(helper); | 2624 List<HInstruction> inputs = <HInstruction>[a0]; |
2631 add(reference); | 2625 push(buildInvokeStatic(helper, inputs, type)); |
2632 List<HInstruction> inputs = <HInstruction>[reference, a0]; | |
2633 push(buildInvokeStatic(inputs, type)); | |
2634 } | 2626 } |
2635 | 2627 |
2636 void pushInvokeHelper2(Element helper, | 2628 void pushInvokeHelper2(Element helper, |
2637 HInstruction a0, | 2629 HInstruction a0, |
2638 HInstruction a1, | 2630 HInstruction a1, |
2639 HType type) { | 2631 HType type) { |
2640 HInstruction reference = new HStatic(helper); | 2632 List<HInstruction> inputs = <HInstruction>[a0, a1]; |
2641 add(reference); | 2633 push(buildInvokeStatic(helper, inputs, type)); |
2642 List<HInstruction> inputs = <HInstruction>[reference, a0, a1]; | |
2643 push(buildInvokeStatic(inputs, type)); | |
2644 } | 2634 } |
2645 | 2635 |
2646 void pushInvokeHelper3(Element helper, | 2636 void pushInvokeHelper3(Element helper, |
2647 HInstruction a0, | 2637 HInstruction a0, |
2648 HInstruction a1, | 2638 HInstruction a1, |
2649 HInstruction a2, | 2639 HInstruction a2, |
2650 HType type) { | 2640 HType type) { |
2651 HInstruction reference = new HStatic(helper); | 2641 List<HInstruction> inputs = <HInstruction>[a0, a1, a2]; |
2652 add(reference); | 2642 push(buildInvokeStatic(helper, inputs, type)); |
2653 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2]; | |
2654 push(buildInvokeStatic(inputs, type)); | |
2655 } | 2643 } |
2656 | 2644 |
2657 void pushInvokeHelper4(Element helper, | 2645 void pushInvokeHelper4(Element helper, |
2658 HInstruction a0, | 2646 HInstruction a0, |
2659 HInstruction a1, | 2647 HInstruction a1, |
2660 HInstruction a2, | 2648 HInstruction a2, |
2661 HInstruction a3, | 2649 HInstruction a3, |
2662 HType type) { | 2650 HType type) { |
2663 HInstruction reference = new HStatic(helper); | 2651 List<HInstruction> inputs = <HInstruction>[a0, a1, a2, a3]; |
2664 add(reference); | 2652 push(buildInvokeStatic(helper, inputs, type)); |
2665 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3]; | |
2666 push(buildInvokeStatic(inputs, type)); | |
2667 } | 2653 } |
2668 | 2654 |
2669 void pushInvokeHelper5(Element helper, | 2655 void pushInvokeHelper5(Element helper, |
2670 HInstruction a0, | 2656 HInstruction a0, |
2671 HInstruction a1, | 2657 HInstruction a1, |
2672 HInstruction a2, | 2658 HInstruction a2, |
2673 HInstruction a3, | 2659 HInstruction a3, |
2674 HInstruction a4, | 2660 HInstruction a4, |
2675 HType type) { | 2661 HType type) { |
2676 HInstruction reference = new HStatic(helper); | 2662 List<HInstruction> inputs = <HInstruction>[a0, a1, a2, a3, a4]; |
2677 add(reference); | 2663 push(buildInvokeStatic(helper, inputs, type)); |
2678 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3, a4]; | |
2679 push(buildInvokeStatic(inputs, type)); | |
2680 } | 2664 } |
2681 | 2665 |
2682 HForeign createForeign(String code, | 2666 HForeign createForeign(String code, |
2683 HType type, | 2667 HType type, |
2684 List<HInstruction> inputs) { | 2668 List<HInstruction> inputs) { |
2685 return new HForeign(js.js.parseForeignJS(code), type, inputs); | 2669 return new HForeign(js.js.parseForeignJS(code), type, inputs); |
2686 } | 2670 } |
2687 | 2671 |
2688 HInstruction getRuntimeTypeInfo(HInstruction target) { | 2672 HInstruction getRuntimeTypeInfo(HInstruction target) { |
2689 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); | 2673 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2768 } else { | 2752 } else { |
2769 generateRuntimeError(node, '$type is malformed: $reasons'); | 2753 generateRuntimeError(node, '$type is malformed: $reasons'); |
2770 } | 2754 } |
2771 return; | 2755 return; |
2772 } | 2756 } |
2773 | 2757 |
2774 HInstruction instruction; | 2758 HInstruction instruction; |
2775 if (type.kind == TypeKind.TYPE_VARIABLE) { | 2759 if (type.kind == TypeKind.TYPE_VARIABLE) { |
2776 HInstruction runtimeType = addTypeVariableReference(type); | 2760 HInstruction runtimeType = addTypeVariableReference(type); |
2777 Element helper = backend.getGetObjectIsSubtype(); | 2761 Element helper = backend.getGetObjectIsSubtype(); |
2778 HInstruction helperCall = new HStatic(helper); | 2762 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; |
2779 add(helperCall); | 2763 HInstruction call = buildInvokeStatic(helper, inputs, HType.BOOLEAN); |
2780 List<HInstruction> inputs = <HInstruction>[helperCall, expression, | |
2781 runtimeType]; | |
2782 HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN); | |
2783 add(call); | 2764 add(call); |
2784 instruction = new HIs(type, <HInstruction>[expression, call], | 2765 instruction = new HIs(type, <HInstruction>[expression, call], |
2785 HIs.VARIABLE_CHECK); | 2766 HIs.VARIABLE_CHECK); |
2786 } else if (RuntimeTypes.hasTypeArguments(type)) { | 2767 } else if (RuntimeTypes.hasTypeArguments(type)) { |
2787 Element element = type.element; | 2768 Element element = type.element; |
2788 Element helper = backend.getCheckSubtype(); | 2769 Element helper = backend.getCheckSubtype(); |
2789 HInstruction helperCall = new HStatic(helper); | |
2790 add(helperCall); | |
2791 HInstruction representations = | 2770 HInstruction representations = |
2792 buildTypeArgumentRepresentations(type); | 2771 buildTypeArgumentRepresentations(type); |
2793 add(representations); | 2772 add(representations); |
2794 String operator = | 2773 String operator = |
2795 backend.namer.operatorIs(backend.getImplementationClass(element)); | 2774 backend.namer.operatorIs(backend.getImplementationClass(element)); |
2796 HInstruction isFieldName = addConstantString(node, operator); | 2775 HInstruction isFieldName = addConstantString(node, operator); |
2797 // TODO(karlklose): use [:null:] for [asField] if [element] does not | 2776 // TODO(karlklose): use [:null:] for [asField] if [element] does not |
2798 // have a subclass. | 2777 // have a subclass. |
2799 HInstruction asFieldName = | 2778 HInstruction asFieldName = |
2800 addConstantString(node, backend.namer.substitutionName(element)); | 2779 addConstantString(node, backend.namer.substitutionName(element)); |
2801 List<HInstruction> inputs = <HInstruction>[helperCall, | 2780 List<HInstruction> inputs = <HInstruction>[expression, |
2802 expression, | |
2803 isFieldName, | 2781 isFieldName, |
2804 representations, | 2782 representations, |
2805 asFieldName]; | 2783 asFieldName]; |
2806 HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN); | 2784 HInstruction call = buildInvokeStatic(helper, inputs, HType.BOOLEAN); |
2807 add(call); | 2785 add(call); |
2808 instruction = new HIs(type, <HInstruction>[expression, call], | 2786 instruction = new HIs(type, <HInstruction>[expression, call], |
2809 HIs.COMPOUND_CHECK); | 2787 HIs.COMPOUND_CHECK); |
2810 } else { | 2788 } else { |
2811 instruction = new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); | 2789 instruction = new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); |
2812 } | 2790 } |
2813 if (isNot) { | 2791 if (isNot) { |
2814 add(instruction); | 2792 add(instruction); |
2815 instruction = new HNot(instruction); | 2793 instruction = new HNot(instruction); |
2816 } | 2794 } |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3034 Selector selector = new Selector.callClosure(0); | 3012 Selector selector = new Selector.callClosure(0); |
3035 push(new HInvokeClosure(selector, <HInstruction>[pop()])); | 3013 push(new HInvokeClosure(selector, <HInstruction>[pop()])); |
3036 } else { | 3014 } else { |
3037 // Call a helper method from the isolate library. | 3015 // Call a helper method from the isolate library. |
3038 Element element = compiler.isolateHelperLibrary.find( | 3016 Element element = compiler.isolateHelperLibrary.find( |
3039 const SourceString('_callInIsolate')); | 3017 const SourceString('_callInIsolate')); |
3040 if (element == null) { | 3018 if (element == null) { |
3041 compiler.cancel( | 3019 compiler.cancel( |
3042 'Isolate library and compiler mismatch', node: node); | 3020 'Isolate library and compiler mismatch', node: node); |
3043 } | 3021 } |
3044 HStatic target = new HStatic(element); | 3022 List<HInstruction> inputs = <HInstruction>[]; |
3045 add(target); | |
3046 List<HInstruction> inputs = <HInstruction>[target]; | |
3047 addGenericSendArgumentsToList(link, inputs); | 3023 addGenericSendArgumentsToList(link, inputs); |
3048 push(buildInvokeStatic(inputs, HType.UNKNOWN)); | 3024 push(buildInvokeStatic(element, inputs, HType.UNKNOWN)); |
3049 } | 3025 } |
3050 } | 3026 } |
3051 | 3027 |
3052 FunctionSignature handleForeignRawFunctionRef(Send node, String name) { | 3028 FunctionSignature handleForeignRawFunctionRef(Send node, String name) { |
3053 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { | 3029 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { |
3054 compiler.cancel('"$name" requires exactly one argument', | 3030 compiler.cancel('"$name" requires exactly one argument', |
3055 node: node.argumentsNode); | 3031 node: node.argumentsNode); |
3056 } | 3032 } |
3057 Node closure = node.arguments.head; | 3033 Node closure = node.arguments.head; |
3058 Element element = elements[closure]; | 3034 Element element = elements[closure]; |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3337 HInstruction newObject) { | 3313 HInstruction newObject) { |
3338 if (!backend.needsRti(element) || element.typeVariables.isEmpty) { | 3314 if (!backend.needsRti(element) || element.typeVariables.isEmpty) { |
3339 return; | 3315 return; |
3340 } | 3316 } |
3341 | 3317 |
3342 HInstruction typeInfo = new HLiteralList(rtiInputs); | 3318 HInstruction typeInfo = new HLiteralList(rtiInputs); |
3343 add(typeInfo); | 3319 add(typeInfo); |
3344 | 3320 |
3345 // Set the runtime type information on the object. | 3321 // Set the runtime type information on the object. |
3346 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); | 3322 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); |
3347 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); | 3323 add(buildInvokeStatic(typeInfoSetterElement, |
3348 add(typeInfoSetter); | 3324 <HInstruction>[newObject, typeInfo], HType.UNKNOWN)); |
3349 add(buildInvokeStatic( | |
3350 <HInstruction>[typeInfoSetter, newObject, typeInfo], HType.UNKNOWN)); | |
3351 } | 3325 } |
3352 | 3326 |
3353 /** | 3327 /** |
3354 * Documentation wanted -- johnniwinther | 3328 * Documentation wanted -- johnniwinther |
3355 * | 3329 * |
3356 * Invariant: [type] must not be malformed in checked mode. | 3330 * Invariant: [type] must not be malformed in checked mode. |
3357 */ | 3331 */ |
3358 visitNewSend(Send node, InterfaceType type) { | 3332 visitNewSend(Send node, InterfaceType type) { |
3359 assert(invariant(node, | 3333 assert(invariant(node, |
3360 !compiler.enableTypeAssertions || !type.isMalformed, | 3334 !compiler.enableTypeAssertions || !type.isMalformed, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3394 | 3368 |
3395 if (isSymbolConstructor) { | 3369 if (isSymbolConstructor) { |
3396 constructor = compiler.symbolValidatedConstructor; | 3370 constructor = compiler.symbolValidatedConstructor; |
3397 assert(invariant(node, constructor != null, | 3371 assert(invariant(node, constructor != null, |
3398 message: 'Constructor Symbol.validated is missing')); | 3372 message: 'Constructor Symbol.validated is missing')); |
3399 selector = compiler.symbolValidatedConstructorSelector; | 3373 selector = compiler.symbolValidatedConstructorSelector; |
3400 assert(invariant(node, selector != null, | 3374 assert(invariant(node, selector != null, |
3401 message: 'Constructor Symbol.validated is missing')); | 3375 message: 'Constructor Symbol.validated is missing')); |
3402 } | 3376 } |
3403 | 3377 |
3404 // TODO(5346): Try to avoid the need for calling [declaration] before | |
3405 // creating an [HStatic]. | |
3406 HInstruction target = new HStatic(constructor.declaration); | |
3407 add(target); | |
3408 var inputs = <HInstruction>[]; | 3378 var inputs = <HInstruction>[]; |
3409 inputs.add(target); | |
3410 // TODO(5347): Try to avoid the need for calling [implementation] before | 3379 // TODO(5347): Try to avoid the need for calling [implementation] before |
3411 // calling [addStaticSendArgumentsToList]. | 3380 // calling [addStaticSendArgumentsToList]. |
3412 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 3381 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
3413 constructor.implementation, | 3382 constructor.implementation, |
3414 inputs); | 3383 inputs); |
3415 if (!succeeded) { | 3384 if (!succeeded) { |
3416 generateWrongArgumentCountError(node, constructor, node.arguments); | 3385 generateWrongArgumentCountError(node, constructor, node.arguments); |
3417 return; | 3386 return; |
3418 } | 3387 } |
3419 | 3388 |
(...skipping 13 matching lines...) Expand all Loading... |
3433 while (!typeVariable.isEmpty) { | 3402 while (!typeVariable.isEmpty) { |
3434 inputs.add(graph.addConstantNull(constantSystem)); | 3403 inputs.add(graph.addConstantNull(constantSystem)); |
3435 typeVariable = typeVariable.tail; | 3404 typeVariable = typeVariable.tail; |
3436 } | 3405 } |
3437 } | 3406 } |
3438 | 3407 |
3439 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { | 3408 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { |
3440 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); | 3409 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); |
3441 } | 3410 } |
3442 HType elementType = computeType(constructor); | 3411 HType elementType = computeType(constructor); |
3443 HInstruction newInstance = buildInvokeStatic(inputs, elementType); | 3412 HInstruction newInstance = |
| 3413 buildInvokeStatic(constructor, inputs, elementType); |
3444 pushWithPosition(newInstance, node); | 3414 pushWithPosition(newInstance, node); |
3445 | 3415 |
3446 // The List constructor forwards to a Dart static method that does | 3416 // The List constructor forwards to a Dart static method that does |
3447 // not know about the type argument. Therefore we special case | 3417 // not know about the type argument. Therefore we special case |
3448 // this constructor to have the setRuntimeTypeInfo called where | 3418 // this constructor to have the setRuntimeTypeInfo called where |
3449 // the 'new' is done. | 3419 // the 'new' is done. |
3450 if (isListConstructor && backend.needsRti(compiler.listClass)) { | 3420 if (isListConstructor && backend.needsRti(compiler.listClass)) { |
3451 handleListConstructor(type, node, newInstance); | 3421 handleListConstructor(type, node, newInstance); |
3452 } | 3422 } |
3453 } | 3423 } |
(...skipping 18 matching lines...) Expand all Loading... |
3472 } | 3442 } |
3473 compiler.ensure(!element.isGenerativeConstructor()); | 3443 compiler.ensure(!element.isGenerativeConstructor()); |
3474 if (element.isFunction()) { | 3444 if (element.isFunction()) { |
3475 bool isIdenticalFunction = element == compiler.identicalFunction; | 3445 bool isIdenticalFunction = element == compiler.identicalFunction; |
3476 | 3446 |
3477 if (!isIdenticalFunction | 3447 if (!isIdenticalFunction |
3478 && tryInlineMethod(element, selector, node.arguments, null, node)) { | 3448 && tryInlineMethod(element, selector, node.arguments, null, node)) { |
3479 return; | 3449 return; |
3480 } | 3450 } |
3481 | 3451 |
3482 HInstruction target = new HStatic(element); | 3452 var inputs = <HInstruction>[]; |
3483 add(target); | |
3484 var inputs = <HInstruction>[target]; | |
3485 // TODO(5347): Try to avoid the need for calling [implementation] before | 3453 // TODO(5347): Try to avoid the need for calling [implementation] before |
3486 // calling [addStaticSendArgumentsToList]. | 3454 // calling [addStaticSendArgumentsToList]. |
3487 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 3455 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
3488 element.implementation, | 3456 element.implementation, |
3489 inputs); | 3457 inputs); |
3490 if (!succeeded) { | 3458 if (!succeeded) { |
3491 generateWrongArgumentCountError(node, element, node.arguments); | 3459 generateWrongArgumentCountError(node, element, node.arguments); |
3492 return; | 3460 return; |
3493 } | 3461 } |
3494 | 3462 |
3495 if (isIdenticalFunction) { | 3463 if (isIdenticalFunction) { |
3496 pushWithPosition(new HIdentity(inputs[1], inputs[2]), node); | 3464 pushWithPosition(new HIdentity(inputs[0], inputs[1]), node); |
3497 return; | 3465 return; |
3498 } | 3466 } |
3499 | 3467 |
3500 HInvokeStatic instruction = buildInvokeStatic(inputs, HType.UNKNOWN); | 3468 HInvokeStatic instruction = |
| 3469 buildInvokeStatic(element, inputs, HType.UNKNOWN); |
3501 HType returnType = | 3470 HType returnType = |
3502 new HType.inferredReturnTypeForElement(element, compiler); | 3471 new HType.inferredReturnTypeForElement(element, compiler); |
3503 if (returnType.isUnknown()) { | 3472 if (returnType.isUnknown()) { |
3504 // TODO(ngeoffray): Only do this if knowing the return type is | 3473 // TODO(ngeoffray): Only do this if knowing the return type is |
3505 // useful. | 3474 // useful. |
3506 returnType = | 3475 returnType = |
3507 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( | 3476 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( |
3508 currentElement, element); | 3477 currentElement, element); |
3509 } | 3478 } |
3510 if (returnType != null) instruction.instructionType = returnType; | 3479 if (returnType != null) instruction.instructionType = returnType; |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3707 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); | 3676 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); |
3708 return new HInvokeDynamicGetter(selector, null, inputs, !hasGetter); | 3677 return new HInvokeDynamicGetter(selector, null, inputs, !hasGetter); |
3709 } else if (selector.isSetter()) { | 3678 } else if (selector.isSetter()) { |
3710 bool hasSetter = compiler.world.hasAnyUserDefinedSetter(selector); | 3679 bool hasSetter = compiler.world.hasAnyUserDefinedSetter(selector); |
3711 return new HInvokeDynamicSetter(selector, null, inputs, !hasSetter); | 3680 return new HInvokeDynamicSetter(selector, null, inputs, !hasSetter); |
3712 } else { | 3681 } else { |
3713 return new HInvokeDynamicMethod(selector, inputs, isIntercepted); | 3682 return new HInvokeDynamicMethod(selector, inputs, isIntercepted); |
3714 } | 3683 } |
3715 } | 3684 } |
3716 | 3685 |
3717 HInstruction buildInvokeStatic(List<HInstruction> inputs, | 3686 HInstruction buildInvokeStatic(Element element, |
| 3687 List<HInstruction> inputs, |
3718 [HType type = null]) { | 3688 [HType type = null]) { |
3719 HStatic staticInstruction = inputs[0]; | |
3720 Element element = staticInstruction.element; | |
3721 if (type == null) { | 3689 if (type == null) { |
3722 type = new HType.inferredReturnTypeForElement(element, compiler); | 3690 type = new HType.inferredReturnTypeForElement(element, compiler); |
3723 } | 3691 } |
3724 HInstruction instruction = new HInvokeStatic(inputs, type); | 3692 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 3693 // creating an [HInvokeStatic]. |
| 3694 HInstruction instruction = |
| 3695 new HInvokeStatic(element.declaration, inputs, type); |
3725 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); | 3696 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); |
3726 return instruction; | 3697 return instruction; |
3727 } | 3698 } |
3728 | 3699 |
3729 HInstruction buildInvokeSuper(Selector selector, | 3700 HInstruction buildInvokeSuper(Selector selector, |
3730 Element element, | 3701 Element element, |
3731 List<HInstruction> arguments) { | 3702 List<HInstruction> arguments) { |
3732 HInstruction receiver = localsHandler.readThis(); | 3703 HInstruction receiver = localsHandler.readThis(); |
3733 // TODO(5346): Try to avoid the need for calling [declaration] before | 3704 // TODO(5346): Try to avoid the need for calling [declaration] before |
3734 // creating an [HStatic]. | 3705 // creating an [HStatic]. |
3735 HInstruction target = new HStatic(element.declaration); | 3706 List<HInstruction> inputs = <HInstruction>[]; |
3736 add(target); | |
3737 List<HInstruction> inputs = <HInstruction>[target]; | |
3738 Set<ClassElement> interceptedClasses = | 3707 Set<ClassElement> interceptedClasses = |
3739 backend.getInterceptedClassesOn(selector.name); | 3708 backend.getInterceptedClassesOn(selector.name); |
3740 if (interceptedClasses != null) { | 3709 if (interceptedClasses != null) { |
3741 inputs.add(invokeInterceptor(interceptedClasses, receiver)); | 3710 inputs.add(invokeInterceptor(interceptedClasses, receiver)); |
3742 } | 3711 } |
3743 inputs.add(receiver); | 3712 inputs.add(receiver); |
3744 inputs.addAll(arguments); | 3713 inputs.addAll(arguments); |
3745 HInstruction instruction = new HInvokeSuper( | 3714 HInstruction instruction = new HInvokeSuper( |
| 3715 element, |
3746 currentNonClosureClass, | 3716 currentNonClosureClass, |
3747 inputs, | 3717 inputs, |
3748 isSetter: selector.isSetter() || selector.isIndexSet()); | 3718 isSetter: selector.isSetter() || selector.isIndexSet()); |
3749 instruction.instructionType = | 3719 instruction.instructionType = |
3750 new HType.inferredReturnTypeForElement(element, compiler); | 3720 new HType.inferredReturnTypeForElement(element, compiler); |
3751 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); | 3721 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); |
3752 return instruction; | 3722 return instruction; |
3753 } | 3723 } |
3754 | 3724 |
3755 void handleComplexOperatorSend(SendSet node, | 3725 void handleComplexOperatorSend(SendSet node, |
(...skipping 1522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5278 new HSubGraphBlockInformation(elseBranch.graph)); | 5248 new HSubGraphBlockInformation(elseBranch.graph)); |
5279 | 5249 |
5280 HBasicBlock conditionStartBlock = conditionBranch.block; | 5250 HBasicBlock conditionStartBlock = conditionBranch.block; |
5281 conditionStartBlock.setBlockFlow(info, joinBlock); | 5251 conditionStartBlock.setBlockFlow(info, joinBlock); |
5282 SubGraph conditionGraph = conditionBranch.graph; | 5252 SubGraph conditionGraph = conditionBranch.graph; |
5283 HIf branch = conditionGraph.end.last; | 5253 HIf branch = conditionGraph.end.last; |
5284 assert(branch is HIf); | 5254 assert(branch is HIf); |
5285 branch.blockInformation = conditionStartBlock.blockFlow; | 5255 branch.blockInformation = conditionStartBlock.blockFlow; |
5286 } | 5256 } |
5287 } | 5257 } |
OLD | NEW |