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

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: Update test status file. 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
« no previous file with comments | « frog/leg/resolver.dart ('k') | frog/leg/typechecker.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 assert(node.receiver === null);
893 Element element = elements[node];
894 HInstruction closureTarget;
895 if (element === null) {
896 visit(node.selector);
897 closureTarget = pop();
898 } else {
899 assert(element.kind === ElementKind.VARIABLE ||
900 element.kind === ElementKind.PARAMETER);
901 closureTarget = definitions[element];
902 assert(closureTarget !== null);
903 }
904 var inputs = <HInstruction>[];
905 inputs.add(closureTarget);
906 addVisitedSendArgumentsToList(node.arguments, inputs);
907 String jsMethodName = compiler.namer.closureInvocationName();
908 push(new HInvokeDynamicMethod(jsMethodName, inputs));
909 }
910
911 visitForeignSend(Send node) {
912 Link<Node> link = node.arguments;
913 // If the invoke is on foreign code, don't visit the first
914 // argument, which is the type, and the second argument,
915 // which is the foreign code.
916 link = link.tail.tail;
917 var inputs = <HInstruction>[];
918 addVisitedSendArgumentsToList(link, inputs);
919 LiteralString type = node.arguments.head;
920 LiteralString literal = node.arguments.tail.head;
921 compiler.ensure(literal is LiteralString);
922 compiler.ensure(type is LiteralString);
923 compiler.ensure(literal.value.stringValue[0] == '@');
924 push(new HForeign(unquote(literal, 1), unquote(type, 0), inputs));
925 }
926
927 visitStaticSend(Send node) {
928 Element element = elements[node];
929 HStatic target = new HStatic(element);
930 add(target);
931 var inputs = <HInstruction>[];
932 inputs.add(target);
933 addVisitedSendArgumentsToList(node.arguments, inputs);
934 push(new HInvokeStatic(inputs));
935 }
936
823 visitSend(Send node) { 937 visitSend(Send node) {
824 if (node.selector is Operator) { 938 if (node.selector is Operator) {
825 Operator op = node.selector; 939 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) { 940 } else if (node.isPropertyAccess) {
849 generateGetter(node, elements[node]); 941 generateGetter(node, elements[node]);
942 } else if (Elements.isClosureSend(node, elements)) {
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; 955 } else if (!element.isInstanceMember()) {
862 if (isInvokeDynamic) { 956 // Example: A.f() or f() with 'f' bound to a static function.
863 dartMethodName = node.selector.asIdentifier().source; 957 // Also includes new A() or new A.named() which is treated like a
864 interceptor = interceptors.getStaticInterceptor( 958 // static call to a factory.
865 dartMethodName, node.argumentCount()); 959 visitStaticSend(node);
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 { 960 } else {
887 HStatic target = new HStatic(element); 961 compiler.internalError("Cannot generate code for send", node: node);
888 add(target);
889 inputs.add(target);
890 }
891
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 } 962 }
914 } 963 }
915 } 964 }
916 965
917 visitNewExpression(NewExpression node) => visitSend(node.send); 966 visitNewExpression(NewExpression node) => visitSend(node.send);
918 967
919 HInstruction updateDefinition(Node node, HInstruction value) { 968 HInstruction updateDefinition(Node node, HInstruction value) {
920 VariableElement element = elements[node]; 969 VariableElement element = elements[node];
921 value = guard(element.type, value); 970 value = guard(element.type, value);
922 definitions[element] = value; 971 definitions[element] = value;
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 } 1228 }
1180 1229
1181 visitCatchBlock(CatchBlock node) { 1230 visitCatchBlock(CatchBlock node) {
1182 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node); 1231 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node);
1183 } 1232 }
1184 1233
1185 visitTypedef(Typedef node) { 1234 visitTypedef(Typedef node) {
1186 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); 1235 compiler.unimplemented('SsaBuilder.visitTypedef', node: node);
1187 } 1236 }
1188 } 1237 }
OLDNEW
« no previous file with comments | « frog/leg/resolver.dart ('k') | frog/leg/typechecker.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698