| 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_task; | 5 library dart2js.ir_builder_task; |
| 6 | 6 |
| 7 import '../closure.dart' as closurelib; | 7 import '../closure.dart' as closurelib; |
| 8 import '../closure.dart' hide ClosureScope; | 8 import '../closure.dart' hide ClosureScope; |
| 9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 } | 849 } |
| 850 | 850 |
| 851 DartType type = elements.getTypeLiteralType(node); | 851 DartType type = elements.getTypeLiteralType(node); |
| 852 if (type is TypeVariableType) { | 852 if (type is TypeVariableType) { |
| 853 return buildReifyTypeVariable(irBuilder.buildThis(), type); | 853 return buildReifyTypeVariable(irBuilder.buildThis(), type); |
| 854 } else { | 854 } else { |
| 855 return translateConstant(node); | 855 return translateConstant(node); |
| 856 } | 856 } |
| 857 } | 857 } |
| 858 | 858 |
| 859 // TODO(karlklose): move to IrBuilder. Remove first argument. |
| 859 ir.Primitive buildReifyTypeVariable(ir.Primitive target, | 860 ir.Primitive buildReifyTypeVariable(ir.Primitive target, |
| 860 TypeVariableType variable); | 861 TypeVariableType variable); |
| 861 | 862 |
| 862 ir.Primitive visitSendSet(ast.SendSet node) { | 863 ir.Primitive visitSendSet(ast.SendSet node) { |
| 863 assert(irBuilder.isOpen); | 864 assert(irBuilder.isOpen); |
| 864 Element element = elements[node]; | 865 Element element = elements[node]; |
| 865 ast.Operator op = node.assignmentOperator; | 866 ast.Operator op = node.assignmentOperator; |
| 866 // For complex operators, this is the result of getting (before assigning) | 867 // For complex operators, this is the result of getting (before assigning) |
| 867 ir.Primitive originalValue; | 868 ir.Primitive originalValue; |
| 868 // For []+= style operators, this saves the index. | 869 // For []+= style operators, this saves the index. |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1276 @override | 1277 @override |
| 1277 ir.Primitive buildReifyTypeVariable(ir.Primitive target, | 1278 ir.Primitive buildReifyTypeVariable(ir.Primitive target, |
| 1278 TypeVariableType variable) { | 1279 TypeVariableType variable) { |
| 1279 assert(target is ir.This); | 1280 assert(target is ir.This); |
| 1280 ir.Primitive prim = new ir.ReifyTypeVar(variable.element); | 1281 ir.Primitive prim = new ir.ReifyTypeVar(variable.element); |
| 1281 irBuilder.add(new ir.LetPrim(prim)); | 1282 irBuilder.add(new ir.LetPrim(prim)); |
| 1282 return prim; | 1283 return prim; |
| 1283 } | 1284 } |
| 1284 } | 1285 } |
| 1285 | 1286 |
| 1287 /// The [IrBuilder]s view on the information about the program that has been |
| 1288 /// computed in resolution and and type interence. |
| 1289 class GlobalProgramInformation { |
| 1290 final Compiler _compiler; |
| 1291 JavaScriptBackend get _backend => _compiler.backend; |
| 1292 |
| 1293 GlobalProgramInformation(this._compiler); |
| 1294 |
| 1295 /// Returns [true], if the analysis could not determine that the type |
| 1296 /// arguments for the class [cls] are never used in the program. |
| 1297 bool requiresRuntimeTypesFor(ClassElement cls) { |
| 1298 return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls); |
| 1299 } |
| 1300 } |
| 1301 |
| 1286 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. | 1302 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. |
| 1287 class JsIrBuilderVisitor extends IrBuilderVisitor { | 1303 class JsIrBuilderVisitor extends IrBuilderVisitor { |
| 1288 /// Promote the type of [irBuilder] to [JsIrBuilder]. | 1304 /// Promote the type of [irBuilder] to [JsIrBuilder]. |
| 1289 JsIrBuilder get irBuilder => super.irBuilder; | 1305 JsIrBuilder get irBuilder => super.irBuilder; |
| 1290 | 1306 |
| 1291 /// Result of closure conversion for the current body of code. | 1307 /// Result of closure conversion for the current body of code. |
| 1292 /// | 1308 /// |
| 1293 /// Will be initialized upon entering the body of a function. | 1309 /// Will be initialized upon entering the body of a function. |
| 1294 /// It is computed by the [ClosureTranslator]. | 1310 /// It is computed by the [ClosureTranslator]. |
| 1295 ClosureClassMap closureMap; | 1311 ClosureClassMap closureMap; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1421 /// Such constants need to be compiled with a different [sourceFile] and | 1437 /// Such constants need to be compiled with a different [sourceFile] and |
| 1422 /// [elements] mapping. | 1438 /// [elements] mapping. |
| 1423 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { | 1439 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { |
| 1424 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( | 1440 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( |
| 1425 context.resolvedAst.elements, | 1441 context.resolvedAst.elements, |
| 1426 compiler, | 1442 compiler, |
| 1427 sourceInformationBuilder.forContext(context)); | 1443 sourceInformationBuilder.forContext(context)); |
| 1428 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp)); | 1444 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp)); |
| 1429 } | 1445 } |
| 1430 | 1446 |
| 1447 JsIrBuilder getBuilderFor(Element element) { |
| 1448 return new JsIrBuilder( |
| 1449 new GlobalProgramInformation(compiler), |
| 1450 compiler.backend.constantSystem, |
| 1451 element); |
| 1452 } |
| 1453 |
| 1431 /// Builds the IR for a given constructor. | 1454 /// Builds the IR for a given constructor. |
| 1432 /// | 1455 /// |
| 1433 /// 1. Evaluates all own or inherited field initializers. | 1456 /// 1. Evaluates all own or inherited field initializers. |
| 1434 /// 2. Creates the object and assigns its fields. | 1457 /// 2. Creates the object and assigns its fields. |
| 1435 /// 3. Calls constructor body and super constructor bodies. | 1458 /// 3. Calls constructor body and super constructor bodies. |
| 1436 /// 4. Returns the created object. | 1459 /// 4. Returns the created object. |
| 1437 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { | 1460 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { |
| 1438 constructor = constructor.implementation; | 1461 constructor = constructor.implementation; |
| 1439 ClassElement classElement = constructor.enclosingClass.implementation; | 1462 ClassElement classElement = constructor.enclosingClass.implementation; |
| 1440 | 1463 |
| 1441 JsIrBuilder builder = | 1464 JsIrBuilder builder = getBuilderFor(constructor); |
| 1442 new JsIrBuilder(compiler.backend.constantSystem, constructor); | 1465 |
| 1466 final bool requiresTypeInformation = |
| 1467 builder.program.requiresRuntimeTypesFor(classElement); |
| 1443 | 1468 |
| 1444 return withBuilder(builder, () { | 1469 return withBuilder(builder, () { |
| 1445 // Setup parameters and create a box if anything is captured. | 1470 // Setup parameters and create a box if anything is captured. |
| 1446 List<ParameterElement> parameters = []; | 1471 List<Local> parameters = <Local>[]; |
| 1447 constructor.functionSignature.orderedForEachParameter(parameters.add); | 1472 constructor.functionSignature.orderedForEachParameter( |
| 1448 builder.buildFunctionHeader(parameters, | 1473 // Note: the closure is explicit to allow typechecking [FormalElement] |
| 1474 // against [Local]. |
| 1475 (ParameterElement p) => parameters.add(p)); |
| 1476 |
| 1477 int firstTypeArgumentParameterIndex; |
| 1478 |
| 1479 // If instances of the class may need runtime type information, we add a |
| 1480 // synthetic parameter for each type parameter. |
| 1481 if (requiresTypeInformation) { |
| 1482 firstTypeArgumentParameterIndex = parameters.length; |
| 1483 classElement.typeVariables.forEach((TypeVariableType variable) { |
| 1484 parameters.add( |
| 1485 new TypeInformationParameter(variable.element, constructor)); |
| 1486 }); |
| 1487 } |
| 1488 |
| 1489 // Create IR parameters and setup the environment. |
| 1490 List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters, |
| 1449 closureScope: getClosureScopeForFunction(constructor)); | 1491 closureScope: getClosureScopeForFunction(constructor)); |
| 1450 | 1492 |
| 1493 // Create a list of the values of all type argument parameters, if any. |
| 1494 List<ir.Primitive> typeInformation; |
| 1495 if (requiresTypeInformation) { |
| 1496 List<ir.Primitive> typeArgumentParameters = <ir.Primitive>[]; |
| 1497 for (int index = firstTypeArgumentParameterIndex; |
| 1498 index < irParameters.length; |
| 1499 ++index) { |
| 1500 typeArgumentParameters.add(irParameters[index]); |
| 1501 } |
| 1502 typeInformation = typeArgumentParameters; |
| 1503 } |
| 1504 |
| 1451 // -- Step 1: evaluate field initializers --- | 1505 // -- Step 1: evaluate field initializers --- |
| 1452 // Evaluate field initializers in constructor and super constructors. | 1506 // Evaluate field initializers in constructor and super constructors. |
| 1507 irBuilder.enterInitializers(); |
| 1453 List<ConstructorElement> constructorList = <ConstructorElement>[]; | 1508 List<ConstructorElement> constructorList = <ConstructorElement>[]; |
| 1454 evaluateConstructorFieldInitializers(constructor, constructorList); | 1509 evaluateConstructorFieldInitializers(constructor, constructorList); |
| 1455 | 1510 irBuilder.leaveInitializers(); |
| 1511 |
| 1456 // All parameters in all constructors are now bound in the environment. | 1512 // All parameters in all constructors are now bound in the environment. |
| 1457 // BoxLocals for captured parameters are also in the environment. | 1513 // BoxLocals for captured parameters are also in the environment. |
| 1458 // The initial value of all fields are now bound in [fieldValues]. | 1514 // The initial value of all fields are now bound in [fieldValues]. |
| 1459 | 1515 |
| 1460 // --- Step 2: create the object --- | 1516 // --- Step 2: create the object --- |
| 1461 // Get the initial field values in the canonical order. | 1517 // Get the initial field values in the canonical order. |
| 1462 List<ir.Primitive> instanceArguments = <ir.Primitive>[]; | 1518 List<ir.Primitive> instanceArguments = <ir.Primitive>[]; |
| 1463 classElement.forEachInstanceField((ClassElement c, FieldElement field) { | 1519 classElement.forEachInstanceField((ClassElement c, FieldElement field) { |
| 1464 ir.Primitive value = fieldValues[field]; | 1520 ir.Primitive value = fieldValues[field]; |
| 1465 if (value != null) { | 1521 if (value != null) { |
| 1466 instanceArguments.add(fieldValues[field]); | 1522 instanceArguments.add(fieldValues[field]); |
| 1467 } else { | 1523 } else { |
| 1468 assert(Elements.isNativeOrExtendsNative(c)); | 1524 assert(Elements.isNativeOrExtendsNative(c)); |
| 1469 // Native fields are initialized elsewhere. | 1525 // Native fields are initialized elsewhere. |
| 1470 } | 1526 } |
| 1471 }, includeSuperAndInjectedMembers: true); | 1527 }, includeSuperAndInjectedMembers: true); |
| 1472 ir.Primitive instance = | 1528 ir.Primitive instance = new ir.CreateInstance( |
| 1473 new ir.CreateInstance(classElement, instanceArguments); | 1529 classElement, |
| 1530 instanceArguments, |
| 1531 typeInformation); |
| 1474 irBuilder.add(new ir.LetPrim(instance)); | 1532 irBuilder.add(new ir.LetPrim(instance)); |
| 1475 | 1533 |
| 1476 // --- Step 3: call constructor bodies --- | 1534 // --- Step 3: call constructor bodies --- |
| 1477 for (ConstructorElement target in constructorList) { | 1535 for (ConstructorElement target in constructorList) { |
| 1478 ConstructorBodyElement bodyElement = getConstructorBody(target); | 1536 ConstructorBodyElement bodyElement = getConstructorBody(target); |
| 1479 if (bodyElement == null) continue; // Skip if constructor has no body. | 1537 if (bodyElement == null) continue; // Skip if constructor has no body. |
| 1480 List<ir.Primitive> bodyArguments = <ir.Primitive>[]; | 1538 List<ir.Primitive> bodyArguments = <ir.Primitive>[]; |
| 1481 for (Local param in getConstructorBodyParameters(bodyElement)) { | 1539 for (Local param in getConstructorBodyParameters(bodyElement)) { |
| 1482 bodyArguments.add(irBuilder.environment.lookup(param)); | 1540 bodyArguments.add(irBuilder.environment.lookup(param)); |
| 1483 } | 1541 } |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1697 /// This function is invoked from one or more "factory" constructors built by | 1755 /// This function is invoked from one or more "factory" constructors built by |
| 1698 /// [buildConstructor]. | 1756 /// [buildConstructor]. |
| 1699 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { | 1757 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { |
| 1700 ConstructorElement constructor = body.constructor; | 1758 ConstructorElement constructor = body.constructor; |
| 1701 ast.FunctionExpression node = constructor.node; | 1759 ast.FunctionExpression node = constructor.node; |
| 1702 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( | 1760 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( |
| 1703 constructor, | 1761 constructor, |
| 1704 node, | 1762 node, |
| 1705 elements); | 1763 elements); |
| 1706 | 1764 |
| 1707 JsIrBuilder builder = | 1765 JsIrBuilder builder = getBuilderFor(body); |
| 1708 new JsIrBuilder(compiler.backend.constantSystem, body); | |
| 1709 | 1766 |
| 1710 return withBuilder(builder, () { | 1767 return withBuilder(builder, () { |
| 1711 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), | 1768 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), |
| 1712 getClosureScopeForNode(node)); | 1769 getClosureScopeForNode(node)); |
| 1713 visit(node.body); | 1770 visit(node.body); |
| 1714 return irBuilder.makeFunctionDefinition([]); | 1771 return irBuilder.makeFunctionDefinition([]); |
| 1715 }); | 1772 }); |
| 1716 } | 1773 } |
| 1717 | 1774 |
| 1718 ir.FunctionDefinition buildFunction(FunctionElement element) { | 1775 ir.FunctionDefinition buildFunction(FunctionElement element) { |
| 1719 assert(invariant(element, element.isImplementation)); | 1776 assert(invariant(element, element.isImplementation)); |
| 1720 ast.FunctionExpression node = element.node; | 1777 ast.FunctionExpression node = element.node; |
| 1721 | 1778 |
| 1722 assert(!element.isSynthesized); | 1779 assert(!element.isSynthesized); |
| 1723 assert(node != null); | 1780 assert(node != null); |
| 1724 assert(elements[node] != null); | 1781 assert(elements[node] != null); |
| 1725 | 1782 |
| 1726 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( | 1783 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( |
| 1727 element, | 1784 element, |
| 1728 node, | 1785 node, |
| 1729 elements); | 1786 elements); |
| 1730 IrBuilder builder = | 1787 IrBuilder builder = getBuilderFor(element); |
| 1731 new JsIrBuilder(compiler.backend.constantSystem, element); | |
| 1732 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 1788 return withBuilder(builder, () => _makeFunctionBody(element, node)); |
| 1733 } | 1789 } |
| 1734 | 1790 |
| 1735 /// Creates a primitive for the default value of [parameter]. | 1791 /// Creates a primitive for the default value of [parameter]. |
| 1736 ir.Primitive translateDefaultValue(ParameterElement parameter) { | 1792 ir.Primitive translateDefaultValue(ParameterElement parameter) { |
| 1737 if (parameter.initializer == null) { | 1793 if (parameter.initializer == null) { |
| 1738 return irBuilder.buildNullLiteral(); | 1794 return irBuilder.buildNullLiteral(); |
| 1739 } else { | 1795 } else { |
| 1740 return inlineConstant(parameter.executableContext, parameter.initializer); | 1796 return inlineConstant(parameter.executableContext, parameter.initializer); |
| 1741 } | 1797 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1803 int nameIndex = selector.namedArguments.indexOf(argName); | 1859 int nameIndex = selector.namedArguments.indexOf(argName); |
| 1804 int translatedIndex = selector.positionalArgumentCount + nameIndex; | 1860 int translatedIndex = selector.positionalArgumentCount + nameIndex; |
| 1805 result.add(arguments[translatedIndex]); | 1861 result.add(arguments[translatedIndex]); |
| 1806 } | 1862 } |
| 1807 return result; | 1863 return result; |
| 1808 } | 1864 } |
| 1809 | 1865 |
| 1810 @override | 1866 @override |
| 1811 ir.Primitive buildReifyTypeVariable(ir.Primitive target, | 1867 ir.Primitive buildReifyTypeVariable(ir.Primitive target, |
| 1812 TypeVariableType variable) { | 1868 TypeVariableType variable) { |
| 1813 ir.Primitive typeArgument = new ir.ReadTypeVariable(variable, target); | 1869 ir.Primitive typeArgument = |
| 1814 irBuilder.add(new ir.LetPrim(typeArgument)); | 1870 irBuilder.buildTypeVariableAccess(target, variable); |
| 1871 |
| 1815 ir.Primitive type = new ir.ReifyRuntimeType(typeArgument); | 1872 ir.Primitive type = new ir.ReifyRuntimeType(typeArgument); |
| 1816 irBuilder.add(new ir.LetPrim(type)); | 1873 irBuilder.add(new ir.LetPrim(type)); |
| 1817 return type; | 1874 return type; |
| 1818 } | 1875 } |
| 1819 } | 1876 } |
| 1820 | 1877 |
| 1821 /// Interface for generating [SourceInformation] for the CPS. | 1878 /// Interface for generating [SourceInformation] for the CPS. |
| 1822 class SourceInformationBuilder { | 1879 class SourceInformationBuilder { |
| 1823 const SourceInformationBuilder(); | 1880 const SourceInformationBuilder(); |
| 1824 | 1881 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1851 SourceInformation buildCall(ast.Node node) { | 1908 SourceInformation buildCall(ast.Node node) { |
| 1852 return new PositionSourceInformation( | 1909 return new PositionSourceInformation( |
| 1853 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); | 1910 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); |
| 1854 } | 1911 } |
| 1855 | 1912 |
| 1856 @override | 1913 @override |
| 1857 SourceInformationBuilder forContext(AstElement element) { | 1914 SourceInformationBuilder forContext(AstElement element) { |
| 1858 return new PositionSourceInformationBuilder(element); | 1915 return new PositionSourceInformationBuilder(element); |
| 1859 } | 1916 } |
| 1860 } | 1917 } |
| OLD | NEW |