| OLD | NEW | 
|---|
| 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 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1027     add(new ir.LetCont(k, invoke)); | 1027     add(new ir.LetCont(k, invoke)); | 
| 1028     return v; | 1028     return v; | 
| 1029   } | 1029   } | 
| 1030 | 1030 | 
| 1031   _GetterElements translateGetter(ast.Send node, Selector selector) { | 1031   _GetterElements translateGetter(ast.Send node, Selector selector) { | 
| 1032     Element element = elements[node]; | 1032     Element element = elements[node]; | 
| 1033     ir.Primitive result; | 1033     ir.Primitive result; | 
| 1034     ir.Primitive receiver; | 1034     ir.Primitive receiver; | 
| 1035     ir.Primitive index; | 1035     ir.Primitive index; | 
| 1036 | 1036 | 
| 1037     if (Elements.isErroneousElement(element)) { |  | 
| 1038       giveup(node, 'Erroneous element on GetterSend'); |  | 
| 1039       return null; |  | 
| 1040     } |  | 
| 1041 |  | 
| 1042     if (element != null && element.isConst) { | 1037     if (element != null && element.isConst) { | 
| 1043       // Reference to constant local, top-level or static field | 1038       // Reference to constant local, top-level or static field | 
| 1044 | 1039 | 
| 1045       result = translateConstant(node); | 1040       result = translateConstant(node); | 
| 1046     } else if (Elements.isLocal(element)) { | 1041     } else if (Elements.isLocal(element)) { | 
| 1047       // Reference to local variable | 1042       // Reference to local variable | 
| 1048 | 1043 | 
| 1049       result = lookupLocal(element); | 1044       result = lookupLocal(element); | 
| 1050     } else if (element == null || | 1045     } else if (element == null || | 
| 1051                Elements.isInstanceField(element) || | 1046                Elements.isInstanceField(element) || | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 1065       } | 1060       } | 
| 1066 | 1061 | 
| 1067       ir.Parameter v = new ir.Parameter(null); | 1062       ir.Parameter v = new ir.Parameter(null); | 
| 1068       ir.Continuation k = new ir.Continuation([v]); | 1063       ir.Continuation k = new ir.Continuation([v]); | 
| 1069       assert(selector.kind == SelectorKind.GETTER || | 1064       assert(selector.kind == SelectorKind.GETTER || | 
| 1070              selector.kind == SelectorKind.INDEX); | 1065              selector.kind == SelectorKind.INDEX); | 
| 1071       ir.Expression invoke = | 1066       ir.Expression invoke = | 
| 1072           createDynamicInvoke(node, selector, receiver, k, arguments); | 1067           createDynamicInvoke(node, selector, receiver, k, arguments); | 
| 1073       add(new ir.LetCont(k, invoke)); | 1068       add(new ir.LetCont(k, invoke)); | 
| 1074       result = v; | 1069       result = v; | 
| 1075     } else if (element.isField || element.isGetter || | 1070     } else if (element.isField || element.isGetter || element.isErroneous || | 
| 1076         // Access to a static field or getter (non-static case handled above). | 1071         // Access to a static field or getter (non-static case handled above). | 
| 1077         // Even if there is only a setter, we compile as if it was a getter, | 1072         // Even if there is only a setter, we compile as if it was a getter, | 
| 1078         // so the vm can fail at runtime. | 1073         // so the vm can fail at runtime. | 
| 1079 |  | 
| 1080         element.isSetter) { | 1074         element.isSetter) { | 
| 1081       ir.Parameter v = new ir.Parameter(null); | 1075       ir.Parameter v = new ir.Parameter(null); | 
| 1082       ir.Continuation k = new ir.Continuation([v]); | 1076       ir.Continuation k = new ir.Continuation([v]); | 
| 1083       assert(selector.kind == SelectorKind.GETTER || | 1077       assert(selector.kind == SelectorKind.GETTER || | 
| 1084              selector.kind == SelectorKind.SETTER); | 1078              selector.kind == SelectorKind.SETTER); | 
| 1085       ir.Expression invoke = | 1079       ir.Expression invoke = | 
| 1086           new ir.InvokeStatic(element, selector, k, []); | 1080           new ir.InvokeStatic(element, selector, k, []); | 
| 1087       add(new ir.LetCont(k, invoke)); | 1081       add(new ir.LetCont(k, invoke)); | 
| 1088       result = v; | 1082       result = v; | 
| 1089     } else if (Elements.isStaticOrTopLevelFunction(element)) { | 1083     } else if (Elements.isStaticOrTopLevelFunction(element)) { | 
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1237       return buildNegation(visit(node.receiver)); | 1231       return buildNegation(visit(node.receiver)); | 
| 1238     } | 1232     } | 
| 1239     if (op.source == "!=") { | 1233     if (op.source == "!=") { | 
| 1240       assert(node.receiver != null); | 1234       assert(node.receiver != null); | 
| 1241       assert(!node.arguments.isEmpty); | 1235       assert(!node.arguments.isEmpty); | 
| 1242       assert(node.arguments.tail.isEmpty); | 1236       assert(node.arguments.tail.isEmpty); | 
| 1243       return buildNegation(visitDynamicSend(node)); | 1237       return buildNegation(visitDynamicSend(node)); | 
| 1244     } | 1238     } | 
| 1245     if (op.source == "is") { | 1239     if (op.source == "is") { | 
| 1246       DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); | 1240       DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); | 
| 1247       if (type.isMalformed) return giveup(node, "Malformed type for is"); |  | 
| 1248       ir.Primitive receiver = visit(node.receiver); | 1241       ir.Primitive receiver = visit(node.receiver); | 
| 1249       ir.IsCheck isCheck = new ir.IsCheck(receiver, type); | 1242       ir.IsCheck isCheck = new ir.IsCheck(receiver, type); | 
| 1250       add(new ir.LetPrim(isCheck)); | 1243       add(new ir.LetPrim(isCheck)); | 
| 1251       return node.isIsNotCheck ? buildNegation(isCheck) : isCheck; | 1244       return node.isIsNotCheck ? buildNegation(isCheck) : isCheck; | 
| 1252     } | 1245     } | 
| 1253     if (op.source == "as") { | 1246     if (op.source == "as") { | 
| 1254       DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); | 1247       DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); | 
| 1255       if (type.isMalformed) return giveup(node, "Malformed type for as"); |  | 
| 1256       ir.Primitive receiver = visit(node.receiver); | 1248       ir.Primitive receiver = visit(node.receiver); | 
| 1257       ir.Parameter v = new ir.Parameter(null); | 1249       ir.Parameter v = new ir.Parameter(null); | 
| 1258       ir.Continuation k = new ir.Continuation([v]); | 1250       ir.Continuation k = new ir.Continuation([v]); | 
| 1259       ir.AsCast asCast = new ir.AsCast(receiver, type, k); | 1251       ir.AsCast asCast = new ir.AsCast(receiver, type, k); | 
| 1260       add(new ir.LetCont(k, asCast)); | 1252       add(new ir.LetCont(k, asCast)); | 
| 1261       return v; | 1253       return v; | 
| 1262     } | 1254     } | 
| 1263     return giveup(node); | 1255     compiler.internalError(node, "Unknown operator '${op.source}'"); | 
| 1264   } | 1256   } | 
| 1265 | 1257 | 
| 1266   // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] | 1258   // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] | 
| 1267   //   where (C', xs) = arguments.fold(Build, C) | 1259   //   where (C', xs) = arguments.fold(Build, C) | 
| 1268   ir.Primitive visitStaticSend(ast.Send node) { | 1260   ir.Primitive visitStaticSend(ast.Send node) { | 
| 1269     assert(isOpen); | 1261     assert(isOpen); | 
| 1270     Element element = elements[node]; | 1262     Element element = elements[node]; | 
| 1271     // TODO(lry): support constructors / factory calls. | 1263     assert(!element.isConstructor); | 
| 1272     if (element.isConstructor) return giveup(node, 'StaticSend: constructor'); |  | 
| 1273     // TODO(lry): support foreign functions. | 1264     // TODO(lry): support foreign functions. | 
| 1274     if (element.isForeign(compiler)) return giveup(node, 'StaticSend: foreign'); | 1265     if (element.isForeign(compiler)) return giveup(node, 'StaticSend: foreign'); | 
| 1275     // TODO(lry): for elements that could not be resolved emit code to throw a |  | 
| 1276     // [NoSuchMethodError]. |  | 
| 1277     if (element.isErroneous) return giveup(node, 'StaticSend: erroneous'); |  | 
| 1278     // TODO(lry): generate IR for object identicality. |  | 
| 1279     if (element == compiler.identicalFunction) { |  | 
| 1280       return giveup(node, 'StaticSend: identical'); |  | 
| 1281     } |  | 
| 1282 | 1266 | 
| 1283     Selector selector = elements.getSelector(node); | 1267     Selector selector = elements.getSelector(node); | 
| 1284 | 1268 | 
| 1285     // TODO(lry): support default arguments, need support for locals. | 1269     // TODO(lry): support default arguments, need support for locals. | 
| 1286     List<ir.Definition> arguments = node.arguments.mapToList(visit, | 1270     List<ir.Definition> arguments = node.arguments.mapToList(visit, | 
| 1287                                                              growable:false); | 1271                                                              growable:false); | 
| 1288     ir.Parameter v = new ir.Parameter(null); | 1272     ir.Parameter v = new ir.Parameter(null); | 
| 1289     ir.Continuation k = new ir.Continuation([v]); | 1273     ir.Continuation k = new ir.Continuation([v]); | 
| 1290     ir.Expression invoke = | 1274     ir.Expression invoke = | 
| 1291         new ir.InvokeStatic(element, selector, k, arguments); | 1275         new ir.InvokeStatic(element, selector, k, arguments); | 
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1382       ir.Continuation k = new ir.Continuation([valueToStore]); | 1366       ir.Continuation k = new ir.Continuation([valueToStore]); | 
| 1383       ir.Expression invoke = | 1367       ir.Expression invoke = | 
| 1384           new ir.InvokeMethod(originalValue, operatorSelector, k, [arg]); | 1368           new ir.InvokeMethod(originalValue, operatorSelector, k, [arg]); | 
| 1385       add(new ir.LetCont(k, invoke)); | 1369       add(new ir.LetCont(k, invoke)); | 
| 1386     } | 1370     } | 
| 1387 | 1371 | 
| 1388     // Set the value | 1372     // Set the value | 
| 1389     if (Elements.isLocal(element)) { | 1373     if (Elements.isLocal(element)) { | 
| 1390       valueToStore.useElementAsHint(element); | 1374       valueToStore.useElementAsHint(element); | 
| 1391       assignedVars[variableIndex[element]] = valueToStore; | 1375       assignedVars[variableIndex[element]] = valueToStore; | 
| 1392     } else if (Elements.isStaticOrTopLevel(element)) { | 1376     } else if ((!node.isSuperCall && Elements.isErroneousElement(element)) || | 
|  | 1377                 Elements.isStaticOrTopLevel(element)) { | 
| 1393       assert(element.isField || element.isSetter); | 1378       assert(element.isField || element.isSetter); | 
| 1394       ir.Parameter v = new ir.Parameter(null); | 1379       ir.Parameter v = new ir.Parameter(null); | 
| 1395       ir.Continuation k = new ir.Continuation([v]); | 1380       ir.Continuation k = new ir.Continuation([v]); | 
| 1396       Selector selector = elements.getSelector(node); | 1381       Selector selector = elements.getSelector(node); | 
| 1397       ir.InvokeStatic invoke = | 1382       ir.InvokeStatic invoke = | 
| 1398           new ir.InvokeStatic(element, selector, k, [valueToStore]); | 1383           new ir.InvokeStatic(element, selector, k, [valueToStore]); | 
| 1399       add(new ir.LetCont(k, invoke)); | 1384       add(new ir.LetCont(k, invoke)); | 
| 1400     } else { | 1385     } else { | 
| 1401       if (element != null && Elements.isUnresolved(element)) { |  | 
| 1402         return giveup(node, 'SendSet: non-local, non-static, unresolved'); |  | 
| 1403       } |  | 
| 1404       // Setter or index-setter invocation | 1386       // Setter or index-setter invocation | 
| 1405       ir.Parameter v = new ir.Parameter(null); | 1387       ir.Parameter v = new ir.Parameter(null); | 
| 1406       ir.Continuation k = new ir.Continuation([v]); | 1388       ir.Continuation k = new ir.Continuation([v]); | 
| 1407       Selector selector = elements.getSelector(node); | 1389       Selector selector = elements.getSelector(node); | 
| 1408       assert(selector.kind == SelectorKind.SETTER || | 1390       assert(selector.kind == SelectorKind.SETTER || | 
| 1409           selector.kind == SelectorKind.INDEX); | 1391           selector.kind == SelectorKind.INDEX); | 
| 1410       List<ir.Definition> arguments = selector.isIndexSet | 1392       List<ir.Definition> arguments = selector.isIndexSet | 
| 1411           ? [index, valueToStore] | 1393           ? [index, valueToStore] | 
| 1412           : [valueToStore]; | 1394           : [valueToStore]; | 
| 1413       ir.Expression invoke = | 1395       ir.Expression invoke = | 
| 1414           createDynamicInvoke(node, selector, receiver, k, arguments); | 1396           createDynamicInvoke(node, selector, receiver, k, arguments); | 
| 1415       add(new ir.LetCont(k, invoke)); | 1397       add(new ir.LetCont(k, invoke)); | 
| 1416     } | 1398     } | 
| 1417 | 1399 | 
| 1418     if (node.isPostfix) { | 1400     if (node.isPostfix) { | 
| 1419       assert(originalValue != null); | 1401       assert(originalValue != null); | 
| 1420       return originalValue; | 1402       return originalValue; | 
| 1421     } else { | 1403     } else { | 
| 1422       return valueToStore; | 1404       return valueToStore; | 
| 1423     } | 1405     } | 
| 1424   } | 1406   } | 
| 1425 | 1407 | 
| 1426   ir.Primitive visitNewExpression(ast.NewExpression node) { | 1408   ir.Primitive visitNewExpression(ast.NewExpression node) { | 
| 1427     assert(isOpen); | 1409     assert(isOpen); | 
| 1428     if (node.isConst) { | 1410     if (node.isConst) { | 
| 1429       return translateConstant(node); | 1411       return translateConstant(node); | 
| 1430     } | 1412     } | 
| 1431     FunctionElement element = elements[node.send]; | 1413     FunctionElement element = elements[node.send]; | 
| 1432     if (Elements.isUnresolved(element)) { |  | 
| 1433       return giveup(node, 'NewExpression: unresolved constructor'); |  | 
| 1434     } |  | 
| 1435     Selector selector = elements.getSelector(node.send); | 1414     Selector selector = elements.getSelector(node.send); | 
| 1436     ast.Node selectorNode = node.send.selector; | 1415     ast.Node selectorNode = node.send.selector; | 
| 1437     GenericType type = elements.getType(node); | 1416     DartType type = elements.getType(node); | 
| 1438     List<ir.Primitive> args = | 1417     List<ir.Primitive> args = | 
| 1439         node.send.arguments.mapToList(visit, growable:false); | 1418         node.send.arguments.mapToList(visit, growable:false); | 
| 1440     ir.Parameter v = new ir.Parameter(null); | 1419     ir.Parameter v = new ir.Parameter(null); | 
| 1441     ir.Continuation k = new ir.Continuation([v]); | 1420     ir.Continuation k = new ir.Continuation([v]); | 
| 1442     ir.InvokeConstructor invoke = | 1421     ir.InvokeConstructor invoke = | 
| 1443         new ir.InvokeConstructor(type, element,selector, k, args); | 1422         new ir.InvokeConstructor(type, element,selector, k, args); | 
| 1444     add(new ir.LetCont(k, invoke)); | 1423     add(new ir.LetCont(k, invoke)); | 
| 1445     return v; | 1424     return v; | 
| 1446   } | 1425   } | 
| 1447 | 1426 | 
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1655   ConstExp visitConditional(ast.Conditional node) { | 1634   ConstExp visitConditional(ast.Conditional node) { | 
| 1656     BoolConstant condition = computeConstant(node.condition); | 1635     BoolConstant condition = computeConstant(node.condition); | 
| 1657     return visit(condition.isTrue ? node.thenExpression : node.elseExpression); | 1636     return visit(condition.isTrue ? node.thenExpression : node.elseExpression); | 
| 1658   } | 1637   } | 
| 1659 | 1638 | 
| 1660   ConstExp visitNode(ast.Node node) { | 1639   ConstExp visitNode(ast.Node node) { | 
| 1661     throw "Unexpected constant: $node"; | 1640     throw "Unexpected constant: $node"; | 
| 1662   } | 1641   } | 
| 1663 | 1642 | 
| 1664 } | 1643 } | 
| OLD | NEW | 
|---|