| 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 d1605c8c713cb6b0e450f0908830a22560740bbc..cf03763815652293332dcf252539c043add77278 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
|
| @@ -306,9 +306,6 @@ class IrBuilder {
|
|
|
| /// Add [variableElement] to the environment with [initialValue] as its
|
| /// initial value.
|
| - ///
|
| - /// [isClosureVariable] marks whether [variableElement] is accessed from an
|
| - /// inner function.
|
| void declareLocalVariable(LocalVariableElement variableElement,
|
| {ir.Primitive initialValue}) {
|
| assert(isOpen);
|
| @@ -329,6 +326,20 @@ class IrBuilder {
|
| }
|
| }
|
|
|
| + /// Add [functionElement] to the environment with provided [definition].
|
| + void declareLocalFunction(LocalFunctionElement functionElement,
|
| + ir.FunctionDefinition definition) {
|
| + assert(isOpen);
|
| + if (isClosureVariable(functionElement)) {
|
| + add(new ir.DeclareFunction(functionElement, definition));
|
| + } else {
|
| + ir.CreateFunction prim = new ir.CreateFunction(definition);
|
| + add(new ir.LetPrim(prim));
|
| + environment.extend(functionElement, prim);
|
| + prim.useElementAsHint(functionElement);
|
| + }
|
| + }
|
| +
|
| // Plug an expression into the 'hole' in the context being accumulated. The
|
| // empty context (just a hole) is represented by root (and current) being
|
| // null. Since the hole in the current context is filled by this function,
|
| @@ -374,6 +385,15 @@ class IrBuilder {
|
| (k) => new ir.InvokeMethod(receiver, selector, k, arguments));
|
| }
|
|
|
| + ir.Primitive _buildInvokeCall(ir.Primitive target,
|
| + Selector selector,
|
| + List<ir.Definition> arguments) {
|
| + Selector callSelector = new Selector.callClosure(
|
| + selector.argumentCount,
|
| + selector.namedArguments);
|
| + return _buildInvokeDynamic(target, callSelector, arguments);
|
| + }
|
| +
|
|
|
| /// Create a constant literal from [constant].
|
| ir.Constant buildConstantLiteral(ConstantExpression constant) {
|
| @@ -494,6 +514,13 @@ class IrBuilder {
|
|
|
| }
|
|
|
| + /// Create a function expression from [definition].
|
| + ir.Primitive buildFunctionExpression(ir.FunctionDefinition definition) {
|
| + ir.CreateFunction prim = new ir.CreateFunction(definition);
|
| + add(new ir.LetPrim(prim));
|
| + return prim;
|
| + }
|
| +
|
| /**
|
| * Add an explicit `return null` for functions that don't have a return
|
| * statement on each branch. This includes functions with an empty body,
|
| @@ -529,7 +556,6 @@ class IrBuilder {
|
| }
|
| }
|
|
|
| -
|
| /// Create a super invocation where the method name and the argument structure
|
| /// are defined by [selector] and the argument values are defined by
|
| /// [arguments].
|
| @@ -665,6 +691,31 @@ class IrBuilder {
|
| return value;
|
| }
|
|
|
| + /// Create an invocation of [local] where the argument structure is defined
|
| + /// by [selector] and the argument values are defined by [arguments].
|
| + ir.Primitive buildLocalInvocation(LocalElement local,
|
| + Selector selector,
|
| + List<ir.Definition> arguments) {
|
| + ir.Primitive receiver;
|
| + if (isClosureVariable(local)) {
|
| + receiver = new ir.GetClosureVariable(local);
|
| + add(new ir.LetPrim(receiver));
|
| + } else {
|
| + receiver = environment.lookup(local);
|
| + }
|
| + return _buildInvokeCall(receiver, selector, arguments);
|
| + }
|
| +
|
| + /// Create an invocation of the [functionExpression] where the argument
|
| + /// structure are defined by [selector] and the argument values are defined by
|
| + /// [arguments].
|
| + ir.Primitive buildFunctionExpressionInvocation(
|
| + ir.Primitive functionExpression,
|
| + Selector selector,
|
| + List<ir.Definition> arguments) {
|
| + return _buildInvokeCall(functionExpression, selector, arguments);
|
| + }
|
| +
|
| /// Creates an if-then-else statement with the provided [condition] where the
|
| /// then and else branches are created through the [buildThenPart] and
|
| /// [buildElsePart] functions, respectively.
|
|
|