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

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 comment. 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) {
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) {
ngeoffray 2012/01/05 14:05:46 Why not removing that check and just do visit(node
floitsch 2012/01/24 13:28:37 Because the selector doesn't (yet) have any elemen
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)) {
942 assert(node.receiver === null);
ngeoffray 2012/01/05 14:05:46 I would not put that assert here. I you really wan
floitsch 2012/01/24 13:28:37 moved to visitClosureSend.
943 visitClosureSend(node);
850 } else { 944 } else {
851 Element element = elements[node]; 945 Element element = elements[node];
852 bool isInvokeDynamic = (element === null) || element.isInstanceMember(); 946 if (element === null) {
853 bool isForeign = 947 // Example: f() with 'f' unbound.
854 (element !== null) && (element.kind === ElementKind.FOREIGN); 948 // This can only happen inside an instance method.
855 bool isStatic = !isInvokeDynamic && !isForeign; 949 visitDynamicSend(node);
856 950 } else if (element.isInstanceMember()) {
857 Link<Node> link = node.arguments; 951 // Example: f() with 'f' bound to instance method.
858 var inputs = <HInstruction>[]; 952 visitDynamicSend(node);
859 953 } else if (element.kind === ElementKind.FOREIGN) {
860 SourceString dartMethodName; 954 visitForeignSend(node);
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 {
878 visit(node.receiver);
879 inputs.add(pop());
880 }
881 } else if (isForeign) {
882 // If the invoke is on foreign code, don't visit the first
883 // argument, which is the type, and the second argument,
884 // which is the foreign code.
885 link = link.tail.tail;
886 } else { 955 } else {
ngeoffray 2012/01/05 14:05:46 else if (!element.isInstanceMember()) { ... } els
floitsch 2012/01/24 13:28:37 Done.
887 HStatic target = new HStatic(element); 956 // Example: A.f() or f() with 'f' bound to a static function.
888 add(target); 957 // Also includes new A() or new A.named() which is treated like a
889 inputs.add(target); 958 // static call to a factory.
890 } 959 assert(!element.isInstanceMember());
891 960 visitStaticSend(node);
892 for (; !link.isEmpty(); link = link.tail) {
893 visit(link.head);
894 inputs.add(pop());
895 }
896
897 if (isInvokeDynamic) {
898 String jsMethodName = compiler.namer.instanceName(dartMethodName);
899 // The first entry in the inputs list is the receiver.
900 push(new HInvokeDynamicMethod(jsMethodName, inputs));
901 } else if (isForeign) {
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 } 961 }
914 } 962 }
915 } 963 }
916 964
917 visitNewExpression(NewExpression node) => visitSend(node.send); 965 visitNewExpression(NewExpression node) => visitSend(node.send);
918 966
919 HInstruction updateDefinition(Node node, HInstruction value) { 967 HInstruction updateDefinition(Node node, HInstruction value) {
920 VariableElement element = elements[node]; 968 VariableElement element = elements[node];
921 value = guard(element.type, value); 969 value = guard(element.type, value);
922 definitions[element] = value; 970 definitions[element] = value;
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 } 1227 }
1180 1228
1181 visitCatchBlock(CatchBlock node) { 1229 visitCatchBlock(CatchBlock node) {
1182 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node); 1230 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node);
1183 } 1231 }
1184 1232
1185 visitTypedef(Typedef node) { 1233 visitTypedef(Typedef node) {
1186 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); 1234 compiler.unimplemented('SsaBuilder.visitTypedef', node: node);
1187 } 1235 }
1188 } 1236 }
OLDNEW
« no previous file with comments | « frog/leg/resolver.dart ('k') | frog/leg/typechecker.dart » ('j') | frog/leg/typechecker.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698