Chromium Code Reviews| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
| index f375244f3497cb446fab74d606a49fe8e9903144..1804042dfdb11c7edaf7ee93b7638a0d6bedda43 100644 |
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
| @@ -2035,6 +2035,21 @@ class DartIrBuilderVisitor extends IrBuilderVisitor { |
| } |
| } |
| +/// The [IrBuilder]s view on the information about the program that has been |
| +/// computed in resolution and and type interence. |
| +class GlobalProgramInformation { |
| + final Compiler _compiler; |
| + JavaScriptBackend get _backend => _compiler.backend; |
| + |
| + GlobalProgramInformation(this._compiler); |
| + |
| + /// Returns [true], if the analysis could not determine that the type |
| + /// arguments for the class [cls] are never used in the program. |
| + bool requiresRuntimeTypesFor(ClassElement cls) { |
| + return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls); |
| + } |
| +} |
| + |
| /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. |
| class JsIrBuilderVisitor extends IrBuilderVisitor { |
| /// Promote the type of [irBuilder] to [JsIrBuilder]. |
| @@ -2180,6 +2195,13 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
| return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp)); |
| } |
| + JsIrBuilder getBuilderFor(Element element) { |
| + return new JsIrBuilder( |
| + new GlobalProgramInformation(compiler), |
| + compiler.backend.constantSystem, |
| + element); |
| + } |
| + |
| /// Builds the IR for a given constructor. |
| /// |
| /// 1. Evaluates all own or inherited field initializers. |
| @@ -2190,20 +2212,53 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
| constructor = constructor.implementation; |
| ClassElement classElement = constructor.enclosingClass.implementation; |
| - JsIrBuilder builder = |
| - new JsIrBuilder(compiler.backend.constantSystem, constructor); |
| + JsIrBuilder builder = getBuilderFor(constructor); |
| + |
| + final bool requiresTypeInformation = |
| + builder.program.requiresRuntimeTypesFor(classElement); |
| return withBuilder(builder, () { |
| // Setup parameters and create a box if anything is captured. |
| - List<ParameterElement> parameters = []; |
| - constructor.functionSignature.orderedForEachParameter(parameters.add); |
| - builder.buildFunctionHeader(parameters, |
| + List<Local> parameters = <Local>[]; |
| + constructor.functionSignature.orderedForEachParameter( |
| + // Note: the closure is explicit to allow typechecking [FormalElement] |
| + // against [Local]. |
|
asgerf
2015/03/24 12:37:21
That's unfortunate, but I think the comment actual
karlklose
2015/03/26 09:50:07
Done. But we need to address the mixup of [Element
asgerf
2015/03/26 09:58:41
Completely agree.
|
| + (ParameterElement p) => parameters.add(p)); |
| + |
| + int firstTypeArgumentParameterIndex; |
| + |
| + // If instances of the class may need runtime type information, we add a |
| + // synthetic parameter for each type parameter. |
| + if (requiresTypeInformation) { |
| + firstTypeArgumentParameterIndex = parameters.length; |
| + classElement.typeVariables.forEach((TypeVariableType variable) { |
| + parameters.add( |
| + new TypeInformationParameter(variable.element, constructor)); |
| + }); |
| + } |
| + |
| + // Create IR parameters and setup the environment. |
| + List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters, |
| closureScope: getClosureScopeForFunction(constructor)); |
| + // Create a list of the values of all type argument parameters, if any. |
| + List<ir.Primitive> typeInformation; |
| + if (requiresTypeInformation) { |
| + List<ir.Primitive> typeArgumentParameters = <ir.Primitive>[]; |
| + for (int index = firstTypeArgumentParameterIndex; |
| + index < irParameters.length; |
| + ++index) { |
| + typeArgumentParameters.add(irParameters[index]); |
| + } |
| + typeInformation = typeArgumentParameters; |
|
asgerf
2015/03/24 12:37:21
How about:
typeInformation = irParameters.sublist
karlklose
2015/03/26 09:50:07
Done.
|
| + } |
| + |
| // -- Step 1: evaluate field initializers --- |
| // Evaluate field initializers in constructor and super constructors. |
| + irBuilder.enterInitializers(); |
| List<ConstructorElement> constructorList = <ConstructorElement>[]; |
| evaluateConstructorFieldInitializers(constructor, constructorList); |
| + irBuilder.leaveInitializers(); |
| // All parameters in all constructors are now bound in the environment. |
| // BoxLocals for captured parameters are also in the environment. |
| @@ -2221,8 +2276,10 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
| // Native fields are initialized elsewhere. |
| } |
| }, includeSuperAndInjectedMembers: true); |
| - ir.Primitive instance = |
| - new ir.CreateInstance(classElement, instanceArguments); |
| + ir.Primitive instance = new ir.CreateInstance( |
| + classElement, |
| + instanceArguments, |
| + typeInformation); |
| irBuilder.add(new ir.LetPrim(instance)); |
| // --- Step 3: call constructor bodies --- |
| @@ -2456,8 +2513,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
| node, |
| elements); |
| - JsIrBuilder builder = |
| - new JsIrBuilder(compiler.backend.constantSystem, body); |
| + JsIrBuilder builder = getBuilderFor(body); |
| return withBuilder(builder, () { |
| irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), |
| @@ -2479,8 +2535,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
| element, |
| node, |
| elements); |
| - IrBuilder builder = |
| - new JsIrBuilder(compiler.backend.constantSystem, element); |
| + IrBuilder builder = getBuilderFor(element); |
| return withBuilder(builder, () => _makeFunctionBody(element, node)); |
| } |
| @@ -2562,8 +2617,9 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
| @override |
| ir.Primitive buildReifyTypeVariable(ir.Primitive target, |
| TypeVariableType variable) { |
| - ir.Primitive typeArgument = new ir.ReadTypeVariable(variable, target); |
| - irBuilder.add(new ir.LetPrim(typeArgument)); |
| + ir.Primitive typeArgument = |
| + irBuilder.buildTypeVariableAccess(target, variable); |
| + |
| ir.Primitive type = new ir.ReifyRuntimeType(typeArgument); |
| irBuilder.add(new ir.LetPrim(type)); |
| return type; |