Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 9 import '../common/names.dart'; | 9 import '../common/names.dart'; |
| 10 import '../common/tasks.dart' show CompilerTask; | 10 import '../common/tasks.dart' show CompilerTask; |
| 11 import '../compiler.dart'; | 11 import '../compiler.dart'; |
| 12 import '../constants/values.dart' show StringConstantValue; | |
| 12 import '../dart_types.dart'; | 13 import '../dart_types.dart'; |
| 13 import '../elements/elements.dart'; | 14 import '../elements/elements.dart'; |
| 14 import '../io/source_information.dart'; | 15 import '../io/source_information.dart'; |
| 16 import '../js/js.dart' as js; | |
| 15 import '../js_backend/backend.dart' show JavaScriptBackend; | 17 import '../js_backend/backend.dart' show JavaScriptBackend; |
| 16 import '../kernel/kernel.dart'; | 18 import '../kernel/kernel.dart'; |
| 19 import '../native/native.dart' as native; | |
| 17 import '../resolution/tree_elements.dart'; | 20 import '../resolution/tree_elements.dart'; |
| 18 import '../tree/dartstring.dart'; | 21 import '../tree/dartstring.dart'; |
| 19 import '../types/masks.dart'; | 22 import '../types/masks.dart'; |
| 20 import '../universe/selector.dart'; | 23 import '../universe/selector.dart'; |
| 24 import '../universe/side_effects.dart' show SideEffects; | |
| 21 import 'graph_builder.dart'; | 25 import 'graph_builder.dart'; |
| 22 import 'kernel_ast_adapter.dart'; | 26 import 'kernel_ast_adapter.dart'; |
| 23 import 'kernel_string_builder.dart'; | 27 import 'kernel_string_builder.dart'; |
| 24 import 'locals_handler.dart'; | 28 import 'locals_handler.dart'; |
| 25 import 'loop_handler.dart'; | 29 import 'loop_handler.dart'; |
| 26 import 'nodes.dart'; | 30 import 'nodes.dart'; |
| 27 import 'ssa_branch_builder.dart'; | 31 import 'ssa_branch_builder.dart'; |
| 28 | 32 |
| 29 class SsaKernelBuilderTask extends CompilerTask { | 33 class SsaKernelBuilderTask extends CompilerTask { |
| 30 final JavaScriptBackend backend; | 34 final JavaScriptBackend backend; |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 560 @override | 564 @override |
| 561 void visitMapEntry(ir.MapEntry mapEntry) { | 565 void visitMapEntry(ir.MapEntry mapEntry) { |
| 562 // Visit value before the key because each will push an expression to the | 566 // Visit value before the key because each will push an expression to the |
| 563 // stack, so when we pop them off, the key is popped first, then the value. | 567 // stack, so when we pop them off, the key is popped first, then the value. |
| 564 mapEntry.value.accept(this); | 568 mapEntry.value.accept(this); |
| 565 mapEntry.key.accept(this); | 569 mapEntry.key.accept(this); |
| 566 } | 570 } |
| 567 | 571 |
| 568 @override | 572 @override |
| 569 void visitStaticGet(ir.StaticGet staticGet) { | 573 void visitStaticGet(ir.StaticGet staticGet) { |
| 570 var staticTarget = staticGet.target; | 574 ir.Member staticTarget = staticGet.target; |
| 571 if (staticTarget is ir.Procedure && | 575 if (staticTarget is ir.Procedure && |
| 572 staticTarget.kind == ir.ProcedureKind.Getter) { | 576 staticTarget.kind == ir.ProcedureKind.Getter) { |
| 573 // Invoke the getter | 577 // Invoke the getter |
| 574 _pushStaticInvocation(staticTarget, const <HInstruction>[], | 578 _pushStaticInvocation(staticTarget, const <HInstruction>[], |
| 575 astAdapter.returnTypeOf(staticTarget)); | 579 astAdapter.returnTypeOf(staticTarget)); |
| 580 } else if (staticTarget is ir.Field && staticTarget.isConst) { | |
| 581 assert(staticTarget.initializer != null); | |
| 582 stack.add(graph.addConstant( | |
| 583 astAdapter.getConstantFor(staticTarget.initializer), compiler)); | |
| 576 } else { | 584 } else { |
| 577 Element element = astAdapter.getElement(staticTarget).declaration; | 585 Element element = astAdapter.getElement(staticTarget).declaration; |
| 578 push(new HStatic(element, astAdapter.inferredTypeOf(staticTarget))); | 586 push(new HStatic(element, astAdapter.inferredTypeOf(staticTarget))); |
| 579 } | 587 } |
| 580 } | 588 } |
| 581 | 589 |
| 582 @override | 590 @override |
| 583 void visitStaticSet(ir.StaticSet staticSet) { | 591 void visitStaticSet(ir.StaticSet staticSet) { |
| 584 staticSet.value.accept(this); | 592 staticSet.value.accept(this); |
| 585 HInstruction value = pop(); | 593 HInstruction value = pop(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 664 argument.value.accept(this); | 672 argument.value.accept(this); |
| 665 result.add(pop()); | 673 result.add(pop()); |
| 666 } | 674 } |
| 667 | 675 |
| 668 return result; | 676 return result; |
| 669 } | 677 } |
| 670 | 678 |
| 671 @override | 679 @override |
| 672 void visitStaticInvocation(ir.StaticInvocation invocation) { | 680 void visitStaticInvocation(ir.StaticInvocation invocation) { |
| 673 ir.Procedure target = invocation.target; | 681 ir.Procedure target = invocation.target; |
| 682 if (astAdapter.isInForeignLibrary(target)) { | |
| 683 handleInvokeStaticForeign(invocation, target); | |
| 684 return; | |
| 685 } | |
| 674 TypeMask typeMask = astAdapter.returnTypeOf(target); | 686 TypeMask typeMask = astAdapter.returnTypeOf(target); |
| 675 | 687 |
| 676 List<HInstruction> arguments = _visitArguments(invocation.arguments); | 688 List<HInstruction> arguments = _visitArguments(invocation.arguments); |
| 677 | 689 |
| 678 _pushStaticInvocation(target, arguments, typeMask); | 690 _pushStaticInvocation(target, arguments, typeMask); |
| 679 } | 691 } |
| 680 | 692 |
| 693 void handleInvokeStaticForeign( | |
| 694 ir.StaticInvocation invocation, ir.Procedure target) { | |
| 695 String name = target.name.name; | |
| 696 if (name == 'JS') { | |
| 697 handleForeignJs(invocation); | |
| 698 } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') { | |
| 699 handleForeignJsCurrentIsolateContext(invocation); | |
| 700 } else if (name == 'JS_CALL_IN_ISOLATE') { | |
| 701 handleForeignJsCallInIsolate(invocation); | |
| 702 } else if (name == 'DART_CLOSURE_TO_JS') { | |
| 703 handleForeignDartClosureToJs(invocation, 'DART_CLOSURE_TO_JS'); | |
| 704 } else if (name == 'RAW_DART_FUNCTION_REF') { | |
| 705 handleForeignRawFunctionRef(invocation, 'RAW_DART_FUNCTION_REF'); | |
| 706 } else if (name == 'JS_SET_STATIC_STATE') { | |
| 707 handleForeignJsSetStaticState(invocation); | |
| 708 } else if (name == 'JS_GET_STATIC_STATE') { | |
| 709 handleForeignJsGetStaticState(invocation); | |
| 710 } else if (name == 'JS_GET_NAME') { | |
| 711 handleForeignJsGetName(invocation); | |
| 712 } else if (name == 'JS_EMBEDDED_GLOBAL') { | |
| 713 handleForeignJsEmbeddedGlobal(invocation); | |
| 714 } else if (name == 'JS_BUILTIN') { | |
| 715 handleForeignJsBuiltin(invocation); | |
| 716 } else if (name == 'JS_GET_FLAG') { | |
| 717 handleForeignJsGetFlag(invocation); | |
| 718 } else if (name == 'JS_EFFECT') { | |
| 719 stack.add(graph.addConstantNull(compiler)); | |
| 720 } else if (name == 'JS_INTERCEPTOR_CONSTANT') { | |
| 721 handleJsInterceptorConstant(invocation); | |
| 722 } else if (name == 'JS_STRING_CONCAT') { | |
| 723 handleJsStringConcat(invocation); | |
| 724 } else { | |
| 725 compiler.reporter.internalError( | |
| 726 astAdapter.getNode(invocation), "Unknown foreign: ${name}"); | |
| 727 } | |
| 728 } | |
| 729 | |
| 730 bool _unexpectedForeignArguments( | |
| 731 ir.StaticInvocation invocation, String name, int minPositional, | |
| 732 [int maxPositional]) { | |
| 733 ir.Arguments arguments = invocation.arguments; | |
| 734 bool bad = false; | |
| 735 if (arguments.types.isNotEmpty) { | |
| 736 compiler.reporter.reportErrorMessage( | |
| 737 astAdapter.getNode(invocation), | |
| 738 MessageKind.GENERIC, | |
| 739 {'text': "Error: '$name' does not take type arguments."}); | |
| 740 bad = true; | |
| 741 } | |
| 742 String pluralize(int count, String singular, String plural) { | |
| 743 if (count == 0) return 'no $plural'; | |
| 744 if (count == 1) return 'one $singular'; | |
| 745 if (count == 2) return 'two $plural'; | |
| 746 return '$count ${plural}s'; | |
|
Harry Terkelsen
2016/10/12 16:42:59
should be '$count $plural'
sra1
2016/10/13 19:02:01
Done.
| |
| 747 } | |
| 748 | |
| 749 if (arguments.positional.length < minPositional) { | |
| 750 String phrase = pluralize(minPositional, 'argument', 'arguments'); | |
| 751 if (maxPositional != minPositional) phrase = 'at least $phrase'; | |
| 752 compiler.reporter.reportErrorMessage( | |
| 753 astAdapter.getNode(invocation), | |
| 754 MessageKind.GENERIC, | |
| 755 {'text': "Error: Too few arguments. '$name' takes $phrase."}); | |
| 756 bad = true; | |
| 757 } | |
| 758 if (maxPositional != null && arguments.positional.length > maxPositional) { | |
| 759 String phrase = pluralize(maxPositional, 'argument', 'arguments'); | |
| 760 if (maxPositional != minPositional) phrase = 'at most $phrase'; | |
| 761 compiler.reporter.reportErrorMessage( | |
| 762 astAdapter.getNode(invocation), | |
| 763 MessageKind.GENERIC, | |
| 764 {'text': "Error: Too many arguments. '$name' takes $phrase."}); | |
| 765 bad = true; | |
| 766 } | |
| 767 if (arguments.named.isNotEmpty) { | |
| 768 compiler.reporter.reportErrorMessage( | |
| 769 astAdapter.getNode(invocation), | |
| 770 MessageKind.GENERIC, | |
| 771 {'text': "Error: '$name' does not take named arguments."}); | |
| 772 bad = true; | |
| 773 } | |
| 774 return bad; | |
| 775 } | |
| 776 | |
| 777 /// Returns the value of the string argument. The argument must evaluate to a | |
| 778 /// constant. If there is an error, the error is reported and `null` is | |
| 779 /// returned. | |
| 780 String _foreignConstantStringArgument( | |
| 781 ir.StaticInvocation invocation, int position, String methodName, | |
| 782 [String adjective = '']) { | |
| 783 ir.Expression argument = invocation.arguments.positional[position]; | |
| 784 argument.accept(this); | |
| 785 HInstruction instruction = pop(); | |
| 786 | |
| 787 if (!instruction.isConstantString()) { | |
| 788 compiler.reporter.reportErrorMessage( | |
| 789 astAdapter.getNode(argument), MessageKind.GENERIC, { | |
| 790 'text': "Error: Expected String constant as ${adjective}argument " | |
| 791 "to '$methodName'." | |
| 792 }); | |
| 793 return null; | |
| 794 } | |
| 795 | |
| 796 HConstant hConstant = instruction; | |
| 797 StringConstantValue stringConstant = hConstant.constant; | |
| 798 return stringConstant.primitiveValue.slowToString(); | |
| 799 } | |
| 800 | |
| 801 dynamic _foreignConstantEnumArgument( | |
|
Harry Terkelsen
2016/10/12 16:42:59
this seems unused?
sra1
2016/10/13 19:02:01
Removed
| |
| 802 ir.StaticInvocation invocation, int position, String methodName, | |
| 803 [String adjective = '']) { | |
| 804 ir.Expression argument = invocation.arguments.positional[position]; | |
| 805 argument.accept(this); | |
| 806 HInstruction instruction = pop(); | |
| 807 | |
| 808 if (!instruction.isConstant()) { | |
| 809 compiler.reporter.reportErrorMessage( | |
| 810 astAdapter.getNode(argument), MessageKind.GENERIC, { | |
| 811 'text': "Error: Expected String constant as ${adjective}argument " | |
|
Harry Terkelsen
2016/10/12 16:42:59
should it be 'Expected enum constant ...'?
sra1
2016/10/13 19:02:01
Acknowledged.
| |
| 812 "to '$methodName'." | |
| 813 }); | |
| 814 return null; | |
| 815 } | |
| 816 | |
| 817 HConstant hConstant = instruction; | |
| 818 StringConstantValue stringConstant = hConstant.constant; | |
|
Harry Terkelsen
2016/10/12 16:42:59
should this be an EnumConstantValue?
sra1
2016/10/13 19:02:01
Acknowledged.
| |
| 819 return stringConstant.primitiveValue.slowToString(); | |
| 820 } | |
| 821 | |
| 822 // TODO(sra): Remove when handleInvokeStaticForeign fully implemented. | |
| 823 void unhandledForeign(ir.StaticInvocation invocation) { | |
| 824 ir.Procedure target = invocation.target; | |
| 825 TypeMask typeMask = astAdapter.returnTypeOf(target); | |
| 826 List<HInstruction> arguments = _visitArguments(invocation.arguments); | |
| 827 _pushStaticInvocation(target, arguments, typeMask); | |
| 828 } | |
| 829 | |
| 830 void handleForeignJsCurrentIsolateContext(ir.StaticInvocation invocation) { | |
| 831 unhandledForeign(invocation); | |
| 832 } | |
| 833 | |
| 834 void handleForeignJsCallInIsolate(ir.StaticInvocation invocation) { | |
| 835 unhandledForeign(invocation); | |
| 836 } | |
| 837 | |
| 838 void handleForeignDartClosureToJs( | |
| 839 ir.StaticInvocation invocation, String name) { | |
| 840 unhandledForeign(invocation); | |
| 841 } | |
| 842 | |
| 843 void handleForeignRawFunctionRef( | |
| 844 ir.StaticInvocation invocation, String name) { | |
| 845 unhandledForeign(invocation); | |
| 846 } | |
| 847 | |
| 848 void handleForeignJsSetStaticState(ir.StaticInvocation invocation) { | |
| 849 if (_unexpectedForeignArguments(invocation, 'JS_SET_STATIC_STATE', 0, 0)) { | |
| 850 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | |
| 851 return; | |
| 852 } | |
| 853 _visitArguments(invocation.arguments); | |
| 854 String isolateName = backend.namer.staticStateHolder; | |
| 855 SideEffects sideEffects = new SideEffects.empty(); | |
| 856 sideEffects.setAllSideEffects(); | |
| 857 push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"), | |
| 858 backend.dynamicType, <HInstruction>[pop()], | |
| 859 nativeBehavior: native.NativeBehavior.CHANGES_OTHER, | |
| 860 effects: sideEffects)); | |
| 861 } | |
| 862 | |
| 863 void handleForeignJsGetStaticState(ir.StaticInvocation invocation) { | |
| 864 if (_unexpectedForeignArguments(invocation, 'JS_GET_STATIC_STATE', 0, 0)) { | |
| 865 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | |
| 866 return; | |
| 867 } | |
| 868 | |
| 869 push(new HForeignCode(js.js.parseForeignJS(backend.namer.staticStateHolder), | |
| 870 backend.dynamicType, <HInstruction>[], | |
| 871 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); | |
| 872 } | |
| 873 | |
| 874 void handleForeignJsGetName(ir.StaticInvocation invocation) { | |
| 875 if (_unexpectedForeignArguments(invocation, 'JS_GET_NAME', 1, 1)) { | |
| 876 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | |
| 877 return; | |
| 878 } | |
| 879 | |
| 880 ir.Node argument = invocation.arguments.positional.first; | |
| 881 argument.accept(this); | |
| 882 HInstruction instruction = pop(); | |
| 883 | |
| 884 if (instruction is HConstant) { | |
| 885 js.Name name = | |
| 886 astAdapter.getNameForJsGetName(argument, instruction.constant); | |
| 887 stack.add(graph.addConstantStringFromName(name, compiler)); | |
| 888 return; | |
| 889 } | |
| 890 | |
| 891 compiler.reporter.reportErrorMessage( | |
| 892 astAdapter.getNode(argument), | |
| 893 MessageKind.GENERIC, | |
| 894 {'text': 'Error: Expected a JsGetName enum value.'}); | |
| 895 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | |
| 896 } | |
| 897 | |
| 898 void handleForeignJsEmbeddedGlobal(ir.StaticInvocation invocation) { | |
| 899 if (_unexpectedForeignArguments(invocation, 'JS_EMBEDDED_GLOBAL', 2, 2)) { | |
| 900 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | |
| 901 return; | |
| 902 } | |
| 903 String globalName = _foreignConstantStringArgument( | |
| 904 invocation, 1, 'JS_EMBEDDED_GLOBAL', 'second '); | |
| 905 js.Template expr = js.js.expressionTemplateYielding( | |
| 906 backend.emitter.generateEmbeddedGlobalAccess(globalName)); | |
| 907 | |
| 908 native.NativeBehavior nativeBehavior = | |
| 909 astAdapter.getNativeBehavior(invocation); | |
| 910 assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null, | |
| 911 message: "No NativeBehavior for $invocation")); | |
| 912 | |
| 913 TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior); | |
| 914 push(new HForeignCode(expr, ssaType, const <HInstruction>[], | |
| 915 nativeBehavior: nativeBehavior)); | |
| 916 } | |
| 917 | |
| 918 void handleForeignJsBuiltin(ir.StaticInvocation invocation) { | |
| 919 if (_unexpectedForeignArguments(invocation, 'JS_BUILTIN', 2)) { | |
| 920 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | |
| 921 return; | |
| 922 } | |
| 923 | |
| 924 List<ir.Expression> arguments = invocation.arguments.positional; | |
| 925 ir.Expression nameArgument = arguments[1]; | |
| 926 | |
| 927 nameArgument.accept(this); | |
| 928 HInstruction instruction = pop(); | |
| 929 | |
| 930 js.Template template; | |
| 931 if (instruction is HConstant) { | |
| 932 template = astAdapter.getJsBuiltinTemplate(instruction.constant); | |
| 933 } | |
| 934 if (template == null) { | |
| 935 compiler.reporter.reportErrorMessage( | |
| 936 astAdapter.getNode(nameArgument), | |
| 937 MessageKind.GENERIC, | |
| 938 {'text': 'Error: Expected a JsBuiltin enum value.'}); | |
| 939 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | |
| 940 return; | |
| 941 } | |
| 942 | |
| 943 List<HInstruction> inputs = <HInstruction>[]; | |
| 944 for (ir.Expression argument in arguments.skip(2)) { | |
| 945 argument.accept(this); | |
| 946 inputs.add(pop()); | |
| 947 } | |
| 948 | |
| 949 native.NativeBehavior nativeBehavior = | |
| 950 astAdapter.getNativeBehavior(invocation); | |
| 951 assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null, | |
| 952 message: "No NativeBehavior for $invocation")); | |
| 953 | |
| 954 TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior); | |
| 955 push(new HForeignCode(template, ssaType, inputs, | |
| 956 nativeBehavior: nativeBehavior)); | |
| 957 } | |
| 958 | |
| 959 void handleForeignJsGetFlag(ir.StaticInvocation invocation) { | |
| 960 if (_unexpectedForeignArguments(invocation, 'JS_GET_FLAG', 1, 1)) { | |
| 961 stack.add( | |
| 962 graph.addConstantBool(false, compiler)); // Result expected on stack. | |
| 963 return; | |
| 964 } | |
| 965 String name = _foreignConstantStringArgument(invocation, 0, 'JS_GET_FLAG'); | |
| 966 bool value = false; | |
| 967 switch (name) { | |
| 968 case 'MUST_RETAIN_METADATA': | |
| 969 value = backend.mustRetainMetadata; | |
| 970 break; | |
| 971 case 'USE_CONTENT_SECURITY_POLICY': | |
| 972 value = compiler.options.useContentSecurityPolicy; | |
| 973 break; | |
| 974 default: | |
| 975 compiler.reporter.reportErrorMessage( | |
| 976 astAdapter.getNode(invocation), | |
| 977 MessageKind.GENERIC, | |
| 978 {'text': 'Error: Unknown internal flag "$name".'}); | |
| 979 } | |
| 980 stack.add(graph.addConstantBool(value, compiler)); | |
| 981 } | |
| 982 | |
| 983 void handleJsInterceptorConstant(ir.StaticInvocation invocation) { | |
| 984 unhandledForeign(invocation); | |
| 985 } | |
| 986 | |
| 987 void handleForeignJs(ir.StaticInvocation invocation) { | |
| 988 if (_unexpectedForeignArguments(invocation, 'JS', 2)) { | |
| 989 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | |
| 990 return; | |
| 991 } | |
| 992 | |
| 993 native.NativeBehavior nativeBehavior = | |
| 994 astAdapter.getNativeBehavior(invocation); | |
| 995 assert(nativeBehavior != null); | |
|
Harry Terkelsen
2016/10/12 16:42:59
remove this assert since it makes the next one unr
sra1
2016/10/13 19:02:01
Done.
| |
| 996 assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null, | |
| 997 message: "No NativeBehavior for $invocation")); | |
| 998 | |
| 999 List<HInstruction> inputs = <HInstruction>[]; | |
| 1000 for (ir.Expression argument in invocation.arguments.positional.skip(2)) { | |
| 1001 argument.accept(this); | |
| 1002 inputs.add(pop()); | |
| 1003 } | |
| 1004 | |
| 1005 if (nativeBehavior.codeTemplate.positionalArgumentCount != inputs.length) { | |
| 1006 compiler.reporter.reportErrorMessage( | |
| 1007 astAdapter.getNode(invocation), MessageKind.GENERIC, { | |
| 1008 'text': 'Mismatch between number of placeholders' | |
| 1009 ' and number of arguments.' | |
| 1010 }); | |
| 1011 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | |
| 1012 return; | |
| 1013 } | |
| 1014 | |
| 1015 if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) { | |
| 1016 compiler.reporter.reportErrorMessage( | |
| 1017 astAdapter.getNode(invocation), MessageKind.JS_PLACEHOLDER_CAPTURE); | |
| 1018 } | |
| 1019 | |
| 1020 TypeMask ssaType = astAdapter.typeFromNativeBehavior(nativeBehavior); | |
| 1021 | |
| 1022 SourceInformation sourceInformation = null; | |
| 1023 if (nativeBehavior.codeTemplate.isExpression) { | |
|
Harry Terkelsen
2016/10/12 16:42:58
maybe rewrite this entire if statement as:
push(n
sra1
2016/10/13 19:02:01
Done.
| |
| 1024 push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs, | |
| 1025 effects: nativeBehavior.sideEffects, nativeBehavior: nativeBehavior) | |
| 1026 ..sourceInformation = sourceInformation); | |
| 1027 } else { | |
| 1028 push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs, | |
| 1029 isStatement: true, | |
| 1030 effects: nativeBehavior.sideEffects, | |
| 1031 nativeBehavior: nativeBehavior) | |
| 1032 ..sourceInformation = sourceInformation); | |
| 1033 } | |
| 1034 } | |
| 1035 | |
| 1036 void handleJsStringConcat(ir.StaticInvocation invocation) { | |
| 1037 if (_unexpectedForeignArguments(invocation, 'JS_STRING_CONCAT', 2)) { | |
| 1038 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | |
| 1039 return; | |
| 1040 } | |
| 1041 List<HInstruction> inputs = _visitArguments(invocation.arguments); | |
| 1042 assert(inputs.length == 2); | |
| 1043 push(new HStringConcat(inputs[0], inputs[1], backend.stringType)); | |
| 1044 } | |
| 1045 | |
| 681 void _pushStaticInvocation( | 1046 void _pushStaticInvocation( |
| 682 ir.Node target, List<HInstruction> arguments, TypeMask typeMask) { | 1047 ir.Node target, List<HInstruction> arguments, TypeMask typeMask) { |
| 683 HInstruction instruction = new HInvokeStatic( | 1048 HInstruction instruction = new HInvokeStatic( |
| 684 astAdapter.getElement(target).declaration, arguments, typeMask, | 1049 astAdapter.getElement(target).declaration, arguments, typeMask, |
| 685 targetCanThrow: astAdapter.getCanThrow(target)); | 1050 targetCanThrow: astAdapter.getCanThrow(target)); |
| 686 instruction.sideEffects = astAdapter.getSideEffects(target); | 1051 instruction.sideEffects = astAdapter.getSideEffects(target); |
| 687 | 1052 |
| 688 push(instruction); | 1053 push(instruction); |
| 689 } | 1054 } |
| 690 | 1055 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 817 push(new HNot(popBoolified(), backend.boolType)); | 1182 push(new HNot(popBoolified(), backend.boolType)); |
| 818 } | 1183 } |
| 819 | 1184 |
| 820 @override | 1185 @override |
| 821 void visitStringConcatenation(ir.StringConcatenation stringConcat) { | 1186 void visitStringConcatenation(ir.StringConcatenation stringConcat) { |
| 822 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); | 1187 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); |
| 823 stringConcat.accept(stringBuilder); | 1188 stringConcat.accept(stringBuilder); |
| 824 stack.add(stringBuilder.result); | 1189 stack.add(stringBuilder.result); |
| 825 } | 1190 } |
| 826 } | 1191 } |
| OLD | NEW |