| Index: pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| index 29ab33d22191e4d6550773f86d021a8dff55c220..ce8d5b1aaf8772930095e5fa6585003a4b0e3497 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
|
| @@ -1160,7 +1160,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| /// Returns `true` if the node was replaced.
|
| specializeOperatorCall(InvokeMethod node) {
|
| if (!backend.isInterceptedSelector(node.selector)) return null;
|
| - if (node.dartArgumentsLength > 1) return null;
|
| + if (node.argumentRefs.length > 1) return null;
|
| if (node.callingConvention == CallingConvention.OneShotIntercepted) {
|
| return null;
|
| }
|
| @@ -1178,11 +1178,11 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
|
|
| // Determine which guards are needed.
|
| ChecksNeeded receiverChecks =
|
| - receiverGuard.getChecksNeeded(node.dartReceiver, classWorld);
|
| + receiverGuard.getChecksNeeded(node.receiver, classWorld);
|
| bool needReceiverGuard = receiverChecks != ChecksNeeded.None;
|
| bool needArgumentGuard =
|
| argumentGuard != null &&
|
| - argumentGuard.needsCheck(node.dartArgument(0), classWorld);
|
| + argumentGuard.needsCheck(node.argument(0), classWorld);
|
|
|
| if (!needReceiverGuard && !needArgumentGuard) return cps;
|
|
|
| @@ -1193,9 +1193,9 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| // if (typeof receiver !== "number") return receiver.$lt();
|
| //
|
| if (!needArgumentGuard) {
|
| - Primitive condition = receiverGuard.makeCheck(cps, node.dartReceiver);
|
| + Primitive condition = receiverGuard.makeCheck(cps, node.receiver);
|
| cps.letPrim(new ReceiverCheck(
|
| - node.dartReceiver,
|
| + node.receiver,
|
| node.selector,
|
| node.sourceInformation,
|
| condition: condition,
|
| @@ -1214,9 +1214,9 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| // if (typeof argument !== "number") return H.iae(argument);
|
| //
|
| if (!needReceiverGuard) {
|
| - cps.ifTruthy(argumentGuard.makeCheck(cps, node.dartArgument(0)))
|
| + cps.ifTruthy(argumentGuard.makeCheck(cps, node.argument(0)))
|
| .invokeStaticThrower(helpers.throwIllegalArgumentException,
|
| - [node.dartArgument(0)]);
|
| + [node.argument(0)]);
|
| return cps;
|
| }
|
|
|
| @@ -1228,14 +1228,15 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| // return J.$lt(receiver, argument);
|
| //
|
| Continuation fail = cps.letCont();
|
| - cps.ifTruthy(receiverGuard.makeCheck(cps, node.dartReceiver))
|
| + cps.ifTruthy(receiverGuard.makeCheck(cps, node.receiver))
|
| .invokeContinuation(fail);
|
| - cps.ifTruthy(argumentGuard.makeCheck(cps, node.dartArgument(0)))
|
| + cps.ifTruthy(argumentGuard.makeCheck(cps, node.argument(0)))
|
| .invokeContinuation(fail);
|
|
|
| cps.insideContinuation(fail)
|
| - ..invokeMethod(node.dartReceiver, node.selector, node.mask,
|
| - [node.dartArgument(0)], CallingConvention.OneShotIntercepted)
|
| + ..invokeMethod(node.receiver, node.selector, node.mask,
|
| + [node.argument(0)],
|
| + callingConvention: CallingConvention.OneShotIntercepted)
|
| ..put(new Unreachable());
|
|
|
| return cps;
|
| @@ -1249,9 +1250,9 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| CpsFragment makeBinary(BuiltinOperator operator,
|
| {TypeCheckOperator guard: TypeCheckOperator.none}) {
|
| CpsFragment cps = makeGuard(guard, guard);
|
| - Primitive left = guard.makeRefinement(cps, node.dartReceiver, classWorld);
|
| + Primitive left = guard.makeRefinement(cps, node.receiver, classWorld);
|
| Primitive right =
|
| - guard.makeRefinement(cps, node.dartArgument(0), classWorld);
|
| + guard.makeRefinement(cps, node.argument(0), classWorld);
|
| Primitive result = cps.applyBuiltin(operator, [left, right]);
|
| result.hint = node.hint;
|
| node.replaceUsesWith(result);
|
| @@ -1264,7 +1265,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| {TypeCheckOperator guard: TypeCheckOperator.none}) {
|
| CpsFragment cps = makeGuard(guard);
|
| Primitive argument =
|
| - guard.makeRefinement(cps, node.dartReceiver, classWorld);
|
| + guard.makeRefinement(cps, node.receiver, classWorld);
|
| Primitive result = cps.applyBuiltin(operator, [argument]);
|
| result.hint = node.hint;
|
| node.replaceUsesWith(result);
|
| @@ -1284,15 +1285,16 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| node.mask,
|
| node.arguments.toList(),
|
| sourceInformation: node.sourceInformation,
|
| - callingConvention: node.callingConvention);
|
| + callingConvention: node.callingConvention,
|
| + interceptor: node.interceptor);
|
| }
|
|
|
| TypeMask successType =
|
| - typeSystem.receiverTypeFor(node.selector, node.dartReceiver.type);
|
| + typeSystem.receiverTypeFor(node.selector, node.receiver.type);
|
|
|
| - if (node.selector.isOperator && node.dartArgumentsLength == 1) {
|
| - Primitive leftArg = node.dartReceiver;
|
| - Primitive rightArg = node.dartArgument(0);
|
| + if (node.selector.isOperator && node.argumentRefs.length == 1) {
|
| + Primitive leftArg = node.receiver;
|
| + Primitive rightArg = node.argument(0);
|
| AbstractConstantValue left = getValue(leftArg);
|
| AbstractConstantValue right = getValue(rightArg);
|
|
|
| @@ -1383,7 +1385,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| }
|
| }
|
| }
|
| - if (node.selector.isOperator && node.dartArgumentsLength == 0) {
|
| + if (node.selector.isOperator && node.argumentRefs.length == 0) {
|
| if (typeSystem.isDefinitelyNum(successType)) {
|
| String opname = node.selector.name;
|
| if (opname == '~') {
|
| @@ -1396,11 +1398,11 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| }
|
| if (node.selector.isCall) {
|
| String name = node.selector.name;
|
| - Primitive receiver = node.dartReceiver;
|
| + Primitive receiver = node.receiver;
|
| AbstractConstantValue receiverValue = getValue(receiver);
|
| if (name == 'remainder') {
|
| - if (node.dartArgumentsLength == 1) {
|
| - Primitive arg = node.dartArgument(0);
|
| + if (node.argumentRefs.length == 1) {
|
| + Primitive arg = node.argument(0);
|
| AbstractConstantValue argValue = getValue(arg);
|
| if (lattice.isDefinitelyInt(receiverValue, allowNull: true) &&
|
| lattice.isDefinitelyInt(argValue) &&
|
| @@ -1410,8 +1412,8 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| }
|
| }
|
| } else if (name == 'codeUnitAt') {
|
| - if (node.dartArgumentsLength == 1) {
|
| - Primitive index = node.dartArgument(0);
|
| + if (node.argumentRefs.length == 1) {
|
| + Primitive index = node.argument(0);
|
| if (lattice.isDefinitelyString(receiverValue) &&
|
| lattice.isDefinitelyInt(getValue(index))) {
|
| CpsFragment cps = new CpsFragment(node.sourceInformation);
|
| @@ -1445,7 +1447,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| /// Returns `true` if the node was replaced.
|
| Primitive specializeFieldAccess(InvokeMethod node) {
|
| if (!node.selector.isGetter && !node.selector.isSetter) return null;
|
| - AbstractConstantValue receiver = getValue(node.dartReceiver);
|
| + AbstractConstantValue receiver = getValue(node.receiver);
|
| Element target =
|
| typeSystem.locateSingleElement(receiver.type, node.selector);
|
| if (target is! FieldElement) return null;
|
| @@ -1455,13 +1457,13 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| return null;
|
| }
|
| if (node.selector.isGetter) {
|
| - return new GetField(node.dartReceiver, target);
|
| + return new GetField(node.receiver, target);
|
| } else {
|
| if (target.isFinal) return null;
|
| assert(node.hasNoUses);
|
| - return new SetField(node.dartReceiver,
|
| + return new SetField(node.receiver,
|
| target,
|
| - node.dartArgument(0));
|
| + node.argument(0));
|
| }
|
| }
|
|
|
| @@ -1515,7 +1517,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| ///
|
| /// Returns `true` if the node was replaced.
|
| specializeIndexableAccess(InvokeMethod node) {
|
| - Primitive receiver = node.dartReceiver;
|
| + Primitive receiver = node.receiver;
|
| AbstractConstantValue receiverValue = getValue(receiver);
|
| if (!typeSystem.isDefinitelyIndexable(receiverValue.type,
|
| allowNull: true)) {
|
| @@ -1532,7 +1534,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| return null;
|
| }
|
| CpsFragment cps = new CpsFragment(node.sourceInformation);
|
| - Primitive newLength = node.dartArgument(0);
|
| + Primitive newLength = node.argument(0);
|
| if (!typeSystem.isDefinitelyUint(newLength.type)) {
|
| // TODO(asgerf): We could let the SetLength instruction throw for
|
| // negative right-hand sides (see length setter in js_array.dart).
|
| @@ -1557,7 +1559,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| return null;
|
|
|
| case '[]':
|
| - Primitive index = node.dartArgument(0);
|
| + Primitive index = node.argument(0);
|
| CpsFragment cps = new CpsFragment(node.sourceInformation);
|
| receiver = makeBoundsCheck(cps, receiver, index);
|
| GetIndex get = cps.letPrim(new GetIndex(receiver, index));
|
| @@ -1571,8 +1573,8 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| allowNull: true)) {
|
| return null;
|
| }
|
| - Primitive index = node.dartArgument(0);
|
| - Primitive value = node.dartArgument(1);
|
| + Primitive index = node.argument(0);
|
| + Primitive value = node.argument(1);
|
| CpsFragment cps = new CpsFragment(node.sourceInformation);
|
| receiver = makeBoundsCheck(cps, receiver, index);
|
| cps.letPrim(new SetIndex(receiver, index, value));
|
| @@ -1610,7 +1612,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| ///
|
| /// Returns `true` if the node was replaced.
|
| CpsFragment specializeArrayAccess(InvokeMethod node) {
|
| - Primitive list = node.dartReceiver;
|
| + Primitive list = node.receiver;
|
| AbstractConstantValue listValue = getValue(list);
|
| // Ensure that the object is a native list or null.
|
| if (!lattice.isDefinitelyArray(listValue, allowNull: true)) {
|
| @@ -1629,7 +1631,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| return null;
|
| }
|
| if (!isExtendable) return null;
|
| - Primitive addedItem = node.dartArgument(0);
|
| + Primitive addedItem = node.argument(0);
|
| CpsFragment cps = new CpsFragment(sourceInfo);
|
| cps.invokeBuiltin(BuiltinMethod.Push,
|
| list,
|
| @@ -1661,7 +1663,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| return null;
|
| }
|
| if (!isExtendable) return null;
|
| - Primitive addedList = node.dartArgument(0);
|
| + Primitive addedList = node.argument(0);
|
| // Rewrite addAll([x1, ..., xN]) to push(x1), ..., push(xN).
|
| // Ensure that the list is not mutated between creation and use.
|
| // We aim for the common case where this is the only use of the list,
|
| @@ -1688,7 +1690,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| return null;
|
| }
|
| if (listValue.isNullable) return null;
|
| - Primitive index = node.dartArgument(0);
|
| + Primitive index = node.argument(0);
|
| if (!lattice.isDefinitelyInt(getValue(index))) return null;
|
| CpsFragment cps = new CpsFragment(node.sourceInformation);
|
| list = makeBoundsCheck(cps, list, index);
|
| @@ -1711,6 +1713,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| Primitive result = cps.inlineFunction(target,
|
| node.receiver,
|
| node.arguments.toList(),
|
| + interceptor: node.interceptor,
|
| hint: node.hint);
|
| node.replaceUsesWith(result);
|
| return cps;
|
| @@ -1898,7 +1901,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| assert(!isInterceptedSelector(call));
|
| assert(call.argumentCount == node.argumentRefs.length);
|
|
|
| - Primitive tearOff = node.dartReceiver.effectiveDefinition;
|
| + Primitive tearOff = node.receiver.effectiveDefinition;
|
| // Note: We don't know if [tearOff] is actually a tear-off.
|
| // We name variables based on the pattern we are trying to match.
|
|
|
| @@ -2028,7 +2031,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| // Accesses to closed-over values are field access primitives. We we don't
|
| // inline if there are other uses of 'this' since that could be an escape or
|
| // a recursive call.
|
| - for (Reference ref = target.thisParameter.firstRef;
|
| + for (Reference ref = target.receiverParameter.firstRef;
|
| ref != null;
|
| ref = ref.next) {
|
| Node use = ref.parent;
|
| @@ -2074,13 +2077,13 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| }
|
| node.effects =
|
| Effects.from(compiler.world.getSideEffectsOfElement(target));
|
| - TypeMask receiverType = node.dartReceiver.type;
|
| + TypeMask receiverType = node.receiver.type;
|
| if (node.callingConvention == CallingConvention.Intercepted &&
|
| typeSystem.areDisjoint(receiverType, typeSystem.interceptorType)) {
|
| // Some direct calls take an interceptor because the target class is
|
| // mixed into a native class. If it is known at the call site that the
|
| // receiver is non-intercepted, get rid of the interceptor.
|
| - node.receiverRef.changeTo(node.dartReceiver);
|
| + node.interceptorRef.changeTo(node.receiver);
|
| }
|
| }
|
|
|
| @@ -2094,7 +2097,7 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| specializeClosureCall(node);
|
| if (specialized != null) return specialized;
|
|
|
| - TypeMask receiverType = node.dartReceiver.type;
|
| + TypeMask receiverType = node.receiver.type;
|
| node.mask = typeSystem.intersection(node.mask, receiverType);
|
|
|
| node.effects = Effects.from(
|
| @@ -2109,16 +2112,13 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| typeSystem.areDisjoint(receiverType, typeSystem.interceptorType)) {
|
| // Use the Dart receiver as the JS receiver. This changes the wording of
|
| // the error message when the receiver is null, but we accept this.
|
| - node.receiverRef.changeTo(node.dartReceiver);
|
| + node.interceptorRef.changeTo(node.receiver);
|
|
|
| // Replace the extra receiver argument with a dummy value if the
|
| // target definitely does not use it.
|
| if (typeSystem.targetIgnoresReceiverArgument(receiverType,
|
| node.selector)) {
|
| - Constant dummy = makeConstantPrimitive(new IntConstantValue(0));
|
| - new LetPrim(dummy).insertAbove(node.parent);
|
| - node.argumentRefs[0].changeTo(dummy);
|
| - node.callingConvention = CallingConvention.DummyIntercepted;
|
| + node.makeDummyIntercepted();
|
| }
|
| }
|
| }
|
| @@ -2155,11 +2155,12 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
| Selectors.toString_, value.type);
|
| if (typeSystem.isDefinitelyString(toStringReturn)) {
|
| CpsFragment cps = new CpsFragment(node.sourceInformation);
|
| - Primitive invoke = cps.invokeMethod(argument,
|
| + Primitive invoke = cps.invokeMethod(
|
| + argument,
|
| Selectors.toString_,
|
| value.type,
|
| - [cps.makeZero()],
|
| - CallingConvention.DummyIntercepted);
|
| + [],
|
| + callingConvention: CallingConvention.DummyIntercepted);
|
| node.replaceUsesWith(invoke);
|
| return cps;
|
| }
|
| @@ -2680,30 +2681,19 @@ class TypePropagationVisitor implements Visitor {
|
| void visit(Node node) { node.accept(this); }
|
|
|
| void visitFunctionDefinition(FunctionDefinition node) {
|
| - bool isIntercepted = backend.isInterceptedMethod(node.element);
|
| -
|
| + if (node.interceptorParameter != null) {
|
| + setValue(node.interceptorParameter, nonConstant(typeSystem.nonNullType));
|
| + }
|
| // If the abstract value of the function parameters is Nothing, use the
|
| // inferred parameter type. Otherwise (e.g., when inlining) do not
|
| // change the abstract value.
|
| - if (node.thisParameter != null && getValue(node.thisParameter).isNothing) {
|
| - if (isIntercepted &&
|
| - !typeSystem.methodIgnoresReceiverArgument(node.element)) {
|
| - setValue(node.thisParameter, nonConstant(typeSystem.nonNullType));
|
| - } else {
|
| - setValue(node.thisParameter,
|
| - nonConstant(typeSystem.getReceiverType(node.element)));
|
| - }
|
| - }
|
| - if (isIntercepted && getValue(node.parameters[0]).isNothing) {
|
| - if (typeSystem.methodIgnoresReceiverArgument(node.element)) {
|
| - setValue(node.parameters[0], nonConstant());
|
| - } else {
|
| - setValue(node.parameters[0],
|
| - nonConstant(typeSystem.getReceiverType(node.element)));
|
| - }
|
| + if (node.receiverParameter != null &&
|
| + getValue(node.receiverParameter).isNothing) {
|
| + setValue(node.receiverParameter,
|
| + nonConstant(typeSystem.getReceiverType(node.element)));
|
| }
|
| bool hasParameterWithoutValue = false;
|
| - for (Parameter param in node.parameters.skip(isIntercepted ? 1 : 0)) {
|
| + for (Parameter param in node.parameters) {
|
| if (getValue(param).isNothing) {
|
| TypeMask type = param.hint is ParameterElement
|
| ? typeSystem.getParameterType(param.hint)
|
| @@ -2773,7 +2763,7 @@ class TypePropagationVisitor implements Visitor {
|
| }
|
|
|
| void visitInvokeMethod(InvokeMethod node) {
|
| - AbstractConstantValue receiver = getValue(node.dartReceiver);
|
| + AbstractConstantValue receiver = getValue(node.receiver);
|
| if (receiver.isNothing) {
|
| return setResult(node, lattice.nothing);
|
| }
|
| @@ -2799,7 +2789,7 @@ class TypePropagationVisitor implements Visitor {
|
|
|
| if (node.selector.isCall) {
|
| if (node.selector == Selectors.codeUnitAt) {
|
| - AbstractConstantValue right = getValue(node.dartArgument(0));
|
| + AbstractConstantValue right = getValue(node.argument(0));
|
| AbstractConstantValue result =
|
| lattice.codeUnitAtSpecial(receiver, right);
|
| return finish(result, canReplace: !receiver.isNullable);
|
| @@ -2808,7 +2798,7 @@ class TypePropagationVisitor implements Visitor {
|
| }
|
|
|
| if (node.selector == Selectors.index) {
|
| - AbstractConstantValue right = getValue(node.dartArgument(0));
|
| + AbstractConstantValue right = getValue(node.argument(0));
|
| AbstractConstantValue result = lattice.indexSpecial(receiver, right);
|
| return finish(result, canReplace: !receiver.isNullable);
|
| }
|
| @@ -2819,7 +2809,7 @@ class TypePropagationVisitor implements Visitor {
|
|
|
| // Calculate the resulting constant if possible.
|
| String opname = node.selector.name;
|
| - if (node.dartArgumentsLength == 0) {
|
| + if (node.argumentRefs.length == 0) {
|
| // Unary operator.
|
| if (opname == "unary-") {
|
| opname = "-";
|
| @@ -2827,9 +2817,9 @@ class TypePropagationVisitor implements Visitor {
|
| UnaryOperator operator = UnaryOperator.parse(opname);
|
| AbstractConstantValue result = lattice.unaryOp(operator, receiver);
|
| return finish(result, canReplace: !receiver.isNullable);
|
| - } else if (node.dartArgumentsLength == 1) {
|
| + } else if (node.argumentRefs.length == 1) {
|
| // Binary operator.
|
| - AbstractConstantValue right = getValue(node.dartArgument(0));
|
| + AbstractConstantValue right = getValue(node.argument(0));
|
| BinaryOperator operator = BinaryOperator.parse(opname);
|
| AbstractConstantValue result =
|
| lattice.binaryOp(operator, receiver, right);
|
|
|