Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 class Interceptors { | 5 class Interceptors { |
| 6 Compiler compiler; | 6 Compiler compiler; |
| 7 Interceptors(Compiler this.compiler); | 7 Interceptors(Compiler this.compiler); |
| 8 | 8 |
| 9 SourceString mapOperatorToMethodName(Operator op) { | 9 SourceString mapOperatorToMethodName(Operator op) { |
| 10 String name = op.source.stringValue; | 10 String name = op.source.stringValue; |
| (...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 841 } else { | 841 } else { |
| 842 visit(node.receiver); | 842 visit(node.receiver); |
| 843 visit(node.argumentsNode); | 843 visit(node.argumentsNode); |
| 844 var right = pop(); | 844 var right = pop(); |
| 845 var left = pop(); | 845 var left = pop(); |
| 846 visitBinary(left, op, right); | 846 visitBinary(left, op, right); |
| 847 } | 847 } |
| 848 } else if (node.isPropertyAccess) { | 848 } else if (node.isPropertyAccess) { |
| 849 generateGetter(node, elements[node]); | 849 generateGetter(node, elements[node]); |
| 850 } else { | 850 } else { |
| 851 final DYNAMIC = 0; | |
|
kasperl
2012/01/05 07:01:52
How about adding a few helper methods for some of
floitsch
2012/01/05 12:18:38
Done.
| |
| 852 final INTERCEPTOR = 1; | |
| 853 final FOREIGN = 2; | |
| 854 final STATIC = 3; | |
| 855 final CLOSURE = 4; | |
| 851 Element element = elements[node]; | 856 Element element = elements[node]; |
| 852 bool isInvokeDynamic = (element === null) || element.isInstanceMember(); | 857 int callKind; |
| 853 bool isForeign = | 858 if (element === null) { |
| 854 (element !== null) && (element.kind === ElementKind.FOREIGN); | 859 callKind = (node.selector.asIdentifier() === null) ? CLOSURE : DYNAMIC; |
| 855 bool isStatic = !isInvokeDynamic && !isForeign; | 860 } else if (element.isInstanceMember()) { |
| 861 callKind = DYNAMIC; | |
| 862 } else if (element.kind === ElementKind.FOREIGN) { | |
| 863 callKind = FOREIGN; | |
| 864 } else if (element.kind === ElementKind.VARIABLE || | |
| 865 element.kind === ElementKind.PARAMETER) { | |
| 866 assert(node.receiver === null); | |
| 867 callKind = CLOSURE; | |
| 868 } else { | |
| 869 assert(!element.isInstanceMember()); | |
| 870 callKind = STATIC; | |
| 871 } | |
| 856 | 872 |
| 857 Link<Node> link = node.arguments; | 873 Link<Node> link = node.arguments; |
| 858 var inputs = <HInstruction>[]; | 874 var inputs = <HInstruction>[]; |
| 859 | 875 |
| 860 SourceString dartMethodName; | 876 SourceString dartMethodName; |
| 861 Element interceptor; | 877 Element interceptor; |
| 862 if (isInvokeDynamic) { | 878 switch (callKind) { |
| 863 dartMethodName = node.selector.asIdentifier().source; | 879 case DYNAMIC: |
| 864 interceptor = interceptors.getStaticInterceptor( | 880 dartMethodName = node.selector.asIdentifier().source; |
| 865 dartMethodName, node.argumentCount()); | 881 interceptor = interceptors.getStaticInterceptor( |
| 866 if (interceptor != null) { | 882 dartMethodName, node.argumentCount()); |
| 867 HStatic target = new HStatic(interceptor); | 883 if (interceptor != null) { |
| 884 callKind = INTERCEPTOR; | |
| 885 HStatic target = new HStatic(interceptor); | |
| 886 add(target); | |
| 887 inputs.add(target); | |
| 888 visit(node.receiver); | |
| 889 inputs.add(pop()); | |
| 890 } else if (node.receiver === null) { | |
| 891 HThis receiver = new HThis(); | |
| 892 add(receiver); | |
| 893 inputs.add(receiver); | |
| 894 } else { | |
| 895 visit(node.receiver); | |
| 896 inputs.add(pop()); | |
| 897 } | |
| 898 break; | |
| 899 case FOREIGN: | |
| 900 // If the invoke is on foreign code, don't visit the first | |
| 901 // argument, which is the type, and the second argument, | |
| 902 // which is the foreign code. | |
| 903 link = link.tail.tail; | |
| 904 break; | |
| 905 case STATIC: | |
| 906 HStatic target = new HStatic(element); | |
| 868 add(target); | 907 add(target); |
| 869 inputs.add(target); | 908 inputs.add(target); |
| 870 visit(node.receiver); | 909 break; |
| 871 inputs.add(pop()); | 910 case CLOSURE: |
| 872 isInvokeDynamic = false; | 911 HInstruction closureTarget; |
| 873 } else if (node.receiver === null) { | 912 if (element === null) { |
| 874 HThis receiver = new HThis(); | 913 visit(node.selector); |
| 875 add(receiver); | 914 closureTarget = pop(); |
| 876 inputs.add(receiver); | 915 } else { |
| 877 } else { | 916 assert(element.kind === ElementKind.VARIABLE || |
| 878 visit(node.receiver); | 917 element.kind === ElementKind.PARAMETER); |
| 879 inputs.add(pop()); | 918 closureTarget = definitions[element]; |
| 880 } | 919 assert(closureTarget !== null); |
| 881 } else if (isForeign) { | 920 } |
| 882 // If the invoke is on foreign code, don't visit the first | 921 inputs.add(closureTarget); |
| 883 // argument, which is the type, and the second argument, | 922 break; |
| 884 // which is the foreign code. | 923 default: |
| 885 link = link.tail.tail; | 924 unreachable("Unhandled callKind in SsaBuilder: $callKind"); break; |
| 886 } else { | |
| 887 HStatic target = new HStatic(element); | |
| 888 add(target); | |
| 889 inputs.add(target); | |
| 890 } | 925 } |
| 891 | 926 |
| 892 for (; !link.isEmpty(); link = link.tail) { | 927 for (; !link.isEmpty(); link = link.tail) { |
| 893 visit(link.head); | 928 visit(link.head); |
| 894 inputs.add(pop()); | 929 inputs.add(pop()); |
| 895 } | 930 } |
| 896 | 931 |
| 897 if (isInvokeDynamic) { | 932 switch (callKind) { |
| 898 String jsMethodName = compiler.namer.instanceName(dartMethodName); | 933 case DYNAMIC: |
| 899 // The first entry in the inputs list is the receiver. | 934 String jsMethodName = compiler.namer.instanceName(dartMethodName); |
| 900 push(new HInvokeDynamicMethod(jsMethodName, inputs)); | 935 // The first entry in the inputs list is the receiver. |
| 901 } else if (isForeign) { | 936 push(new HInvokeDynamicMethod(jsMethodName, inputs)); |
| 902 LiteralString type = node.arguments.head; | 937 break; |
| 903 LiteralString literal = node.arguments.tail.head; | 938 case FOREIGN: |
| 904 compiler.ensure(literal is LiteralString); | 939 LiteralString type = node.arguments.head; |
| 905 compiler.ensure(type is LiteralString); | 940 LiteralString literal = node.arguments.tail.head; |
| 906 compiler.ensure(literal.value.stringValue[0] == '@'); | 941 compiler.ensure(literal is LiteralString); |
| 907 push(new HForeign(unquote(literal, 1), unquote(type, 0), inputs)); | 942 compiler.ensure(type is LiteralString); |
| 908 } else if (interceptor != null) { | 943 compiler.ensure(literal.value.stringValue[0] == '@'); |
| 909 push(new HInvokeInterceptor(dartMethodName.stringValue, false, inputs)); | 944 push(new HForeign(unquote(literal, 1), unquote(type, 0), inputs)); |
| 910 } else { | 945 break; |
| 911 assert(isStatic); | 946 case INTERCEPTOR: |
| 912 push(new HInvokeStatic(inputs)); | 947 assert(interceptor != null); |
| 948 push(new HInvokeInterceptor(dartMethodName.stringValue, false, | |
| 949 inputs)); | |
| 950 break; | |
| 951 case STATIC: | |
| 952 push(new HInvokeStatic(inputs)); | |
| 953 break; | |
| 954 case CLOSURE: | |
| 955 String jsMethodName = compiler.namer.closureInvocationName(); | |
| 956 push(new HInvokeDynamicMethod(jsMethodName, inputs)); | |
| 957 break; | |
| 958 default: | |
| 959 unreachable("Unhandled callKind in SsaBuilder: $callKind"); break; | |
| 913 } | 960 } |
| 914 } | 961 } |
| 915 } | 962 } |
| 916 | 963 |
| 917 visitNewExpression(NewExpression node) => visitSend(node.send); | 964 visitNewExpression(NewExpression node) => visitSend(node.send); |
| 918 | 965 |
| 919 HInstruction updateDefinition(Node node, HInstruction value) { | 966 HInstruction updateDefinition(Node node, HInstruction value) { |
| 920 VariableElement element = elements[node]; | 967 VariableElement element = elements[node]; |
| 921 value = guard(element.type, value); | 968 value = guard(element.type, value); |
| 922 definitions[element] = value; | 969 definitions[element] = value; |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1179 } | 1226 } |
| 1180 | 1227 |
| 1181 visitCatchBlock(CatchBlock node) { | 1228 visitCatchBlock(CatchBlock node) { |
| 1182 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node); | 1229 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node); |
| 1183 } | 1230 } |
| 1184 | 1231 |
| 1185 visitTypedef(Typedef node) { | 1232 visitTypedef(Typedef node) { |
| 1186 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); | 1233 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); |
| 1187 } | 1234 } |
| 1188 } | 1235 } |
| OLD | NEW |