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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart

Issue 1011403003: cps-ir: Set runtime type information for new objects that require it. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add parameter for each type variable to the JS-factory. Created 5 years, 9 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_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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698