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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 value = new HLiteral(null, HType.UNKNOWN); | 229 value = new HLiteral(null, HType.UNKNOWN); |
| 230 add(value); | 230 add(value); |
| 231 } | 231 } |
| 232 fieldValues.add(value); | 232 fieldValues.add(value); |
| 233 } | 233 } |
| 234 } | 234 } |
| 235 HForeignNew newObject = new HForeignNew(classElement, fieldValues); | 235 HForeignNew newObject = new HForeignNew(classElement, fieldValues); |
| 236 add(newObject); | 236 add(newObject); |
| 237 | 237 |
| 238 // Call the method body. | 238 // Call the method body. |
| 239 SourceString methodName = compiler.namer.getConstructorName(bodyElement); | 239 SourceString methodName = bodyElement.name; |
| 240 | 240 |
| 241 List bodyCallInputs = <HInstruction>[]; | 241 List bodyCallInputs = <HInstruction>[]; |
| 242 bodyCallInputs.add(newObject); | 242 bodyCallInputs.add(newObject); |
| 243 for (Link link = parameters.nodes; !link.isEmpty(); link = link.tail) { | 243 for (Link link = parameters.nodes; !link.isEmpty(); link = link.tail) { |
| 244 Link<Node> nodeLink = link.head.definitions.nodes; | 244 Link<Node> nodeLink = link.head.definitions.nodes; |
| 245 // We expect exactly one identifier. | 245 // We expect exactly one identifier. |
| 246 assert(!nodeLink.isEmpty() && nodeLink.tail.isEmpty()); | 246 assert(!nodeLink.isEmpty() && nodeLink.tail.isEmpty()); |
| 247 Node current = nodeLink.head; | 247 Node current = nodeLink.head; |
| 248 Element parameterElement = elements[current]; | 248 Element parameterElement = elements[current]; |
| 249 HInstruction currentValue = definitions[parameterElement]; | 249 HInstruction currentValue = definitions[parameterElement]; |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 896 addVisitedSendArgumentsToList(Link<Node> link, List<HInstruction> list) { | 896 addVisitedSendArgumentsToList(Link<Node> link, List<HInstruction> list) { |
| 897 for (; !link.isEmpty(); link = link.tail) { | 897 for (; !link.isEmpty(); link = link.tail) { |
| 898 visit(link.head); | 898 visit(link.head); |
| 899 list.add(pop()); | 899 list.add(pop()); |
| 900 } | 900 } |
| 901 } | 901 } |
| 902 | 902 |
| 903 visitDynamicSend(Send node) { | 903 visitDynamicSend(Send node) { |
| 904 var inputs = <HInstruction>[]; | 904 var inputs = <HInstruction>[]; |
| 905 | 905 |
| 906 SourceString dartMethodName = node.selector.asIdentifier().source; | 906 SourceString dartMethodName; |
| 907 bool isNotEquals = false; | |
| 908 if (node.isIndex && !node.arguments.tail.isEmpty()) { | |
| 909 dartMethodName = Elements.constructOperatorName( | |
| 910 const SourceString('operator'), | |
| 911 const SourceString('[]=')); | |
| 912 } else if (node.selector.asOperator() != null) { | |
| 913 SourceString name = node.selector.asIdentifier().source; | |
| 914 isNotEquals = name.stringValue === '!='; | |
| 915 dartMethodName = Elements.constructOperatorName( | |
| 916 const SourceString('operator'), | |
| 917 name, | |
| 918 node.argumentsNode is Prefix); | |
| 919 } else { | |
| 920 dartMethodName = node.selector.asIdentifier().source; | |
| 921 } | |
| 907 | 922 |
| 908 Element interceptor = null; | 923 Element interceptor = null; |
| 909 if (methodInterceptionEnabled) { | 924 if (methodInterceptionEnabled) { |
| 910 interceptor = interceptors.getStaticInterceptor(dartMethodName, | 925 interceptor = interceptors.getStaticInterceptor(dartMethodName, |
| 911 node.argumentCount()); | 926 node.argumentCount()); |
| 912 } | 927 } |
| 913 if (interceptor != null) { | 928 if (interceptor != null) { |
| 914 HStatic target = new HStatic(interceptor); | 929 HStatic target = new HStatic(interceptor); |
| 915 add(target); | 930 add(target); |
| 916 inputs.add(target); | 931 inputs.add(target); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 929 inputs.add(receiver); | 944 inputs.add(receiver); |
| 930 } else { | 945 } else { |
| 931 visit(node.receiver); | 946 visit(node.receiver); |
| 932 inputs.add(pop()); | 947 inputs.add(pop()); |
| 933 } | 948 } |
| 934 | 949 |
| 935 addVisitedSendArgumentsToList(node.arguments, inputs); | 950 addVisitedSendArgumentsToList(node.arguments, inputs); |
| 936 | 951 |
| 937 // The first entry in the inputs list is the receiver. | 952 // The first entry in the inputs list is the receiver. |
| 938 push(new HInvokeDynamicMethod(dartMethodName, inputs)); | 953 push(new HInvokeDynamicMethod(dartMethodName, inputs)); |
| 954 | |
| 955 if (isNotEquals) { | |
| 956 HNot not = new HNot(popBoolified()); | |
| 957 push(not); | |
| 958 } | |
| 939 } | 959 } |
| 940 | 960 |
| 941 visitClosureSend(Send node) { | 961 visitClosureSend(Send node) { |
| 942 assert(node.receiver === null); | 962 assert(node.receiver === null); |
| 943 Element element = elements[node]; | 963 Element element = elements[node]; |
| 944 HInstruction closureTarget; | 964 HInstruction closureTarget; |
| 945 if (element === null) { | 965 if (element === null) { |
| 946 visit(node.selector); | 966 visit(node.selector); |
| 947 closureTarget = pop(); | 967 closureTarget = pop(); |
| 948 } else { | 968 } else { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1008 Element element = elements[node]; | 1028 Element element = elements[node]; |
| 1009 HStatic target = new HStatic(element); | 1029 HStatic target = new HStatic(element); |
| 1010 add(target); | 1030 add(target); |
| 1011 var inputs = <HInstruction>[]; | 1031 var inputs = <HInstruction>[]; |
| 1012 inputs.add(target); | 1032 inputs.add(target); |
| 1013 addVisitedSendArgumentsToList(node.arguments, inputs); | 1033 addVisitedSendArgumentsToList(node.arguments, inputs); |
| 1014 push(new HInvokeStatic(inputs)); | 1034 push(new HInvokeStatic(inputs)); |
| 1015 } | 1035 } |
| 1016 | 1036 |
| 1017 visitSend(Send node) { | 1037 visitSend(Send node) { |
| 1018 if (node.selector is Operator) { | 1038 if (node.selector is Operator && methodInterceptionEnabled) { |
| 1019 visitOperatorSend(node); | 1039 visitOperatorSend(node); |
| 1020 } else if (node.isPropertyAccess) { | 1040 } else if (node.isPropertyAccess) { |
| 1021 generateGetter(node, elements[node]); | 1041 generateGetter(node, elements[node]); |
| 1022 } else if (Elements.isClosureSend(node, elements)) { | 1042 } else if (Elements.isClosureSend(node, elements)) { |
| 1023 visitClosureSend(node); | 1043 visitClosureSend(node); |
| 1024 } else if (node.isSuperCall) { | 1044 } else if (node.isSuperCall) { |
| 1025 visitSuperSend(node); | 1045 visitSuperSend(node); |
| 1026 } else { | 1046 } else { |
| 1027 Element element = elements[node]; | 1047 Element element = elements[node]; |
| 1028 if (element === null) { | 1048 if (element === null) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1052 if (element is !VariableElement) { | 1072 if (element is !VariableElement) { |
| 1053 compiler.internalError("expected a variable", node: node); | 1073 compiler.internalError("expected a variable", node: node); |
| 1054 } | 1074 } |
| 1055 definitions[element] = value; | 1075 definitions[element] = value; |
| 1056 return value; | 1076 return value; |
| 1057 } | 1077 } |
| 1058 | 1078 |
| 1059 visitSendSet(SendSet node) { | 1079 visitSendSet(SendSet node) { |
| 1060 Operator op = node.assignmentOperator; | 1080 Operator op = node.assignmentOperator; |
| 1061 if (node.isIndex) { | 1081 if (node.isIndex) { |
| 1062 HStatic target = new HStatic(interceptors.getIndexAssignmentInterceptor()) ; | 1082 if (!methodInterceptionEnabled) { |
| 1063 add(target); | 1083 assert(op.source == const SourceString("=")); |
|
Lasse Reichstein Nielsen
2012/01/27 09:42:34
Might as well do
op.source.stringValue == "="
(
ngeoffray
2012/01/27 10:50:04
Done.
| |
| 1064 visit(node.receiver); | 1084 visitDynamicSend(node); |
| 1065 HInstruction receiver = pop(); | |
| 1066 visit(node.argumentsNode); | |
| 1067 if (const SourceString("=") == op.source) { | |
| 1068 HInstruction value = pop(); | |
| 1069 HInstruction index = pop(); | |
| 1070 push(new HIndexAssign(target, receiver, index, value)); | |
| 1071 } else { | 1085 } else { |
| 1072 HInstruction value; | 1086 HStatic target = new HStatic( |
| 1073 HInstruction index; | 1087 interceptors.getIndexAssignmentInterceptor()); |
| 1074 bool isCompoundAssignment = op.source.stringValue.endsWith('='); | 1088 add(target); |
| 1075 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. | 1089 visit(node.receiver); |
| 1076 Element getter = elements[node.selector]; | 1090 HInstruction receiver = pop(); |
| 1077 if (isCompoundAssignment) { | 1091 visit(node.argumentsNode); |
| 1078 value = pop(); | 1092 if (const SourceString("=") == op.source) { |
| 1079 index = pop(); | 1093 HInstruction value = pop(); |
| 1094 HInstruction index = pop(); | |
| 1095 push(new HIndexAssign(target, receiver, index, value)); | |
| 1080 } else { | 1096 } else { |
| 1081 index = pop(); | 1097 HInstruction value; |
| 1082 value = new HLiteral(1, HType.INTEGER); | 1098 HInstruction index; |
| 1083 add(value); | 1099 bool isCompoundAssignment = op.source.stringValue.endsWith('='); |
| 1084 } | 1100 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. |
|
Lasse Reichstein Nielsen
2012/01/27 09:42:34
"are prefix." => "are considered as being prefix."
ngeoffray
2012/01/27 10:50:04
Done.
| |
| 1085 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor()); | 1101 Element getter = elements[node.selector]; |
| 1086 add(indexMethod); | 1102 if (isCompoundAssignment) { |
| 1087 HInstruction left = new HIndex(indexMethod, receiver, index); | 1103 value = pop(); |
| 1088 add(left); | 1104 index = pop(); |
| 1089 Element opElement = elements[op]; | 1105 } else { |
| 1090 visitBinary(left, op, value); | 1106 index = pop(); |
| 1091 HInstruction assign = new HIndexAssign(target, receiver, index, pop()); | 1107 value = new HLiteral(1, HType.INTEGER); |
| 1092 add(assign); | 1108 add(value); |
| 1093 if (isPrefix) { | 1109 } |
| 1094 stack.add(assign); | 1110 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor()); |
| 1095 } else { | 1111 add(indexMethod); |
| 1096 stack.add(left); | 1112 HInstruction left = new HIndex(indexMethod, receiver, index); |
| 1113 add(left); | |
| 1114 Element opElement = elements[op]; | |
| 1115 visitBinary(left, op, value); | |
| 1116 HInstruction assign = new HIndexAssign( | |
| 1117 target, receiver, index, pop()); | |
| 1118 add(assign); | |
| 1119 if (isPrefix) { | |
| 1120 stack.add(assign); | |
| 1121 } else { | |
| 1122 stack.add(left); | |
| 1123 } | |
| 1097 } | 1124 } |
| 1098 } | 1125 } |
| 1099 } else if (const SourceString("=") == op.source) { | 1126 } else if (const SourceString("=") == op.source && !node.isIndex) { |
|
Lasse Reichstein Nielsen
2012/01/27 09:42:34
Change that to
assert(!node.isIndex);
It can't ha
ngeoffray
2012/01/27 10:50:04
You're right, that's a leftover from a previous im
| |
| 1100 Element element = elements[node]; | 1127 Element element = elements[node]; |
| 1101 Link<Node> link = node.arguments; | 1128 Link<Node> link = node.arguments; |
| 1102 assert(!link.isEmpty() && link.tail.isEmpty()); | 1129 assert(!link.isEmpty() && link.tail.isEmpty()); |
| 1103 visit(link.head); | 1130 visit(link.head); |
| 1104 HInstruction value = pop(); | 1131 HInstruction value = pop(); |
| 1105 generateSetter(node, element, value); | 1132 generateSetter(node, element, value); |
| 1106 } else if (op.source.stringValue === "is") { | 1133 } else if (op.source.stringValue === "is") { |
| 1107 compiler.internalError("is-operator as SendSet", node: op); | 1134 compiler.internalError("is-operator as SendSet", node: op); |
| 1108 } else { | 1135 } else { |
| 1109 assert(const SourceString("++") == op.source || | 1136 assert(const SourceString("++") == op.source || |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1406 } | 1433 } |
| 1407 | 1434 |
| 1408 visitCatchBlock(CatchBlock node) { | 1435 visitCatchBlock(CatchBlock node) { |
| 1409 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node); | 1436 compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node); |
| 1410 } | 1437 } |
| 1411 | 1438 |
| 1412 visitTypedef(Typedef node) { | 1439 visitTypedef(Typedef node) { |
| 1413 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); | 1440 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); |
| 1414 } | 1441 } |
| 1415 } | 1442 } |
| OLD | NEW |