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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart

Issue 349923004: Add support for superSend to the new IR and dart backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 6 years, 5 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library dart2js.ir_builder; 5 library dart2js.ir_builder;
6 6
7 import 'ir_nodes.dart' as ir; 7 import 'ir_nodes.dart' as ir;
8 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import '../dart2jslib.dart'; 9 import '../dart2jslib.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 130
131 SourceFile elementSourceFile(Element element) { 131 SourceFile elementSourceFile(Element element) {
132 if (element is FunctionElement) { 132 if (element is FunctionElement) {
133 FunctionElement functionElement = element; 133 FunctionElement functionElement = element;
134 if (functionElement.patch != null) element = functionElement.patch; 134 if (functionElement.patch != null) element = functionElement.patch;
135 } 135 }
136 return element.compilationUnit.script.file; 136 return element.compilationUnit.script.file;
137 } 137 }
138 } 138 }
139 139
140 class _GetterElements {
141 ir.Primitive result;
142 ir.Primitive index;
143 ir.Primitive receiver;
144
145 _GetterElements({this.result, this.index, this.receiver}) ;
146 }
147
140 /** 148 /**
141 * A tree visitor that builds [IrNodes]. The visit methods add statements using 149 * A tree visitor that builds [IrNodes]. The visit methods add statements using
142 * to the [builder] and return the last added statement for trees that represent 150 * to the [builder] and return the last added statement for trees that represent
143 * an expression. 151 * an expression.
144 */ 152 */
145 class IrBuilder extends ResolvedVisitor<ir.Primitive> { 153 class IrBuilder extends ResolvedVisitor<ir.Primitive> {
146 final SourceFile sourceFile; 154 final SourceFile sourceFile;
147 final ir.Continuation returnContinuation; 155 final ir.Continuation returnContinuation;
148 final List<ir.Parameter> parameters; 156 final List<ir.Parameter> parameters;
149 157
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 return result; 828 return result;
821 } 829 }
822 830
823 ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) { 831 ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) {
824 assert(isOpen); 832 assert(isOpen);
825 return translateConstant(node); 833 return translateConstant(node);
826 } 834 }
827 835
828 ir.Primitive visitIdentifier(ast.Identifier node) { 836 ir.Primitive visitIdentifier(ast.Identifier node) {
829 assert(isOpen); 837 assert(isOpen);
838 // "this" is the only identifier that should be met by the visitor.
830 assert(node.isThis()); 839 assert(node.isThis());
831 return lookupThis(); 840 return lookupThis();
832 } 841 }
833 842
834 ir.Primitive visitParenthesizedExpression( 843 ir.Primitive visitParenthesizedExpression(
835 ast.ParenthesizedExpression node) { 844 ast.ParenthesizedExpression node) {
836 assert(isOpen); 845 assert(isOpen);
837 return visit(node.expression); 846 return visit(node.expression);
838 } 847 }
839 848
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 closureTarget = visit(node.selector); 915 closureTarget = visit(node.selector);
907 } else { 916 } else {
908 assert(Elements.isLocal(element)); 917 assert(Elements.isLocal(element));
909 closureTarget = lookupLocal(element); 918 closureTarget = lookupLocal(element);
910 } 919 }
911 Selector closureSelector = elements.getSelector(node); 920 Selector closureSelector = elements.getSelector(node);
912 return translateClosureCall(closureTarget, closureSelector, 921 return translateClosureCall(closureTarget, closureSelector,
913 node.argumentsNode); 922 node.argumentsNode);
914 } 923 }
915 924
925 /// If [node] is null, returns this.
926 /// If [node] is super, returns null (for special handling)
927 /// Otherwise visits [node] and returns the result.
928 ir.Primitive visitReceiver(ast.Expression node) {
929 if (node == null) return lookupThis();
930 if (node.isSuper()) return null;
931 return visit(node);
932 }
933
934 /// Makes an [InvokeMethod] unless [node.receiver.isSuper()], in that case
935 /// makes an [InvokeSuperMethod] ignoring [receiver].
936 ir.Expression createDynamicInvoke(ast.Send node,
937 Selector selector,
938 ir.Definition receiver,
939 ir.Continuation k,
940 List<ir.Definition> arguments) {
941 return node.receiver != null && node.receiver.isSuper()
942 ? new ir.InvokeSuperMethod(selector, k, arguments)
943 : new ir.InvokeMethod(receiver, selector, k, arguments);
944 }
945
916 ir.Primitive visitDynamicSend(ast.Send node) { 946 ir.Primitive visitDynamicSend(ast.Send node) {
917 assert(isOpen); 947 assert(isOpen);
918 if (node.receiver == null || node.receiver.isSuper()) {
919 return giveup(node, 'DynamicSend without receiver, or super receiver');
920 }
921 Selector selector = elements.getSelector(node); 948 Selector selector = elements.getSelector(node);
922 ir.Primitive receiver = visit(node.receiver); 949 ir.Primitive receiver = visitReceiver(node.receiver);
923 List<ir.Primitive> arguments = new List<ir.Primitive>(); 950 List<ir.Primitive> arguments = new List<ir.Primitive>();
924 for (ast.Node n in node.arguments) { 951 for (ast.Node n in node.arguments) {
925 arguments.add(visit(n)); 952 arguments.add(visit(n));
926 } 953 }
927 ir.Parameter v = new ir.Parameter(null); 954 ir.Parameter v = new ir.Parameter(null);
928 ir.Continuation k = new ir.Continuation([v]); 955 ir.Continuation k = new ir.Continuation([v]);
929 ir.Expression invoke = 956 ir.Expression invoke =
930 new ir.InvokeMethod(receiver, selector, k, arguments); 957 createDynamicInvoke(node, selector, receiver, k, arguments);
931 add(new ir.LetCont(k, invoke)); 958 add(new ir.LetCont(k, invoke));
932 return v; 959 return v;
933 } 960 }
934 961
962 _GetterElements translateGetter(ast.Send node, Selector selector) {
963 Element element = elements[node];
964 ir.Primitive result;
965 ir.Primitive receiver;
966 ir.Primitive index;
967
968 if (Elements.isErroneousElement(element)) {
969 giveup(node, 'Erroneous element on GetterSend');
970 return null;
971 }
972
973 if (element != null && element.isConst) {
974 // Reference to constant local, top-level or static field
975
976 result = translateConstant(node);
977 } else if (Elements.isLocal(element)) {
978 // Reference to local variable
979
980 result = lookupLocal(element);
981 } else if (element == null ||
982 Elements.isInstanceField(element) ||
983 Elements.isInstanceMethod(element) ||
984 selector.isIndex ||
985 node.isSuperCall) {
986 // Dynamic dispatch to a getter. Sometimes resolution will suggest a target
987 // element, but in these cases we must still emit a dynamic dispatch. The
988 // target element may be an instance method in case we are converting a
989 // method to a function object.
990
991 receiver = visitReceiver(node.receiver);
992 List<ir.Primitive> arguments = new List<ir.Primitive>();
993 if (selector.isIndex) {
994 index = visit(node.arguments.head);
995 arguments.add(index);
996 }
997
998 ir.Parameter v = new ir.Parameter(null);
999 ir.Continuation k = new ir.Continuation([v]);
1000 assert(selector.kind == SelectorKind.GETTER ||
1001 selector.kind == SelectorKind.INDEX);
1002 ir.Expression invoke =
1003 createDynamicInvoke(node, selector, receiver, k, arguments);
1004 add(new ir.LetCont(k, invoke));
1005 result = v;
1006 } else if (element.isField || element.isGetter ||
1007 // Access to a static field or getter (non-static case handled above).
1008 // Even if there is only a setter, we compile as if it was a getter,
1009 // so the vm can fail at runtime.
1010
1011 element.isSetter) {
1012 ir.Parameter v = new ir.Parameter(null);
1013 ir.Continuation k = new ir.Continuation([v]);
1014 assert(selector.kind == SelectorKind.GETTER ||
1015 selector.kind == SelectorKind.SETTER);
1016 ir.Expression invoke =
1017 new ir.InvokeStatic(element, selector, k, []);
1018 add(new ir.LetCont(k, invoke));
1019 result = v;
1020 } else if (Elements.isStaticOrTopLevelFunction(element)) {
1021 // Convert a top-level or static function to a function object.
1022
1023 result = translateConstant(node);
1024 } else {
1025 throw "Unexpected SendSet getter: $node, $element";
1026 }
1027 return new _GetterElements(
1028 result: result,index: index, receiver: receiver);
1029 }
1030
935 ir.Primitive visitGetterSend(ast.Send node) { 1031 ir.Primitive visitGetterSend(ast.Send node) {
936 assert(isOpen); 1032 assert(isOpen);
937 Element element = elements[node]; 1033 return translateGetter(node, elements.getSelector(node)).result;
938 1034
939 // TODO(asgerf): Generate code for erroneous getter access
940 if (Elements.isErroneousElement(element)) {
941 return giveup(node, 'Erroneous element on GetterSend');
942 }
943
944 // Reference to constant local, top-level or static field
945 if (element != null && element.isConst) {
946 return translateConstant(node);
947 }
948
949 // Reference to local variable
950 if (Elements.isLocal(element)) {
951 return lookupLocal(element);
952 }
953
954 // Dynamic dispatch to a getter. Sometimes resolution will suggest a target
955 // element, but in these cases we must still emit a dynamic dispatch.
956 // The target element may be an instance method in case we are converting
957 // a method to a function object.
958 if (element == null ||
959 Elements.isInstanceField(element) ||
960 Elements.isInstanceMethod(element)) {
961 ir.Primitive receiver = node.receiver == null
962 ? lookupThis()
963 : visit(node.receiver);
964 ir.Parameter v = new ir.Parameter(null);
965 ir.Continuation k = new ir.Continuation([v]);
966 Selector selector = elements.getSelector(node);
967 assert(selector.kind == SelectorKind.GETTER);
968 ir.InvokeMethod invoke = new ir.InvokeMethod(receiver, selector, k, []);
969 add(new ir.LetCont(k, invoke));
970 return v;
971 }
972
973 // Access to a static field or getter (non-static case handled above).
974 if (element.isField || element.isGetter) {
975 ir.Parameter v = new ir.Parameter(null);
976 ir.Continuation k = new ir.Continuation([v]);
977 Selector selector = elements.getSelector(node);
978 assert(selector.kind == SelectorKind.GETTER);
979 ir.InvokeStatic invoke = new ir.InvokeStatic(element, selector, k, []);
980 add(new ir.LetCont(k, invoke));
981 return v;
982 }
983
984 // Convert a top-level or static function to a function object.
985 if (Elements.isStaticOrTopLevelFunction(element)) {
986 return translateConstant(node);
987 }
988
989 throw "Unexpected GetterSend: $node, $element";
990 } 1035 }
991 1036
992 ir.Primitive buildNegation(ir.Primitive condition) { 1037 ir.Primitive buildNegation(ir.Primitive condition) {
993 // ! e is translated as e ? false : true 1038 // ! e is translated as e ? false : true
994 1039
995 // Add a continuation parameter for the result of the expression. 1040 // Add a continuation parameter for the result of the expression.
996 ir.Parameter resultParameter = new ir.Parameter(null); 1041 ir.Parameter resultParameter = new ir.Parameter(null);
997 1042
998 ir.Continuation joinContinuation = new ir.Continuation([resultParameter]); 1043 ir.Continuation joinContinuation = new ir.Continuation([resultParameter]);
999 ir.Continuation thenContinuation = new ir.Continuation([]); 1044 ir.Continuation thenContinuation = new ir.Continuation([]);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 ir.Parameter v = new ir.Parameter(null); 1219 ir.Parameter v = new ir.Parameter(null);
1175 ir.Continuation k = new ir.Continuation([v]); 1220 ir.Continuation k = new ir.Continuation([v]);
1176 ir.Expression invoke = 1221 ir.Expression invoke =
1177 new ir.InvokeStatic(element, selector, k, arguments); 1222 new ir.InvokeStatic(element, selector, k, arguments);
1178 add(new ir.LetCont(k, invoke)); 1223 add(new ir.LetCont(k, invoke));
1179 return v; 1224 return v;
1180 } 1225 }
1181 1226
1182 ir.Primitive visitSuperSend(ast.Send node) { 1227 ir.Primitive visitSuperSend(ast.Send node) {
1183 assert(isOpen); 1228 assert(isOpen);
1184 return giveup(node, 'SuperSend'); 1229 if (node.isPropertyAccess) {
1230 return visitGetterSend(node);
1231 } else {
1232 return visitDynamicSend(node);
1233 }
1185 } 1234 }
1186 1235
1187 ir.Primitive visitTypeReferenceSend(ast.Send node) { 1236 ir.Primitive visitTypeReferenceSend(ast.Send node) {
1188 assert(isOpen); 1237 assert(isOpen);
1189 Element element = elements[node]; 1238 Element element = elements[node];
1190 assert(element is TypeDeclarationElement || element.isTypeVariable); 1239 assert(element is TypeDeclarationElement || element.isTypeVariable);
1191 1240
1192 // If the user is trying to invoke the type literal or variable, 1241 // If the user is trying to invoke the type literal or variable,
1193 // it must be treated as a function call. 1242 // it must be treated as a function call.
1194 if (node.argumentsNode != null) { 1243 if (node.argumentsNode != null) {
1195 return visitDynamicSend(node); 1244 return visitDynamicSend(node);
1196 } 1245 }
1197 1246
1198 if (element is TypeDeclarationElement) { 1247 if (element is TypeDeclarationElement) {
1199 return translateConstant(node); 1248 return translateConstant(node);
1200 } else { 1249 } else {
1201 ir.Primitive prim = new ir.ReifyTypeVar(element); 1250 ir.Primitive prim = new ir.ReifyTypeVar(element);
1202 add(new ir.LetPrim(prim)); 1251 add(new ir.LetPrim(prim));
1203 return prim; 1252 return prim;
1204 } 1253 }
1205 } 1254 }
1206 1255
1207 ir.Primitive visitSendSet(ast.SendSet node) { 1256 ir.Primitive visitSendSet(ast.SendSet node) {
1208 assert(isOpen); 1257 assert(isOpen);
1209 Element element = elements[node]; 1258 Element element = elements[node];
1210 ast.Operator op = node.assignmentOperator; 1259 ast.Operator op = node.assignmentOperator;
1211 ir.Primitive result; 1260 // For complex operators, this is the result of getting (before assigning)
1212 ir.Primitive getter; 1261 ir.Primitive originalValue;
1213 if (op.source == '=') { 1262 // For []+= style operators, this saves the index.
1214 if (Elements.isLocal(element)) { 1263 ir.Primitive index;
1215 // Exactly one argument expected for a simple assignment. 1264 ir.Primitive receiver;
1216 assert(!node.arguments.isEmpty); 1265 // This is what gets assigned.
1217 assert(node.arguments.tail.isEmpty); 1266 ir.Primitive valueToStore;
1218 result = visit(node.arguments.head); 1267 Selector selector = elements.getSelector(node);
1219 result.useElementAsHint(element); 1268 Selector operatorSelector =
1220 assignedVars[variableIndex[element]] = result; 1269 elements.getOperatorSelectorInComplexSendSet(node);
1221 return result; 1270 Selector getterSelector =
1222 } else if (Elements.isStaticOrTopLevel(element)) { 1271 elements.getGetterSelectorInComplexSendSet(node);
1223 assert(element.isField || element.isSetter); 1272 assert(
1224 assert(!node.arguments.isEmpty && node.arguments.tail.isEmpty); 1273 // Indexing send-sets have an argument for the index.
1225 ir.Parameter v = new ir.Parameter(null); 1274 (selector.isIndexSet ? 1 : 0) +
1226 ir.Continuation k = new ir.Continuation([v]); 1275 // Non-increment send-sets have one more argument.
1227 Selector selector = elements.getSelector(node); 1276 (ast.Operator.INCREMENT_OPERATORS.contains(op.source) ? 0 : 1)
1228 ir.Definition arg = visit(node.arguments.head); 1277 == node.argumentCount());
1229 ir.InvokeStatic invoke =
1230 new ir.InvokeStatic(element, selector, k, [arg]);
1231 add(new ir.LetCont(k, invoke));
1232 return arg;
1233 } else if (node.receiver == null) {
1234 // Nodes that fall in this case:
1235 // - Unresolved top-level
1236 // - Assignment to final variable (will not be resolved)
1237 return giveup(node, 'SendSet: non-local, non-static, but no receiver');
1238 } else {
1239 if (element != null && Elements.isUnresolved(element)) {
1240 return giveup(node);
1241 }
1242 1278
1243 // Setter or index-setter invocation 1279 ast.Node assignArg = selector.isIndexSet
1244 assert(node.receiver != null); 1280 ? node.arguments.tail.head
1281 : node.arguments.head;
1245 1282
1246 if (node.receiver.isSuper()) return giveup(node, 'Super SendSet'); 1283 // Get the value into valueToStore
1284 if (op.source == "=") {
1285 if (selector.isIndexSet) {
1286 receiver = visitReceiver(node.receiver);
1287 index = visit(node.arguments.head);
1288 } else if (element == null || Elements.isInstanceField(element)) {
1289 receiver = visitReceiver(node.receiver);
1290 }
1291 valueToStore = visit(assignArg);
1292 } else {
1293 // Get the original value into getter
1294 assert(ast.Operator.COMPLEX_OPERATORS.contains(op.source));
1247 1295
1248 ir.Primitive receiver = node.receiver == null 1296 _GetterElements getterResult = translateGetter(node, getterSelector);
1249 ? lookupThis() 1297 index = getterResult.index;
1250 : visit(node.receiver); 1298 receiver = getterResult.receiver;
1251 ir.Parameter v = new ir.Parameter(null); 1299 originalValue = getterResult.result;
1252 ir.Continuation k = new ir.Continuation([v]);
1253 Selector selector = elements.getSelector(node);
1254 assert(selector.kind == SelectorKind.SETTER ||
1255 selector.kind == SelectorKind.INDEX);
1256 List<ir.Definition> args = node.arguments.mapToList(visit,
1257 growable:false);
1258 ir.InvokeMethod invoke =
1259 new ir.InvokeMethod(receiver, selector, k, args);
1260 add(new ir.LetCont(k, invoke));
1261 return args.last;
1262 }
1263 } else if (ast.Operator.COMPLEX_OPERATORS.contains(op.source)) {
1264 Element selectorElement = elements[node.selector];
1265 if (selectorElement != null && !selectorElement.isAssignable) {
1266 return giveup(node, 'Unresolved or non-assignable compound assignment');
1267 }
1268 if (!Elements.isLocal(selectorElement)) {
1269 return giveup(node, 'Non-local compound assignment');
1270 }
1271 1300
1272 Selector selector = elements.getOperatorSelectorInComplexSendSet(node); 1301 // Do the modification of the value in getter.
1273 getter = lookupLocal(selectorElement);
1274
1275 ir.Primitive arg; 1302 ir.Primitive arg;
1276 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) { 1303 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) {
1277 assert(node.arguments.isEmpty);
1278 arg = makePrimConst(constantSystem.createInt(1)); 1304 arg = makePrimConst(constantSystem.createInt(1));
1279 add(new ir.LetPrim(arg)); 1305 add(new ir.LetPrim(arg));
1280 } else { 1306 } else {
1281 assert(!node.arguments.isEmpty); 1307 arg = visit(assignArg);
1282 assert(node.arguments.tail.isEmpty);
1283 arg = visit(node.arguments.head);
1284 } 1308 }
1285 arg.useElementAsHint(element); 1309 valueToStore = new ir.Parameter(null);
1286 result = new ir.Parameter(null); 1310 ir.Continuation k = new ir.Continuation([valueToStore]);
1287 ir.Continuation k = new ir.Continuation([result]); 1311 ir.Expression invoke =
1288 ir.Expression invoke = new ir.InvokeMethod(getter, selector, k, [arg]); 1312 new ir.InvokeMethod(originalValue, operatorSelector, k, [arg]);
1289 add(new ir.LetCont(k, invoke)); 1313 add(new ir.LetCont(k, invoke));
1314 }
1290 1315
1291 assignedVars[variableIndex[element]] = result; 1316 // Set the value
1317 if (Elements.isLocal(element)) {
1318 valueToStore.useElementAsHint(element);
1319 assignedVars[variableIndex[element]] = valueToStore;
1320 } else if (Elements.isStaticOrTopLevel(element)) {
1321 assert(element.isField || element.isSetter);
1322 ir.Parameter v = new ir.Parameter(null);
1323 ir.Continuation k = new ir.Continuation([v]);
1324 Selector selector = elements.getSelector(node);
1325 ir.InvokeStatic invoke =
1326 new ir.InvokeStatic(element, selector, k, [valueToStore]);
1327 add(new ir.LetCont(k, invoke));
1328 } else {
1329 if (element != null && Elements.isUnresolved(element)) {
1330 return giveup(node, 'SendSet: non-local, non-static, unresolved');
1331 }
1332 // Setter or index-setter invocation
1333 ir.Parameter v = new ir.Parameter(null);
1334 ir.Continuation k = new ir.Continuation([v]);
1335 Selector selector = elements.getSelector(node);
1336 assert(selector.kind == SelectorKind.SETTER ||
1337 selector.kind == SelectorKind.INDEX);
1338 List<ir.Definition> arguments = selector.isIndexSet
1339 ? [index, valueToStore]
1340 : [valueToStore];
1341 ir.Expression invoke =
1342 createDynamicInvoke(node, selector, receiver, k, arguments);
1343 add(new ir.LetCont(k, invoke));
1344 }
1292 1345
1293 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source) && 1346 if (node.isPostfix) {
1294 !node.isPrefix) { 1347 assert(originalValue != null);
1295 assert(getter != null); 1348 return originalValue;
1296 return getter;
1297 } else {
1298 return result;
1299 }
1300 } else { 1349 } else {
1301 compiler.internalError(node, "Unknown assignment operator ${op.source}"); 1350 return valueToStore;
1302 return null;
1303 } 1351 }
1304 } 1352 }
1305 1353
1306 ir.Primitive visitNewExpression(ast.NewExpression node) { 1354 ir.Primitive visitNewExpression(ast.NewExpression node) {
1307 assert(isOpen); 1355 assert(isOpen);
1308 if (node.isConst) { 1356 if (node.isConst) {
1309 return translateConstant(node); 1357 return translateConstant(node);
1310 } 1358 }
1311 FunctionElement element = elements[node.send]; 1359 FunctionElement element = elements[node.send];
1312 if (Elements.isUnresolved(element)) { 1360 if (Elements.isUnresolved(element)) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 1414
1367 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted"; 1415 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
1368 1416
1369 ir.Primitive giveup(ast.Node node, [String reason]) { 1417 ir.Primitive giveup(ast.Node node, [String reason]) {
1370 throw ABORT_IRNODE_BUILDER; 1418 throw ABORT_IRNODE_BUILDER;
1371 } 1419 }
1372 1420
1373 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) { 1421 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
1374 try { 1422 try {
1375 return action(); 1423 return action();
1376 } catch(e) { 1424 } catch(e, tr) {
1377 if (e == ABORT_IRNODE_BUILDER) return null; 1425 if (e == ABORT_IRNODE_BUILDER) {
1426 return null;
1427 }
1378 rethrow; 1428 rethrow;
1379 } 1429 }
1380 } 1430 }
1381 1431
1382 void internalError(String reason, {ast.Node node}) { 1432 void internalError(String reason, {ast.Node node}) {
1383 giveup(node); 1433 giveup(node);
1384 } 1434 }
1385 } 1435 }
1386 1436
1387 /// Translates constant expressions from the AST to the [ConstExp] language. 1437 /// Translates constant expressions from the AST to the [ConstExp] language.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1532 ConstExp visitConditional(ast.Conditional node) { 1582 ConstExp visitConditional(ast.Conditional node) {
1533 BoolConstant condition = computeConstant(node.condition); 1583 BoolConstant condition = computeConstant(node.condition);
1534 return visit(condition.isTrue ? node.thenExpression : node.elseExpression); 1584 return visit(condition.isTrue ? node.thenExpression : node.elseExpression);
1535 } 1585 }
1536 1586
1537 ConstExp visitNode(ast.Node node) { 1587 ConstExp visitNode(ast.Node node) {
1538 throw "Unexpected constant: $node"; 1588 throw "Unexpected constant: $node";
1539 } 1589 }
1540 1590
1541 } 1591 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698