| Index: sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/compiler/implementation/ssa/nodes.dart (revision 21860)
|
| +++ sdk/lib/_internal/compiler/implementation/ssa/nodes.dart (working copy)
|
| @@ -903,6 +903,9 @@
|
| */
|
| HType instructionType = HType.UNKNOWN;
|
|
|
| + Selector get selector => null;
|
| + HInstruction getDartReceiver(Compiler compiler) => null;
|
| +
|
| bool isInBasicBlock() => block != null;
|
|
|
| String inputsToString() {
|
| @@ -1068,6 +1071,14 @@
|
| return users;
|
| }
|
|
|
| + void replaceAllUsersDominatedBy(HInstruction cursor,
|
| + HInstruction newInstruction) {
|
| + Set<HInstruction> users = dominatedUsers(cursor);
|
| + for (HInstruction user in users) {
|
| + user.changeUse(this, newInstruction);
|
| + }
|
| + }
|
| +
|
| void moveBefore(HInstruction other) {
|
| assert(this is !HControlFlow);
|
| assert(this is !HPhi);
|
| @@ -1135,7 +1146,7 @@
|
| }
|
| }
|
|
|
| - /**
|
| + /**
|
| * Return whether the instructions do not belong to a loop or
|
| * belong to the same loop.
|
| */
|
| @@ -1227,7 +1238,7 @@
|
|
|
| // A [HTypeGuard] cannot be moved anywhere in the graph, otherwise
|
| // instructions that have side effects could end up before the guard
|
| - // in the otpimized version, and after the guard in a bailout
|
| + // in the optimized version, and after the guard in a bailout
|
| // version.
|
| bool isPure() => false;
|
|
|
| @@ -1565,7 +1576,8 @@
|
| }
|
|
|
| abstract class HInvokeBinary extends HInstruction {
|
| - HInvokeBinary(HInstruction left, HInstruction right)
|
| + final Selector selector;
|
| + HInvokeBinary(HInstruction left, HInstruction right, this.selector)
|
| : super(<HInstruction>[left, right]) {
|
| clearAllSideEffects();
|
| setUseGvn();
|
| @@ -1578,12 +1590,12 @@
|
| }
|
|
|
| abstract class HBinaryArithmetic extends HInvokeBinary {
|
| - HBinaryArithmetic(HInstruction left, HInstruction right) : super(left, right);
|
| + HBinaryArithmetic(left, right, selector) : super(left, right, selector);
|
| BinaryOperation operation(ConstantSystem constantSystem);
|
| }
|
|
|
| class HAdd extends HBinaryArithmetic {
|
| - HAdd(HInstruction left, HInstruction right) : super(left, right);
|
| + HAdd(left, right, selector) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitAdd(this);
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem)
|
| @@ -1594,7 +1606,7 @@
|
| }
|
|
|
| class HDivide extends HBinaryArithmetic {
|
| - HDivide(HInstruction left, HInstruction right) : super(left, right) {
|
| + HDivide(left, right, selector) : super(left, right, selector) {
|
| instructionType = HType.DOUBLE;
|
| }
|
| accept(HVisitor visitor) => visitor.visitDivide(this);
|
| @@ -1607,7 +1619,7 @@
|
| }
|
|
|
| class HMultiply extends HBinaryArithmetic {
|
| - HMultiply(HInstruction left, HInstruction right) : super(left, right);
|
| + HMultiply(left, right, selector) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitMultiply(this);
|
|
|
| BinaryOperation operation(ConstantSystem operations)
|
| @@ -1618,7 +1630,7 @@
|
| }
|
|
|
| class HSubtract extends HBinaryArithmetic {
|
| - HSubtract(HInstruction left, HInstruction right) : super(left, right);
|
| + HSubtract(left, right, selector) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitSubtract(this);
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem)
|
| @@ -1652,13 +1664,13 @@
|
| }
|
|
|
| abstract class HBinaryBitOp extends HInvokeBinary {
|
| - HBinaryBitOp(HInstruction left, HInstruction right) : super(left, right) {
|
| + HBinaryBitOp(left, right, selector) : super(left, right, selector) {
|
| instructionType = HType.INTEGER;
|
| }
|
| }
|
|
|
| class HShiftLeft extends HBinaryBitOp {
|
| - HShiftLeft(HInstruction left, HInstruction right) : super(left, right);
|
| + HShiftLeft(left, right, selector) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitShiftLeft(this);
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem)
|
| @@ -1669,7 +1681,7 @@
|
| }
|
|
|
| class HBitOr extends HBinaryBitOp {
|
| - HBitOr(HInstruction left, HInstruction right) : super(left, right);
|
| + HBitOr(left, right, selector) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitBitOr(this);
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem)
|
| @@ -1680,7 +1692,7 @@
|
| }
|
|
|
| class HBitAnd extends HBinaryBitOp {
|
| - HBitAnd(HInstruction left, HInstruction right) : super(left, right);
|
| + HBitAnd(left, right, selector) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitBitAnd(this);
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem)
|
| @@ -1691,7 +1703,7 @@
|
| }
|
|
|
| class HBitXor extends HBinaryBitOp {
|
| - HBitXor(HInstruction left, HInstruction right) : super(left, right);
|
| + HBitXor(left, right, selector) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitBitXor(this);
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem)
|
| @@ -1702,7 +1714,9 @@
|
| }
|
|
|
| abstract class HInvokeUnary extends HInstruction {
|
| - HInvokeUnary(HInstruction input) : super(<HInstruction>[input]) {
|
| + final Selector selector;
|
| + HInvokeUnary(HInstruction input, this.selector)
|
| + : super(<HInstruction>[input]) {
|
| clearAllSideEffects();
|
| setUseGvn();
|
| }
|
| @@ -1713,7 +1727,7 @@
|
| }
|
|
|
| class HNegate extends HInvokeUnary {
|
| - HNegate(HInstruction input) : super(input);
|
| + HNegate(input, selector) : super(input, selector);
|
| accept(HVisitor visitor) => visitor.visitNegate(this);
|
|
|
| UnaryOperation operation(ConstantSystem constantSystem)
|
| @@ -1724,7 +1738,7 @@
|
| }
|
|
|
| class HBitNot extends HInvokeUnary {
|
| - HBitNot(HInstruction input) : super(input) {
|
| + HBitNot(input, selector) : super(input, selector) {
|
| instructionType = HType.INTEGER;
|
| }
|
| accept(HVisitor visitor) => visitor.visitBitNot(this);
|
| @@ -1958,13 +1972,13 @@
|
|
|
| abstract class HRelational extends HInvokeBinary {
|
| bool usesBoolifiedInterceptor = false;
|
| - HRelational(HInstruction left, HInstruction right) : super(left, right) {
|
| + HRelational(left, right, selector) : super(left, right, selector) {
|
| instructionType = HType.BOOLEAN;
|
| }
|
| }
|
|
|
| class HIdentity extends HRelational {
|
| - HIdentity(HInstruction left, HInstruction right) : super(left, right);
|
| + HIdentity(left, right, [selector]) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitIdentity(this);
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem)
|
| @@ -1975,7 +1989,7 @@
|
| }
|
|
|
| class HGreater extends HRelational {
|
| - HGreater(HInstruction left, HInstruction right) : super(left, right);
|
| + HGreater(left, right, selector) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitGreater(this);
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem)
|
| @@ -1986,7 +2000,7 @@
|
| }
|
|
|
| class HGreaterEqual extends HRelational {
|
| - HGreaterEqual(HInstruction left, HInstruction right) : super(left, right);
|
| + HGreaterEqual(left, right, selector) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitGreaterEqual(this);
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem)
|
| @@ -1997,7 +2011,7 @@
|
| }
|
|
|
| class HLess extends HRelational {
|
| - HLess(HInstruction left, HInstruction right) : super(left, right);
|
| + HLess(left, right, selector) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitLess(this);
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem)
|
| @@ -2008,7 +2022,7 @@
|
| }
|
|
|
| class HLessEqual extends HRelational {
|
| - HLessEqual(HInstruction left, HInstruction right) : super(left, right);
|
| + HLessEqual(left, right, selector) : super(left, right, selector);
|
| accept(HVisitor visitor) => visitor.visitLessEqual(this);
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem)
|
| @@ -2152,7 +2166,8 @@
|
| * does not throw because we generate the checks explicitly.
|
| */
|
| class HIndex extends HInstruction {
|
| - HIndex(HInstruction receiver, HInstruction index)
|
| + final Selector selector;
|
| + HIndex(HInstruction receiver, HInstruction index, this.selector)
|
| : super(<HInstruction>[receiver, index]) {
|
| clearAllSideEffects();
|
| setDependsOnIndexStore();
|
| @@ -2175,9 +2190,11 @@
|
| * does not throw because we generate the checks explicitly.
|
| */
|
| class HIndexAssign extends HInstruction {
|
| + final Selector selector;
|
| HIndexAssign(HInstruction receiver,
|
| HInstruction index,
|
| - HInstruction value)
|
| + HInstruction value,
|
| + this.selector)
|
| : super(<HInstruction>[receiver, index, value]) {
|
| clearAllSideEffects();
|
| setChangesIndex();
|
| @@ -2239,16 +2256,20 @@
|
| class HTypeConversion extends HCheck {
|
| final DartType typeExpression;
|
| final int kind;
|
| + final Selector receiverTypeCheckSelector;
|
|
|
| static const int NO_CHECK = 0;
|
| static const int CHECKED_MODE_CHECK = 1;
|
| static const int ARGUMENT_TYPE_CHECK = 2;
|
| static const int CAST_TYPE_CHECK = 3;
|
| static const int BOOLEAN_CONVERSION_CHECK = 4;
|
| + static const int RECEIVER_TYPE_CHECK = 5;
|
|
|
| HTypeConversion(this.typeExpression, this.kind,
|
| - HType type, HInstruction input)
|
| + HType type, HInstruction input,
|
| + [this.receiverTypeCheckSelector])
|
| : super(<HInstruction>[input]) {
|
| + assert(!isReceiverTypeCheck || receiverTypeCheckSelector != null);
|
| sourceElement = input.sourceElement;
|
| instructionType = type;
|
| }
|
| @@ -2259,13 +2280,14 @@
|
| || kind == BOOLEAN_CONVERSION_CHECK;
|
| }
|
| bool get isArgumentTypeCheck => kind == ARGUMENT_TYPE_CHECK;
|
| + bool get isReceiverTypeCheck => kind == RECEIVER_TYPE_CHECK;
|
| bool get isCastTypeCheck => kind == CAST_TYPE_CHECK;
|
| bool get isBooleanConversionCheck => kind == BOOLEAN_CONVERSION_CHECK;
|
|
|
| accept(HVisitor visitor) => visitor.visitTypeConversion(this);
|
|
|
| - bool isJsStatement() => kind == ARGUMENT_TYPE_CHECK;
|
| - bool isControlFlow() => kind == ARGUMENT_TYPE_CHECK;
|
| + bool isJsStatement() => isControlFlow();
|
| + bool isControlFlow() => isArgumentTypeCheck || isReceiverTypeCheck;
|
| bool canThrow() => isChecked;
|
|
|
| int typeCode() => HInstruction.TYPE_CONVERSION_TYPECODE;
|
|
|