Chromium Code Reviews| 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 closure; | 7 import '../closure.dart' as closure; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/names.dart' show | 9 import '../common/names.dart' show |
| 10 Names, | 10 Names, |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 /// 5. Returns the created object. | 375 /// 5. Returns the created object. |
| 376 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { | 376 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { |
| 377 // TODO(asgerf): Optimization: If constructor is redirecting, then just | 377 // TODO(asgerf): Optimization: If constructor is redirecting, then just |
| 378 // evaluate arguments and call the target constructor. | 378 // evaluate arguments and call the target constructor. |
| 379 constructor = constructor.implementation; | 379 constructor = constructor.implementation; |
| 380 ClassElement classElement = constructor.enclosingClass.implementation; | 380 ClassElement classElement = constructor.enclosingClass.implementation; |
| 381 | 381 |
| 382 IrBuilder builder = getBuilderFor(constructor); | 382 IrBuilder builder = getBuilderFor(constructor); |
| 383 | 383 |
| 384 final bool requiresTypeInformation = | 384 final bool requiresTypeInformation = |
| 385 builder.program.requiresRuntimeTypesFor(classElement); | 385 builder.program.requiresRuntimeTypesFor(classElement); |
| 386 | 386 |
| 387 return withBuilder(builder, () { | 387 return withBuilder(builder, () { |
| 388 // Setup parameters and create a box if anything is captured. | 388 // Setup parameters and create a box if anything is captured. |
| 389 List<Local> parameters = <Local>[]; | 389 List<Local> parameters = <Local>[]; |
| 390 constructor.functionSignature.orderedForEachParameter( | 390 constructor.functionSignature.orderedForEachParameter( |
| 391 (ParameterElement p) => parameters.add(p)); | 391 (ParameterElement p) => parameters.add(p)); |
| 392 | 392 |
| 393 int firstTypeArgumentParameterIndex; | 393 int firstTypeArgumentParameterIndex; |
| 394 | 394 |
| 395 // If instances of the class may need runtime type information, we add a | 395 // If instances of the class may need runtime type information, we add a |
| 396 // synthetic parameter for each type parameter. | 396 // synthetic parameter for each type parameter. |
| 397 if (requiresTypeInformation) { | 397 if (requiresTypeInformation) { |
| 398 firstTypeArgumentParameterIndex = parameters.length; | 398 firstTypeArgumentParameterIndex = parameters.length; |
| 399 classElement.typeVariables.forEach((TypeVariableType variable) { | 399 classElement.typeVariables.forEach((TypeVariableType variable) { |
| 400 parameters.add(new closure.TypeVariableLocal(variable, constructor)); | 400 parameters.add(new closure.TypeVariableLocal(variable, constructor)); |
| 401 }); | 401 }); |
| 402 } else { | 402 } else { |
| 403 classElement.typeVariables.forEach((TypeVariableType variable) { | 403 classElement.typeVariables.forEach((TypeVariableType variable) { |
| 404 irBuilder.declareTypeVariable(variable, const DynamicType()); | 404 irBuilder.declareTypeVariable(variable, const DynamicType()); |
| 405 }); | 405 }); |
| 406 } | 406 } |
| 407 | 407 |
| 408 // Create IR parameters and setup the environment. | 408 // Create IR parameters and setup the environment. |
| 409 List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters, | 409 List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters, |
| 410 closureScope: getClosureScopeForFunction(constructor)); | 410 closureScope: getClosureScopeForFunction(constructor)); |
| 411 | 411 |
| 412 // Create a list of the values of all type argument parameters, if any. | 412 // Create a list of the values of all type argument parameters, if any. |
| 413 List<ir.Primitive> typeInformation; | 413 ir.Primitive typeInformation; |
| 414 if (requiresTypeInformation) { | 414 if (requiresTypeInformation) { |
| 415 typeInformation = irParameters.sublist(firstTypeArgumentParameterIndex); | 415 typeInformation = new ir.TypeExpression( |
| 416 ir.TypeExpressionKind.INSTANCE, | |
| 417 classElement.thisType, | |
| 418 irParameters.sublist(firstTypeArgumentParameterIndex)); | |
| 419 irBuilder.add(new ir.LetPrim(typeInformation)); | |
| 416 } else { | 420 } else { |
| 417 typeInformation = const <ir.Primitive>[]; | 421 typeInformation = null; |
| 418 } | 422 } |
| 419 | 423 |
| 420 // -- Load values for type variables declared on super classes -- | 424 // -- Load values for type variables declared on super classes -- |
| 421 // Field initializers for super classes can reference these, so they | 425 // Field initializers for super classes can reference these, so they |
| 422 // must be available before evaluating field initializers. | 426 // must be available before evaluating field initializers. |
| 423 // This could be interleaved with field initialization, but we choose do | 427 // This could be interleaved with field initialization, but we choose do |
| 424 // get it out of the way here to avoid complications with mixins. | 428 // get it out of the way here to avoid complications with mixins. |
| 425 loadTypeVariablesForSuperClasses(classElement); | 429 loadTypeVariablesForSuperClasses(classElement); |
| 426 | 430 |
| 427 /// Maps each field from this class or a superclass to its initial value. | 431 /// Maps each field from this class or a superclass to its initial value. |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 746 assert(elements[node] != null); | 750 assert(elements[node] != null); |
| 747 | 751 |
| 748 closureClassMap = | 752 closureClassMap = |
| 749 compiler.closureToClassMapper.computeClosureToClassMapping( | 753 compiler.closureToClassMapper.computeClosureToClassMapping( |
| 750 element, | 754 element, |
| 751 node, | 755 node, |
| 752 elements); | 756 elements); |
| 753 TryBoxedVariables variables = _analyzeTryBoxedVariables(node); | 757 TryBoxedVariables variables = _analyzeTryBoxedVariables(node); |
| 754 tryStatements = variables.tryStatements; | 758 tryStatements = variables.tryStatements; |
| 755 IrBuilder builder = getBuilderFor(element); | 759 IrBuilder builder = getBuilderFor(element); |
| 756 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 760 return withBuilder(builder, |
| 761 () => _makeFunctionBody(builder, element, node)); | |
| 757 } | 762 } |
| 758 | 763 |
| 759 ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) { | 764 ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) { |
| 760 if (!backend.constants.lazyStatics.contains(element)) { | 765 if (!backend.constants.lazyStatics.contains(element)) { |
| 761 return null; // Nothing to do. | 766 return null; // Nothing to do. |
| 762 } | 767 } |
| 763 closureClassMap = | 768 closureClassMap = |
| 764 compiler.closureToClassMapper.computeClosureToClassMapping( | 769 compiler.closureToClassMapper.computeClosureToClassMapping( |
| 765 element, | 770 element, |
| 766 element.node, | 771 element.node, |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 868 if (constant != null && !field.isAssignable) { | 873 if (constant != null && !field.isAssignable) { |
| 869 typeMaskSystem.associateConstantValueWithElement(constant, field); | 874 typeMaskSystem.associateConstantValueWithElement(constant, field); |
| 870 return irBuilder.buildConstant(constant, sourceInformation: src); | 875 return irBuilder.buildConstant(constant, sourceInformation: src); |
| 871 } else if (backend.constants.lazyStatics.contains(field)) { | 876 } else if (backend.constants.lazyStatics.contains(field)) { |
| 872 return irBuilder.addPrimitive(new ir.GetLazyStatic(field, src)); | 877 return irBuilder.addPrimitive(new ir.GetLazyStatic(field, src)); |
| 873 } else { | 878 } else { |
| 874 return irBuilder.addPrimitive(new ir.GetStatic(field, src)); | 879 return irBuilder.addPrimitive(new ir.GetStatic(field, src)); |
| 875 } | 880 } |
| 876 } | 881 } |
| 877 | 882 |
| 878 ir.FunctionDefinition _makeFunctionBody(FunctionElement element, | 883 ir.FunctionDefinition _makeFunctionBody( |
| 879 ast.FunctionExpression node) { | 884 IrBuilder builder, |
| 885 FunctionElement element, | |
| 886 ast.FunctionExpression node) { | |
| 880 FunctionSignature signature = element.functionSignature; | 887 FunctionSignature signature = element.functionSignature; |
| 881 List<Local> parameters = <Local>[]; | 888 List<Local> parameters = <Local>[]; |
| 882 signature.orderedForEachParameter( | 889 signature.orderedForEachParameter( |
| 883 (LocalParameterElement e) => parameters.add(e)); | 890 (LocalParameterElement e) => parameters.add(e)); |
| 884 | 891 |
| 892 bool requiresRuntimeTypes = false; | |
| 885 if (element.isFactoryConstructor) { | 893 if (element.isFactoryConstructor) { |
| 886 // Type arguments are passed in as extra parameters. | 894 requiresRuntimeTypes = |
| 887 for (DartType typeVariable in element.enclosingClass.typeVariables) { | 895 builder.program.requiresRuntimeTypesFor(element.enclosingElement); |
| 888 parameters.add(new closure.TypeVariableLocal(typeVariable, element)); | 896 if (requiresRuntimeTypes) { |
|
sra1
2016/01/27 07:06:08
This caused a mismatch between call site and calle
| |
| 897 // Type arguments are passed in as extra parameters. | |
| 898 for (DartType typeVariable in element.enclosingClass.typeVariables) { | |
| 899 parameters.add(new closure.TypeVariableLocal(typeVariable, element)); | |
| 900 } | |
| 889 } | 901 } |
| 890 } | 902 } |
| 891 | 903 |
| 892 irBuilder.buildFunctionHeader(parameters, | 904 irBuilder.buildFunctionHeader(parameters, |
| 893 closureScope: getClosureScopeForNode(node), | 905 closureScope: getClosureScopeForNode(node), |
| 894 env: getClosureEnvironment()); | 906 env: getClosureEnvironment()); |
| 895 | 907 |
| 896 visit(node.body); | 908 if (element == helpers.jsArrayTypedConstructor) { |
| 909 // Generate a body for JSArray<E>.typed(allocation): | |
| 910 // | |
| 911 // t1 = setRuntimeTypeInfo(allocation, TypeExpression($E)); | |
| 912 // return Refinement(t1, <JSArray>); | |
| 913 // | |
| 914 assert(parameters.length == 1 || parameters.length == 2); | |
| 915 ir.Primitive allocation = irBuilder.buildLocalGet(parameters[0]); | |
| 916 ClassElement classElement = element.enclosingElement; | |
| 917 | |
| 918 // Only call setRuntimeTypeInfo if JSArray requires the type parameter. | |
| 919 if (requiresRuntimeTypes) { | |
| 920 assert(parameters.length == 2); | |
| 921 ir.Primitive typeArgument = | |
| 922 irBuilder.buildTypeVariableAccess(parameters[1].typeVariable); | |
| 923 | |
| 924 ir.Primitive typeInformation = irBuilder.addPrimitive( | |
| 925 new ir.TypeExpression(ir.TypeExpressionKind.INSTANCE, | |
| 926 element.enclosingClass.thisType, | |
| 927 <ir.Primitive>[typeArgument])); | |
| 928 | |
| 929 Element helper = helpers.setRuntimeTypeInfo; | |
| 930 CallStructure callStructure = CallStructure.TWO_ARGS; | |
| 931 Selector selector = new Selector.call(helper.memberName, callStructure); | |
| 932 allocation = irBuilder.buildInvokeStatic( | |
| 933 helper, selector, <ir.Primitive>[allocation, typeInformation], | |
| 934 sourceInformationBuilder.buildGeneric(node)); | |
| 935 } | |
| 936 | |
| 937 ir.Primitive refinement = irBuilder.addPrimitive( | |
| 938 new ir.Refinement(allocation, typeMaskSystem.arrayType)); | |
| 939 | |
| 940 irBuilder.buildReturn(value: refinement, | |
| 941 sourceInformation: | |
| 942 sourceInformationBuilder.buildImplicitReturn(element)); | |
| 943 } else { | |
| 944 visit(node.body); | |
| 945 } | |
| 897 return irBuilder.makeFunctionDefinition(); | 946 return irBuilder.makeFunctionDefinition(); |
| 898 } | 947 } |
| 899 | 948 |
| 900 /// Builds the IR for creating an instance of the closure class corresponding | 949 /// Builds the IR for creating an instance of the closure class corresponding |
| 901 /// to the given nested function. | 950 /// to the given nested function. |
| 902 closure.ClosureClassElement makeSubFunction(ast.FunctionExpression node) { | 951 closure.ClosureClassElement makeSubFunction(ast.FunctionExpression node) { |
| 903 closure.ClosureClassMap innerMap = | 952 closure.ClosureClassMap innerMap = |
| 904 compiler.closureToClassMapper.getMappingForNestedFunction(node); | 953 compiler.closureToClassMapper.getMappingForNestedFunction(node); |
| 905 closure.ClosureClassElement closureClass = innerMap.closureClassElement; | 954 closure.ClosureClassElement closureClass = innerMap.closureClassElement; |
| 906 return closureClass; | 955 return closureClass; |
| (...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1544 return compiler.typesTask.getGuaranteedTypeOfNode( | 1593 return compiler.typesTask.getGuaranteedTypeOfNode( |
| 1545 elements.analyzedElement, node); | 1594 elements.analyzedElement, node); |
| 1546 } | 1595 } |
| 1547 | 1596 |
| 1548 ir.Primitive visitLiteralList(ast.LiteralList node) { | 1597 ir.Primitive visitLiteralList(ast.LiteralList node) { |
| 1549 if (node.isConst) { | 1598 if (node.isConst) { |
| 1550 return translateConstant(node); | 1599 return translateConstant(node); |
| 1551 } | 1600 } |
| 1552 List<ir.Primitive> values = node.elements.nodes.mapToList(visit); | 1601 List<ir.Primitive> values = node.elements.nodes.mapToList(visit); |
| 1553 InterfaceType type = elements.getType(node); | 1602 InterfaceType type = elements.getType(node); |
| 1554 return irBuilder.buildListLiteral(type, values, | 1603 ir.Primitive list = irBuilder.buildListLiteral(type, values, |
| 1555 allocationSiteType: getAllocationSiteType(node)); | 1604 allocationSiteType: getAllocationSiteType(node)); |
| 1605 if (type.treatAsRaw) return list; | |
| 1606 // Call JSArray<E>.typed(allocation) to install the reified type. | |
| 1607 ConstructorElement constructor = helpers.jsArrayTypedConstructor; | |
|
sra1
2016/01/27 07:06:08
There is a small issue here with losing type preci
| |
| 1608 return irBuilder.buildConstructorInvocation( | |
| 1609 constructor.effectiveTarget, | |
| 1610 CallStructure.ONE_ARG, | |
| 1611 constructor.computeEffectiveTargetType(type), | |
| 1612 <ir.Primitive>[list], | |
| 1613 sourceInformationBuilder.buildNew(node)); | |
| 1556 } | 1614 } |
| 1557 | 1615 |
| 1558 ir.Primitive visitLiteralMap(ast.LiteralMap node) { | 1616 ir.Primitive visitLiteralMap(ast.LiteralMap node) { |
| 1559 assert(irBuilder.isOpen); | 1617 assert(irBuilder.isOpen); |
| 1560 if (node.isConst) { | 1618 if (node.isConst) { |
| 1561 return translateConstant(node); | 1619 return translateConstant(node); |
| 1562 } | 1620 } |
| 1563 | 1621 |
| 1564 InterfaceType type = elements.getType(node); | 1622 InterfaceType type = elements.getType(node); |
| 1565 | 1623 |
| (...skipping 2257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3823 } | 3881 } |
| 3824 | 3882 |
| 3825 Element get closureConverter { | 3883 Element get closureConverter { |
| 3826 return _backend.helpers.closureConverter; | 3884 return _backend.helpers.closureConverter; |
| 3827 } | 3885 } |
| 3828 | 3886 |
| 3829 void addNativeMethod(FunctionElement function) { | 3887 void addNativeMethod(FunctionElement function) { |
| 3830 _backend.emitter.nativeEmitter.nativeMethods.add(function); | 3888 _backend.emitter.nativeEmitter.nativeMethods.add(function); |
| 3831 } | 3889 } |
| 3832 } | 3890 } |
| OLD | NEW |