Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(941)

Side by Side Diff: frog/leg/ssa/builder.dart

Issue 9086010: closure calls (just the invocation part). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 802 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 visit(send.receiver); 813 visit(send.receiver);
814 receiver = pop(); 814 receiver = pop();
815 } 815 }
816 add(new HInvokeDynamicSetter(null, jsSetterName, receiver, value)); 816 add(new HInvokeDynamicSetter(null, jsSetterName, receiver, value));
817 stack.add(value); 817 stack.add(value);
818 } else { 818 } else {
819 stack.add(updateDefinition(send, value)); 819 stack.add(updateDefinition(send, value));
820 } 820 }
821 } 821 }
822 822
823 visitOperatorSend(node) {
ngeoffray 2012/01/05 14:05:46 node -> Send node
824 assert(node.selector is Operator);
825 Operator op = node.selector;
826 if (const SourceString("[]") == op.source) {
827 HStatic target = new HStatic(interceptors.getIndexInterceptor());
828 add(target);
829 visit(node.receiver);
830 HInstruction receiver = pop();
831 visit(node.argumentsNode);
832 HInstruction index = pop();
833 push(new HIndex(target, receiver, index));
834 } else if (const SourceString("&&") == op.source ||
835 const SourceString("||") == op.source) {
836 visitLogicalAndOr(node, op);
837 } else if (const SourceString("!") == op.source) {
838 visitLogicalNot(node);
839 } else if (node.argumentsNode is Prefix) {
840 visitUnary(node, op);
841 } else {
842 visit(node.receiver);
843 visit(node.argumentsNode);
844 var right = pop();
845 var left = pop();
846 visitBinary(left, op, right);
847 }
848 }
849
850 addVisitedSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
851 for (; !link.isEmpty(); link = link.tail) {
852 visit(link.head);
853 list.add(pop());
854 }
855 }
856
857 visitDynamicSend(Send node) {
858 var inputs = <HInstruction>[];
859
860 SourceString dartMethodName = node.selector.asIdentifier().source;
861
862 Element interceptor =
863 interceptors.getStaticInterceptor(dartMethodName, node.argumentCount());
864 if (interceptor != null) {
865 HStatic target = new HStatic(interceptor);
866 add(target);
867 inputs.add(target);
868 visit(node.receiver);
869 inputs.add(pop());
870 addVisitedSendArgumentsToList(node.arguments, inputs);
871 push(new HInvokeInterceptor(dartMethodName.stringValue, false, inputs));
872 return;
873 }
874
875 if (node.receiver === null) {
876 HThis receiver = new HThis();
877 add(receiver);
878 inputs.add(receiver);
879 } else {
880 visit(node.receiver);
881 inputs.add(pop());
882 }
883
884 addVisitedSendArgumentsToList(node.arguments, inputs);
885
886 String jsMethodName = compiler.namer.instanceName(dartMethodName);
887 // The first entry in the inputs list is the receiver.
888 push(new HInvokeDynamicMethod(jsMethodName, inputs));
889 }
890
891 visitClosureSend(Send node) {
892 Element element = elements[node];
893 HInstruction closureTarget;
894 if (element === null) {
895 visit(node.selector);
896 closureTarget = pop();
897 } else {
898 assert(element.kind === ElementKind.VARIABLE ||
899 element.kind === ElementKind.PARAMETER);
900 closureTarget = definitions[element];
901 assert(closureTarget !== null);
902 }
903 var inputs = <HInstruction>[];
904 inputs.add(closureTarget);
905 addVisitedSendArgumentsToList(node.arguments, inputs);
906 String jsMethodName = compiler.namer.closureInvocationName();
907 push(new HInvokeDynamicMethod(jsMethodName, inputs));
908 }
909
910 visitForeignSend(Send node) {
911 Link<Node> link = node.arguments;
912 // If the invoke is on foreign code, don't visit the first
913 // argument, which is the type, and the second argument,
914 // which is the foreign code.
915 link = link.tail.tail;
916 var inputs = <HInstruction>[];
917 addVisitedSendArgumentsToList(link, inputs);
918 LiteralString type = node.arguments.head;
919 LiteralString literal = node.arguments.tail.head;
920 compiler.ensure(literal is LiteralString);
921 compiler.ensure(type is LiteralString);
922 compiler.ensure(literal.value.stringValue[0] == '@');
923 push(new HForeign(unquote(literal, 1), unquote(type, 0), inputs));
924 }
925
926 visitStaticSend(Send node) {
927 Element element = elements[node];
928 HStatic target = new HStatic(element);
929 add(target);
930 var inputs = <HInstruction>[];
931 inputs.add(target);
932 addVisitedSendArgumentsToList(node.arguments, inputs);
933 push(new HInvokeStatic(inputs));
934 }
935
823 visitSend(Send node) { 936 visitSend(Send node) {
824 if (node.selector is Operator) { 937 if (node.selector is Operator) {
825 Operator op = node.selector; 938 visitOperatorSend(node);
826 if (const SourceString("[]") == op.source) {
827 HStatic target = new HStatic(interceptors.getIndexInterceptor());
828 add(target);
829 visit(node.receiver);
830 HInstruction receiver = pop();
831 visit(node.argumentsNode);
832 HInstruction index = pop();
833 push(new HIndex(target, receiver, index));
834 } else if (const SourceString("&&") == op.source ||
835 const SourceString("||") == op.source) {
836 visitLogicalAndOr(node, op);
837 } else if (const SourceString("!") == op.source) {
838 visitLogicalNot(node);
839 } else if (node.argumentsNode is Prefix) {
840 visitUnary(node, op);
841 } else {
842 visit(node.receiver);
843 visit(node.argumentsNode);
844 var right = pop();
845 var left = pop();
846 visitBinary(left, op, right);
847 }
848 } else if (node.isPropertyAccess) { 939 } else if (node.isPropertyAccess) {
849 generateGetter(node, elements[node]); 940 generateGetter(node, elements[node]);
941 /*} else if (Elements.isClosureSend(node, elements)) {
kasperl 2012/01/05 12:52:19 Hmm. What's your plan here?
floitsch 2012/01/05 13:59:20 oops :) done.
942 assert(node.receiver === null);
943 visitClosureSend(node); */
850 } else { 944 } else {
945 var isClosure = Elements.isClosureSend(node, elements);
851 Element element = elements[node]; 946 Element element = elements[node];
852 bool isInvokeDynamic = (element === null) || element.isInstanceMember(); 947 if (element === null) {
853 bool isForeign = 948 if (node.selector.asIdentifier() === null) {
854 (element !== null) && (element.kind === ElementKind.FOREIGN); 949 // Example: (foo())(), or (f)().
855 bool isStatic = !isInvokeDynamic && !isForeign; 950 assert(node.receiver === null);
856 951 if (!isClosure) print(1);
kasperl 2012/01/05 12:52:19 Debug printing.
floitsch 2012/01/05 13:59:20 Done.
857 Link<Node> link = node.arguments; 952 visitClosureSend(node);
858 var inputs = <HInstruction>[];
859
860 SourceString dartMethodName;
861 Element interceptor;
862 if (isInvokeDynamic) {
863 dartMethodName = node.selector.asIdentifier().source;
864 interceptor = interceptors.getStaticInterceptor(
865 dartMethodName, node.argumentCount());
866 if (interceptor != null) {
867 HStatic target = new HStatic(interceptor);
868 add(target);
869 inputs.add(target);
870 visit(node.receiver);
871 inputs.add(pop());
872 isInvokeDynamic = false;
873 } else if (node.receiver === null) {
874 HThis receiver = new HThis();
875 add(receiver);
876 inputs.add(receiver);
877 } else { 953 } else {
878 visit(node.receiver); 954 // Example: f() with 'f' unbound.
879 inputs.add(pop()); 955 // This can only happen inside an instance method.
956 if (isClosure) print(2);
kasperl 2012/01/05 12:52:19 Debug printing.
floitsch 2012/01/05 13:59:20 Done.
957 visitDynamicSend(node);
880 } 958 }
881 } else if (isForeign) { 959 } else if (element.isInstanceMember()) {
882 // If the invoke is on foreign code, don't visit the first 960 // Example: f() with 'f' bound to instance method.
883 // argument, which is the type, and the second argument, 961 if (isClosure) print(3);
884 // which is the foreign code. 962 visitDynamicSend(node);
885 link = link.tail.tail; 963 } else if (element.kind === ElementKind.FOREIGN) {
964 if (isClosure) print(4);
965 visitForeignSend(node);
966 } else if (element.kind === ElementKind.VARIABLE ||
967 element.kind === ElementKind.PARAMETER) {
968 // Example: f() with 'f' a local variable or parameter.
969 assert(node.receiver === null);
970 if (!isClosure) print(4);
971 visitClosureSend(node);
886 } else { 972 } else {
887 HStatic target = new HStatic(element); 973 // Example: A.f() or f() with 'f' bound to a static function.
888 add(target); 974 // Also includes new A() or new A.named() which is treated like a
889 inputs.add(target); 975 // static call to a factory.
890 } 976 assert(!element.isInstanceMember());
891 977 if (isClosure) {
892 for (; !link.isEmpty(); link = link.tail) { 978 print(node.receiver);
893 visit(link.head); 979 print(node.selector is TypeAnnotation);
894 inputs.add(pop()); 980 print(node.selector.asStatement() === null);
895 } 981 print(node.selector.asSend() === null);
896 982 print(node.selector.asIdentifier() === null);
897 if (isInvokeDynamic) { 983 print(node.receiver === null);
898 String jsMethodName = compiler.namer.instanceName(dartMethodName); 984 print(element.kind === ElementKind.VARIABLE);
899 // The first entry in the inputs list is the receiver. 985 print(element.kind === ElementKind.PARAMETER);
900 push(new HInvokeDynamicMethod(jsMethodName, inputs)); 986 }
901 } else if (isForeign) { 987 visitStaticSend(node);
902 LiteralString type = node.arguments.head;
903 LiteralString literal = node.arguments.tail.head;
904 compiler.ensure(literal is LiteralString);
905 compiler.ensure(type is LiteralString);
906 compiler.ensure(literal.value.stringValue[0] == '@');
907 push(new HForeign(unquote(literal, 1), unquote(type, 0), inputs));
908 } else if (interceptor != null) {
909 push(new HInvokeInterceptor(dartMethodName.stringValue, false, inputs));
910 } else {
911 assert(isStatic);
912 push(new HInvokeStatic(inputs));
913 } 988 }
914 } 989 }
915 } 990 }
916 991
917 visitNewExpression(NewExpression node) => visitSend(node.send); 992 visitNewExpression(NewExpression node) => visitSend(node.send);
918 993
919 HInstruction updateDefinition(Node node, HInstruction value) { 994 HInstruction updateDefinition(Node node, HInstruction value) {
920 VariableElement element = elements[node]; 995 VariableElement element = elements[node];
921 value = guard(element.type, value); 996 value = guard(element.type, value);
922 definitions[element] = value; 997 definitions[element] = value;
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 } 1254 }
1180 1255
1181 visitCatchBlock(CatchBlock node) { 1256 visitCatchBlock(CatchBlock node) {
1182 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node); 1257 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node);
1183 } 1258 }
1184 1259
1185 visitTypedef(Typedef node) { 1260 visitTypedef(Typedef node) {
1186 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); 1261 compiler.unimplemented('SsaBuilder.visitTypedef', node: node);
1187 } 1262 }
1188 } 1263 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698