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

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

Issue 9284022: Operators. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' 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/scanner/parser.dart ('k') | frog/tests/leg/src/ResolverTest.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 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 value = new HLiteral(null, HType.UNKNOWN); 231 value = new HLiteral(null, HType.UNKNOWN);
232 add(value); 232 add(value);
233 } 233 }
234 fieldValues.add(value); 234 fieldValues.add(value);
235 } 235 }
236 } 236 }
237 HForeignNew newObject = new HForeignNew(classElement, fieldValues); 237 HForeignNew newObject = new HForeignNew(classElement, fieldValues);
238 add(newObject); 238 add(newObject);
239 239
240 // Call the method body. 240 // Call the method body.
241 SourceString methodName = compiler.namer.getConstructorName(bodyElement); 241 SourceString methodName = bodyElement.name;
242 242
243 List bodyCallInputs = <HInstruction>[]; 243 List bodyCallInputs = <HInstruction>[];
244 bodyCallInputs.add(newObject); 244 bodyCallInputs.add(newObject);
245 for (Link link = parameters.nodes; !link.isEmpty(); link = link.tail) { 245 for (Link link = parameters.nodes; !link.isEmpty(); link = link.tail) {
246 Link<Node> nodeLink = link.head.definitions.nodes; 246 Link<Node> nodeLink = link.head.definitions.nodes;
247 // We expect exactly one identifier. 247 // We expect exactly one identifier.
248 assert(!nodeLink.isEmpty() && nodeLink.tail.isEmpty()); 248 assert(!nodeLink.isEmpty() && nodeLink.tail.isEmpty());
249 Node current = nodeLink.head; 249 Node current = nodeLink.head;
250 Element parameterElement = elements[current]; 250 Element parameterElement = elements[current];
251 HInstruction currentValue = definitions[parameterElement]; 251 HInstruction currentValue = definitions[parameterElement];
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 addVisitedSendArgumentsToList(Link<Node> link, List<HInstruction> list) { 898 addVisitedSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
899 for (; !link.isEmpty(); link = link.tail) { 899 for (; !link.isEmpty(); link = link.tail) {
900 visit(link.head); 900 visit(link.head);
901 list.add(pop()); 901 list.add(pop());
902 } 902 }
903 } 903 }
904 904
905 visitDynamicSend(Send node) { 905 visitDynamicSend(Send node) {
906 var inputs = <HInstruction>[]; 906 var inputs = <HInstruction>[];
907 907
908 SourceString dartMethodName = node.selector.asIdentifier().source; 908 SourceString dartMethodName;
909 bool isNotEquals = false;
910 if (node.isIndex && !node.arguments.tail.isEmpty()) {
911 dartMethodName = Elements.constructOperatorName(
912 const SourceString('operator'),
913 const SourceString('[]='));
914 } else if (node.selector.asOperator() != null) {
915 SourceString name = node.selector.asIdentifier().source;
916 isNotEquals = name.stringValue === '!=';
917 dartMethodName = Elements.constructOperatorName(
918 const SourceString('operator'),
919 name,
920 node.argumentsNode is Prefix);
921 } else {
922 dartMethodName = node.selector.asIdentifier().source;
923 }
909 924
910 Element interceptor = null; 925 Element interceptor = null;
911 if (methodInterceptionEnabled) { 926 if (methodInterceptionEnabled) {
912 interceptor = interceptors.getStaticInterceptor(dartMethodName, 927 interceptor = interceptors.getStaticInterceptor(dartMethodName,
913 node.argumentCount()); 928 node.argumentCount());
914 } 929 }
915 if (interceptor != null) { 930 if (interceptor != null) {
916 HStatic target = new HStatic(interceptor); 931 HStatic target = new HStatic(interceptor);
917 add(target); 932 add(target);
918 inputs.add(target); 933 inputs.add(target);
(...skipping 12 matching lines...) Expand all
931 inputs.add(receiver); 946 inputs.add(receiver);
932 } else { 947 } else {
933 visit(node.receiver); 948 visit(node.receiver);
934 inputs.add(pop()); 949 inputs.add(pop());
935 } 950 }
936 951
937 addVisitedSendArgumentsToList(node.arguments, inputs); 952 addVisitedSendArgumentsToList(node.arguments, inputs);
938 953
939 // The first entry in the inputs list is the receiver. 954 // The first entry in the inputs list is the receiver.
940 push(new HInvokeDynamicMethod(dartMethodName, inputs)); 955 push(new HInvokeDynamicMethod(dartMethodName, inputs));
956
957 if (isNotEquals) {
958 HNot not = new HNot(popBoolified());
959 push(not);
960 }
941 } 961 }
942 962
943 visitClosureSend(Send node) { 963 visitClosureSend(Send node) {
944 assert(node.receiver === null); 964 assert(node.receiver === null);
945 Element element = elements[node]; 965 Element element = elements[node];
946 HInstruction closureTarget; 966 HInstruction closureTarget;
947 if (element === null) { 967 if (element === null) {
948 visit(node.selector); 968 visit(node.selector);
949 closureTarget = pop(); 969 closureTarget = pop();
950 } else { 970 } else {
(...skipping 10 matching lines...) Expand all
961 981
962 visitForeignSend(Send node) { 982 visitForeignSend(Send node) {
963 Identifier selector = node.selector; 983 Identifier selector = node.selector;
964 switch (selector.source.stringValue) { 984 switch (selector.source.stringValue) {
965 case "JS": 985 case "JS":
966 Link<Node> link = node.arguments; 986 Link<Node> link = node.arguments;
967 // If the invoke is on foreign code, don't visit the first 987 // If the invoke is on foreign code, don't visit the first
968 // argument, which is the type, and the second argument, 988 // argument, which is the type, and the second argument,
969 // which is the foreign code. 989 // which is the foreign code.
970 link = link.tail.tail; 990 link = link.tail.tail;
971 var inputs = <HInstruction>[]; 991 List<HInstruction> inputs = <HInstruction>[];
972 addVisitedSendArgumentsToList(link, inputs); 992 addVisitedSendArgumentsToList(link, inputs);
973 LiteralString type = node.arguments.head; 993 LiteralString type = node.arguments.head;
974 LiteralString literal = node.arguments.tail.head; 994 LiteralString literal = node.arguments.tail.head;
975 compiler.ensure(literal is LiteralString); 995 compiler.ensure(literal is LiteralString);
976 compiler.ensure(type is LiteralString); 996 compiler.ensure(type is LiteralString);
977 compiler.ensure(literal.value.stringValue[0] == '@'); 997 compiler.ensure(literal.value.stringValue[0] == '@');
978 push(new HForeign(unquote(literal, 1), unquote(type, 0), inputs)); 998 push(new HForeign(unquote(literal, 1), unquote(type, 0), inputs));
979 break; 999 break;
980 case "UNINTERCEPTED": 1000 case "UNINTERCEPTED":
981 Link<Node> link = node.arguments; 1001 Link<Node> link = node.arguments;
982 if (!link.tail.isEmpty()) { 1002 if (!link.tail.isEmpty()) {
983 compiler.cancel('More than one expression in UNINTERCEPTED()'); 1003 compiler.cancel('More than one expression in UNINTERCEPTED()');
984 } 1004 }
985 Expression expression = link.head; 1005 Expression expression = link.head;
986 disableMethodInterception(); 1006 disableMethodInterception();
987 visit(expression); 1007 visit(expression);
988 enableMethodInterception(); 1008 enableMethodInterception();
989 break; 1009 break;
1010 case "JS_HAS_EQUALS":
1011 List<HInstruction> inputs = <HInstruction>[];
1012 if (!node.arguments.tail.isEmpty()) {
1013 compiler.cancel('More than one expression in JS_HAS_EQUALS()');
1014 }
1015 addVisitedSendArgumentsToList(node.arguments, inputs);
1016 String name = compiler.namer.instanceMethodName(
1017 Namer.OPERATOR_EQUALS, 1);
1018 push(new HForeign(
1019 new SourceString('\$0.$name'), const SourceString('bool'), inputs));
1020 break;
990 default: 1021 default:
991 throw "Unknown foreign: ${node.selector}"; 1022 throw "Unknown foreign: ${node.selector}";
992 } 1023 }
993 } 1024 }
994 1025
995 visitSuperSend(Send node) { 1026 visitSuperSend(Send node) {
996 Element element = elements[node]; 1027 Element element = elements[node];
997 HStatic target = new HStatic(element); 1028 HStatic target = new HStatic(element);
998 HThis context = thisDefinition; 1029 HThis context = thisDefinition;
999 if (context === null) { 1030 if (context === null) {
(...skipping 10 matching lines...) Expand all
1010 Element element = elements[node]; 1041 Element element = elements[node];
1011 HStatic target = new HStatic(element); 1042 HStatic target = new HStatic(element);
1012 add(target); 1043 add(target);
1013 var inputs = <HInstruction>[]; 1044 var inputs = <HInstruction>[];
1014 inputs.add(target); 1045 inputs.add(target);
1015 addVisitedSendArgumentsToList(node.arguments, inputs); 1046 addVisitedSendArgumentsToList(node.arguments, inputs);
1016 push(new HInvokeStatic(inputs)); 1047 push(new HInvokeStatic(inputs));
1017 } 1048 }
1018 1049
1019 visitSend(Send node) { 1050 visitSend(Send node) {
1020 if (node.selector is Operator) { 1051 if (node.selector is Operator && methodInterceptionEnabled) {
1021 visitOperatorSend(node); 1052 visitOperatorSend(node);
1022 } else if (node.isPropertyAccess) { 1053 } else if (node.isPropertyAccess) {
1023 generateGetter(node, elements[node]); 1054 generateGetter(node, elements[node]);
1024 } else if (Elements.isClosureSend(node, elements)) { 1055 } else if (Elements.isClosureSend(node, elements)) {
1025 visitClosureSend(node); 1056 visitClosureSend(node);
1026 } else if (node.isSuperCall) { 1057 } else if (node.isSuperCall) {
1027 visitSuperSend(node); 1058 visitSuperSend(node);
1028 } else { 1059 } else {
1029 Element element = elements[node]; 1060 Element element = elements[node];
1030 if (element === null) { 1061 if (element === null) {
(...skipping 23 matching lines...) Expand all
1054 if (element is !VariableElement) { 1085 if (element is !VariableElement) {
1055 compiler.internalError("expected a variable", node: node); 1086 compiler.internalError("expected a variable", node: node);
1056 } 1087 }
1057 definitions[element] = value; 1088 definitions[element] = value;
1058 return value; 1089 return value;
1059 } 1090 }
1060 1091
1061 visitSendSet(SendSet node) { 1092 visitSendSet(SendSet node) {
1062 Operator op = node.assignmentOperator; 1093 Operator op = node.assignmentOperator;
1063 if (node.isIndex) { 1094 if (node.isIndex) {
1064 HStatic target = new HStatic(interceptors.getIndexAssignmentInterceptor()) ; 1095 if (!methodInterceptionEnabled) {
1065 add(target); 1096 assert(op.source.stringValue === '=');
1066 visit(node.receiver); 1097 visitDynamicSend(node);
1067 HInstruction receiver = pop();
1068 visit(node.argumentsNode);
1069 if (const SourceString("=") == op.source) {
1070 HInstruction value = pop();
1071 HInstruction index = pop();
1072 push(new HIndexAssign(target, receiver, index, value));
1073 } else { 1098 } else {
1074 HInstruction value; 1099 HStatic target = new HStatic(
1075 HInstruction index; 1100 interceptors.getIndexAssignmentInterceptor());
1076 bool isCompoundAssignment = op.source.stringValue.endsWith('='); 1101 add(target);
1077 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. 1102 visit(node.receiver);
1078 Element getter = elements[node.selector]; 1103 HInstruction receiver = pop();
1079 if (isCompoundAssignment) { 1104 visit(node.argumentsNode);
1080 value = pop(); 1105 if (const SourceString("=") == op.source) {
1081 index = pop(); 1106 HInstruction value = pop();
1107 HInstruction index = pop();
1108 push(new HIndexAssign(target, receiver, index, value));
1082 } else { 1109 } else {
1083 index = pop(); 1110 HInstruction value;
1084 value = new HLiteral(1, HType.INTEGER); 1111 HInstruction index;
1085 add(value); 1112 bool isCompoundAssignment = op.source.stringValue.endsWith('=');
1086 } 1113 // Compound assignments are considered as being prefix.
1087 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor()); 1114 bool isPrefix = !node.isPostfix;
1088 add(indexMethod); 1115 Element getter = elements[node.selector];
1089 HInstruction left = new HIndex(indexMethod, receiver, index); 1116 if (isCompoundAssignment) {
1090 add(left); 1117 value = pop();
1091 Element opElement = elements[op]; 1118 index = pop();
1092 visitBinary(left, op, value); 1119 } else {
1093 HInstruction assign = new HIndexAssign(target, receiver, index, pop()); 1120 index = pop();
1094 add(assign); 1121 value = new HLiteral(1, HType.INTEGER);
1095 if (isPrefix) { 1122 add(value);
1096 stack.add(assign); 1123 }
1097 } else { 1124 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor());
1098 stack.add(left); 1125 add(indexMethod);
1126 HInstruction left = new HIndex(indexMethod, receiver, index);
1127 add(left);
1128 Element opElement = elements[op];
1129 visitBinary(left, op, value);
1130 HInstruction assign = new HIndexAssign(
1131 target, receiver, index, pop());
1132 add(assign);
1133 if (isPrefix) {
1134 stack.add(assign);
1135 } else {
1136 stack.add(left);
1137 }
1099 } 1138 }
1100 } 1139 }
1101 } else if (const SourceString("=") == op.source) { 1140 } else if (const SourceString("=") == op.source) {
1102 Element element = elements[node]; 1141 Element element = elements[node];
1103 Link<Node> link = node.arguments; 1142 Link<Node> link = node.arguments;
1104 assert(!link.isEmpty() && link.tail.isEmpty()); 1143 assert(!link.isEmpty() && link.tail.isEmpty());
1105 visit(link.head); 1144 visit(link.head);
1106 HInstruction value = pop(); 1145 HInstruction value = pop();
1107 generateSetter(node, element, value); 1146 generateSetter(node, element, value);
1108 } else if (op.source.stringValue === "is") { 1147 } else if (op.source.stringValue === "is") {
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 } 1447 }
1409 1448
1410 visitCatchBlock(CatchBlock node) { 1449 visitCatchBlock(CatchBlock node) {
1411 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node); 1450 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node);
1412 } 1451 }
1413 1452
1414 visitTypedef(Typedef node) { 1453 visitTypedef(Typedef node) {
1415 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); 1454 compiler.unimplemented('SsaBuilder.visitTypedef', node: node);
1416 } 1455 }
1417 } 1456 }
OLDNEW
« no previous file with comments | « frog/leg/scanner/parser.dart ('k') | frog/tests/leg/src/ResolverTest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698