| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| index 87203a2b1e5b13c412e29782d33cdc19f7a66513..27a7f394c0a3db06166eee87b8ada57f4877b2d1 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| @@ -13,7 +13,8 @@ import '../io/source_information.dart';
|
| import '../tree/tree.dart' as ast;
|
| import '../closure.dart' hide ClosureScope;
|
| import 'cps_ir_nodes.dart' as ir;
|
| -import 'cps_ir_builder_task.dart' show DartCapturedVariables;
|
| +import 'cps_ir_builder_task.dart' show DartCapturedVariables,
|
| + GlobalProgramInformation;
|
|
|
| /// A mapping from variable elements to their compile-time values.
|
| ///
|
| @@ -295,7 +296,7 @@ abstract class IrBuilder {
|
|
|
| /// Add the given function parameter to the IR, and bind it in the environment
|
| /// or put it in its box, if necessary.
|
| - void _createFunctionParameter(ParameterElement parameterElement);
|
| + void _createFunctionParameter(Local parameterElement);
|
|
|
| /// Creates an access to the receiver from the current (or enclosing) method.
|
| ///
|
| @@ -399,7 +400,7 @@ abstract class IrBuilder {
|
| _enterScope(closureScope);
|
| }
|
|
|
| - List<ir.Primitive> buildFunctionHeader(Iterable<ParameterElement> parameters,
|
| + List<ir.Primitive> buildFunctionHeader(Iterable<Local> parameters,
|
| {ClosureScope closureScope,
|
| ClosureEnvironment env}) {
|
| _enterClosureEnvironment(env);
|
| @@ -787,12 +788,8 @@ abstract class IrBuilder {
|
| /// argument values are defined by [arguments].
|
| ir.Primitive buildConstructorInvocation(FunctionElement element,
|
| Selector selector,
|
| - DartType type,
|
| - List<ir.Primitive> arguments) {
|
| - assert(isOpen);
|
| - return _continueWithExpression(
|
| - (k) => new ir.InvokeConstructor(type, element, selector, k, arguments));
|
| - }
|
| + InterfaceType type,
|
| + List<ir.Primitive> arguments);
|
|
|
| /// Create a string concatenation of the [arguments].
|
| ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments) {
|
| @@ -2026,7 +2023,7 @@ class DartIrBuilder extends IrBuilder {
|
| }
|
| }
|
|
|
| - void _createFunctionParameter(ParameterElement parameterElement) {
|
| + void _createFunctionParameter(Local parameterElement) {
|
| ir.Parameter parameter = new ir.Parameter(parameterElement);
|
| _parameters.add(parameter);
|
| if (isInMutableVariable(parameterElement)) {
|
| @@ -2113,6 +2110,16 @@ class DartIrBuilder extends IrBuilder {
|
| return _buildInvokeSuper(target, selector, arguments);
|
| }
|
|
|
| + @override
|
| + ir.Primitive buildConstructorInvocation(FunctionElement element,
|
| + Selector selector,
|
| + InterfaceType type,
|
| + List<ir.Primitive> arguments) {
|
| + assert(isOpen);
|
| + return _continueWithExpression(
|
| + (k) => new ir.InvokeConstructor(type, element, selector, k,
|
| + arguments));
|
| + }
|
| }
|
|
|
| /// State shared between JsIrBuilders within the same function.
|
| @@ -2125,6 +2132,10 @@ class JsIrBuilderSharedState {
|
|
|
| /// If non-null, this refers to the receiver (`this`) in the enclosing method.
|
| ir.Primitive receiver;
|
| +
|
| + /// `true` when we are currently building expressions inside the initializer
|
| + /// list of a constructor.
|
| + bool inInitializers = false;
|
| }
|
|
|
| /// JS-specific subclass of [IrBuilder].
|
| @@ -2133,11 +2144,13 @@ class JsIrBuilderSharedState {
|
| /// variables are boxed as necessary using [CreateBox], [GetField], [SetField].
|
| class JsIrBuilder extends IrBuilder {
|
| final JsIrBuilderSharedState jsState;
|
| + final GlobalProgramInformation program;
|
|
|
| - IrBuilder _makeInstance() => new JsIrBuilder._blank(jsState);
|
| - JsIrBuilder._blank(this.jsState);
|
| + IrBuilder _makeInstance() => new JsIrBuilder._blank(program, jsState);
|
| + JsIrBuilder._blank(this.program, this.jsState);
|
|
|
| - JsIrBuilder(ConstantSystem constantSystem, ExecutableElement currentElement)
|
| + JsIrBuilder(this.program, ConstantSystem constantSystem,
|
| + ExecutableElement currentElement)
|
| : jsState = new JsIrBuilderSharedState() {
|
| _init(constantSystem, currentElement);
|
| }
|
| @@ -2148,6 +2161,16 @@ class JsIrBuilder extends IrBuilder {
|
| void makeMutableVariable(Local local) {}
|
| void removeMutableVariable(Local local) {}
|
|
|
| + void enterInitializers() {
|
| + assert(jsState.inInitializers == false);
|
| + jsState.inInitializers = true;
|
| + }
|
| +
|
| + void leaveInitializers() {
|
| + assert(jsState.inInitializers == true);
|
| + jsState.inInitializers = false;
|
| + }
|
| +
|
| void _enterClosureEnvironment(ClosureEnvironment env) {
|
| if (env == null) return;
|
|
|
| @@ -2202,7 +2225,7 @@ class JsIrBuilder extends IrBuilder {
|
| });
|
| }
|
|
|
| - void _createFunctionParameter(ParameterElement parameterElement) {
|
| + void _createFunctionParameter(Local parameterElement) {
|
| ir.Parameter parameter = new ir.Parameter(parameterElement);
|
| _parameters.add(parameter);
|
| state.functionParameters.add(parameter);
|
| @@ -2378,6 +2401,71 @@ class JsIrBuilder extends IrBuilder {
|
| jsState.boxedVariables.addAll(closureScope.capturedVariables);
|
| }
|
| }
|
| +
|
| + @override
|
| + ir.Primitive buildConstructorInvocation(FunctionElement element,
|
| + Selector selector,
|
| + InterfaceType type,
|
| + List<ir.Primitive> arguments) {
|
| + assert(isOpen);
|
| + // TODO(karlklose): resolve effective target and type here or inline later?
|
| + ClassElement cls = element.enclosingClass;
|
| + Iterable<ir.Primitive> typeArguments = const <ir.Primitive>[];
|
| + if (program.requiresRuntimeTypesFor(cls)) {
|
| + ir.Primitive argumentArray;
|
| + typeArguments = type.typeArguments.map((DartType argument) {
|
| + return type.treatAsRaw
|
| + ? buildNullLiteral()
|
| + : buildTypeExpression(argument);
|
| + });
|
| + arguments = new List<ir.Primitive>.from(arguments)
|
| + ..addAll(typeArguments);
|
| + }
|
| + return _continueWithExpression(
|
| + (k) => new ir.InvokeConstructor(type, element, selector, k,
|
| + arguments));
|
| + }
|
| +
|
| + ir.Primitive buildTypeExpression(DartType type) {
|
| + if (type is TypeVariableType) {
|
| + return buildTypeVariableAccess(buildThis(), type);
|
| + } else {
|
| + assert(type is InterfaceType);
|
| + // TODO(karlklose): optimization: share the type expression for variables.
|
| + List<ir.Primitive> arguments = <ir.Primitive>[];
|
| + type.forEachTypeVariable((TypeVariableType variable) {
|
| + ir.Primitive value = buildTypeExpression(variable);
|
| + arguments.add(value);
|
| + });
|
| + // TODO(karlklose): use addPrimitive.
|
| + ir.Primitive expression = new ir.TypeExpression(type, arguments);
|
| + add(new ir.LetPrim(expression));
|
| + return expression;
|
| + }
|
| + }
|
| +
|
| + ir.Primitive buildTypeVariableAccess(ir.Primitive target,
|
| + TypeVariableType variable) {
|
| + ir.Parameter accessTypeArgumentParameter() {
|
| + for (int i = 0; i < environment.length; i++) {
|
| + Local local = environment.index2variable[i];
|
| + if (local is TypeInformationParameter &&
|
| + local.variable == variable.element) {
|
| + return environment.index2value[i];
|
| + }
|
| + }
|
| + throw 'unable to find constructor parameter for type variable $variable.';
|
| + }
|
| +
|
| + // TODO(karlklose): use addPrimitive.
|
| + if (jsState.inInitializers) {
|
| + return accessTypeArgumentParameter();
|
| + } else {
|
| + ir.Primitive result = new ir.ReadTypeVariable(variable, target);
|
| + add(new ir.LetPrim(result));
|
| + return result;
|
| + }
|
| + }
|
| }
|
|
|
|
|
| @@ -2449,3 +2537,12 @@ class CatchClauseInfo {
|
| this.stackTraceVariable,
|
| this.buildCatchBlock});
|
| }
|
| +
|
| +/// The synthetic parameter to a factory that takes the runtime type information
|
| +/// to be set on the new instance.
|
| +class TypeInformationParameter implements Local {
|
| + final TypeVariableElement variable;
|
| + final ExecutableElement executableContext;
|
| + TypeInformationParameter(this.variable, this.executableContext);
|
| + String get name => variable.name;
|
| +}
|
|
|