| Index: pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
|
| diff --git a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
|
| index 3fa6f1826031657c093fafb7dfe41bb7cc12c210..4c841348047d1509863719f5613d663e6b6d2707 100644
|
| --- a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
|
| +++ b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
|
| @@ -8,7 +8,6 @@ import '../../elements/elements.dart';
|
| import '../../js_backend/codegen/glue.dart';
|
| import '../../universe/selector.dart' show Selector;
|
| import '../../cps_ir/cps_ir_builder.dart' show ThisParameterLocal;
|
| -import '../../cps_ir/cps_fragment.dart';
|
|
|
| class ExplicitReceiverParameterEntity implements Local {
|
| String get name => 'receiver';
|
| @@ -26,6 +25,7 @@ class InterceptorEntity extends Entity {
|
| String get name => interceptedVariable.name + '_';
|
| }
|
|
|
| +
|
| /// Rewrites the initial CPS IR to make Dart semantics explicit and inserts
|
| /// special nodes that respect JavaScript behavior.
|
| ///
|
| @@ -34,8 +34,9 @@ class InterceptorEntity extends Entity {
|
| /// - Add explicit receiver argument for methods that are called in interceptor
|
| /// calling convention.
|
| /// - Convert two-parameter exception handlers to one-parameter ones.
|
| -class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
|
| +class UnsugarVisitor extends RecursiveVisitor implements Pass {
|
| Glue _glue;
|
| + ParentVisitor _parentVisitor = new ParentVisitor();
|
|
|
| Parameter thisParameter;
|
| Parameter explicitReceiverParameter;
|
| @@ -71,11 +72,14 @@ class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
|
| if (inInterceptedMethod) {
|
| ThisParameterLocal holder = thisParameter.hint;
|
| explicitReceiverParameter = new Parameter(
|
| - new ExplicitReceiverParameterEntity(holder.executableContext));
|
| - explicitReceiverParameter.parent = function;
|
| + new ExplicitReceiverParameterEntity(
|
| + holder.executableContext));
|
| function.parameters.insert(0, explicitReceiverParameter);
|
| }
|
|
|
| + // Set all parent pointers.
|
| + _parentVisitor.visit(function);
|
| +
|
| if (inInterceptedMethod && methodUsesReceiverArgument(function.element)) {
|
| explicitReceiverParameter.substituteFor(thisParameter);
|
| }
|
| @@ -97,7 +101,11 @@ class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
|
|
|
| void insertLetPrim(Primitive primitive, Expression node) {
|
| LetPrim let = new LetPrim(primitive);
|
| - let.insertAbove(node);
|
| + InteriorNode parent = node.parent;
|
| + parent.body = let;
|
| + let.body = node;
|
| + node.parent = let;
|
| + let.parent = parent;
|
| }
|
|
|
| void insertEqNullCheck(FunctionDefinition function) {
|
| @@ -112,14 +120,28 @@ class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
|
| // else
|
| // body;
|
| //
|
| - CpsFragment cps = new CpsFragment();
|
| - Primitive isNull = cps.applyBuiltin(
|
| + Continuation originalBody = new Continuation(<Parameter>[]);
|
| + originalBody.body = function.body;
|
| +
|
| + Continuation returnFalse = new Continuation(<Parameter>[]);
|
| + Primitive falsePrimitive = falseConstant;
|
| + returnFalse.body =
|
| + new LetPrim(falsePrimitive,
|
| + new InvokeContinuation(
|
| + function.returnContinuation, <Primitive>[falsePrimitive]));
|
| +
|
| + Primitive nullPrimitive = nullConstant;
|
| + Primitive test = new ApplyBuiltinOperator(
|
| BuiltinOperator.Identical,
|
| - <Primitive>[function.parameters.single, cps.makeNull()]);
|
| - CpsFragment trueBranch = cps.ifTruthy(isNull);
|
| - trueBranch.invokeContinuation(function.returnContinuation,
|
| - <Primitive>[trueBranch.makeFalse()]);
|
| - cps.insertAbove(function.body);
|
| + <Primitive>[function.parameters.single, nullPrimitive],
|
| + function.parameters.single.sourceInformation);
|
| +
|
| + Expression newBody =
|
| + new LetCont.many(<Continuation>[returnFalse, originalBody],
|
| + new LetPrim(nullPrimitive,
|
| + new LetPrim(test,
|
| + new Branch.loose(test, returnFalse, originalBody))));
|
| + function.body = newBody;
|
| }
|
|
|
| /// Insert a static call to [function] at the point of [node] with result
|
| @@ -130,22 +152,25 @@ class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
|
| /// let cont continuation(result) = node
|
| /// in invoke function arguments continuation
|
| void insertStaticCall(FunctionElement function, List<Primitive> arguments,
|
| - Parameter result, Expression node) {
|
| + Parameter result,
|
| + Expression node) {
|
| InteriorNode parent = node.parent;
|
| Continuation continuation = new Continuation([result]);
|
| + continuation.body = node;
|
| + _parentVisitor.processContinuation(continuation);
|
|
|
| Selector selector = new Selector.fromElement(function);
|
| // TODO(johnniwinther): Come up with an implementation of SourceInformation
|
| // for calls such as this one that don't appear in the original source.
|
| InvokeStatic invoke = new InvokeStatic(
|
| function, selector, arguments, continuation, null);
|
| + _parentVisitor.processInvokeStatic(invoke);
|
|
|
| LetCont letCont = new LetCont(continuation, invoke);
|
| + _parentVisitor.processLetCont(letCont);
|
|
|
| parent.body = letCont;
|
| letCont.parent = parent;
|
| - continuation.body = node;
|
| - node.parent = continuation;
|
| }
|
|
|
| @override
|
| @@ -185,10 +210,11 @@ class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
|
|
|
| processThrow(Throw node) {
|
| // The subexpression of throw is wrapped in the JavaScript output.
|
| - Parameter wrappedException = new Parameter(null);
|
| + Parameter value = new Parameter(null);
|
| insertStaticCall(_glue.getWrapExceptionHelper(), [node.value.definition],
|
| - wrappedException, node);
|
| - node.value.changeTo(wrappedException);
|
| + value, node);
|
| + node.value.unlink();
|
| + node.value = new Reference<Primitive>(value);
|
| }
|
|
|
| processRethrow(Rethrow node) {
|
| @@ -236,7 +262,7 @@ class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
|
| insertLetPrim(newReceiver, contBinding);
|
| }
|
| node.arguments.insert(0, node.receiver);
|
| - node.receiver = new Reference<Primitive>(newReceiver)..parent = node;
|
| + node.receiver = new Reference<Primitive>(newReceiver);
|
| node.receiverIsIntercepted = true;
|
| }
|
|
|
| @@ -262,7 +288,7 @@ class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
|
| insertLetPrim(newReceiver, contBinding);
|
| }
|
| node.arguments.insert(0, node.receiver);
|
| - node.receiver = new Reference<Primitive>(newReceiver)..parent = node;
|
| + node.receiver = new Reference<Primitive>(newReceiver);
|
| }
|
|
|
| processInterceptor(Interceptor node) {
|
|
|