| 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 |