Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 interface HVisitor<R> { | 5 interface HVisitor<R> { |
| 6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
| 7 R visitBitAnd(HBitAnd node); | 7 R visitBitAnd(HBitAnd node); |
| 8 R visitBitNot(HBitNot node); | 8 R visitBitNot(HBitNot node); |
| 9 R visitBitOr(HBitOr node); | 9 R visitBitOr(HBitOr node); |
| 10 R visitBitXor(HBitXor node); | 10 R visitBitXor(HBitXor node); |
| (...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 933 | 933 |
| 934 bool isConstant() => false; | 934 bool isConstant() => false; |
| 935 bool isConstantBoolean() => false; | 935 bool isConstantBoolean() => false; |
| 936 bool isConstantNull() => false; | 936 bool isConstantNull() => false; |
| 937 bool isConstantNumber() => false; | 937 bool isConstantNumber() => false; |
| 938 bool isConstantString() => false; | 938 bool isConstantString() => false; |
| 939 bool isConstantList() => false; | 939 bool isConstantList() => false; |
| 940 bool isConstantMap() => false; | 940 bool isConstantMap() => false; |
| 941 bool isConstantFalse() => false; | 941 bool isConstantFalse() => false; |
| 942 bool isConstantTrue() => false; | 942 bool isConstantTrue() => false; |
| 943 bool isConstantInteger() => false; | |
|
floitsch
2012/06/19 11:15:58
move next to isConstantNumber
kasperl
2012/06/19 11:22:06
Done.
| |
| 943 | 944 |
| 944 bool isValid() { | 945 bool isValid() { |
| 945 HValidator validator = new HValidator(); | 946 HValidator validator = new HValidator(); |
| 946 validator.currentBlock = block; | 947 validator.currentBlock = block; |
| 947 validator.visitInstruction(this); | 948 validator.visitInstruction(this); |
| 948 return validator.isValid; | 949 return validator.isValid; |
| 949 } | 950 } |
| 950 | 951 |
| 951 /** | 952 /** |
| 952 * The code for computing a bailout environment, and the code | 953 * The code for computing a bailout environment, and the code |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1393 | 1394 |
| 1394 // TODO(1603): The class should be marked as abstract. | 1395 // TODO(1603): The class should be marked as abstract. |
| 1395 abstract BinaryOperation get operation(); | 1396 abstract BinaryOperation get operation(); |
| 1396 } | 1397 } |
| 1397 | 1398 |
| 1398 class HAdd extends HBinaryArithmetic { | 1399 class HAdd extends HBinaryArithmetic { |
| 1399 HAdd(HStatic target, HInstruction left, HInstruction right) | 1400 HAdd(HStatic target, HInstruction left, HInstruction right) |
| 1400 : super(target, left, right); | 1401 : super(target, left, right); |
| 1401 accept(HVisitor visitor) => visitor.visitAdd(this); | 1402 accept(HVisitor visitor) => visitor.visitAdd(this); |
| 1402 | 1403 |
| 1403 HType computeTypeFromInputTypes() { | |
| 1404 if (left.isInteger() && right.isInteger()) return left.propagatedType; | |
| 1405 if (left.isNumber()) { | |
| 1406 if (left.isDouble() || right.isDouble()) return HType.DOUBLE; | |
| 1407 return HType.NUMBER; | |
| 1408 } | |
| 1409 return HType.UNKNOWN; | |
| 1410 } | |
| 1411 | |
| 1412 HType computeDesiredTypeForNonTargetInput(HInstruction input) { | |
| 1413 // If the desired output type is an integer we want two integers as input. | |
| 1414 if (propagatedType.isInteger()) { | |
| 1415 return HType.INTEGER; | |
| 1416 } | |
| 1417 // If the desired output is a number or any of the inputs is a number | |
| 1418 // ask for a number. Note that we might return the input's (say 'left') | |
| 1419 // type depending on its (the 'left's) type. But that shouldn't matter. | |
| 1420 if (propagatedType.isNumber() || left.isNumber() || right.isNumber()) { | |
| 1421 return HType.NUMBER; | |
| 1422 } | |
| 1423 return HType.UNKNOWN; | |
| 1424 } | |
| 1425 | |
| 1426 HType get likelyType() { | |
| 1427 if (left.isTypeUnknown() || left.isNumber()) return HType.NUMBER; | |
| 1428 return HType.UNKNOWN; | |
| 1429 } | |
| 1430 | |
| 1431 AddOperation get operation() => const AddOperation(); | 1404 AddOperation get operation() => const AddOperation(); |
| 1432 | |
| 1433 int typeCode() => 5; | 1405 int typeCode() => 5; |
| 1434 bool typeEquals(other) => other is HAdd; | 1406 bool typeEquals(other) => other is HAdd; |
| 1435 bool dataEquals(HInstruction other) => true; | 1407 bool dataEquals(HInstruction other) => true; |
| 1436 } | 1408 } |
| 1437 | 1409 |
| 1438 class HDivide extends HBinaryArithmetic { | 1410 class HDivide extends HBinaryArithmetic { |
| 1439 HDivide(HStatic target, HInstruction left, HInstruction right) | 1411 HDivide(HStatic target, HInstruction left, HInstruction right) |
| 1440 : super(target, left, right); | 1412 : super(target, left, right); |
| 1441 accept(HVisitor visitor) => visitor.visitDivide(this); | 1413 accept(HVisitor visitor) => visitor.visitDivide(this); |
| 1442 | 1414 |
| 1443 bool get builtin() => left.isNumber() && right.isNumber(); | |
| 1444 | |
| 1445 HType computeTypeFromInputTypes() { | 1415 HType computeTypeFromInputTypes() { |
| 1446 if (left.isNumber()) return HType.DOUBLE; | 1416 if (left.isNumber()) return HType.DOUBLE; |
| 1447 return HType.UNKNOWN; | 1417 return HType.UNKNOWN; |
| 1448 } | 1418 } |
| 1449 | 1419 |
| 1450 HType computeDesiredTypeForNonTargetInput(HInstruction input) { | 1420 HType computeDesiredTypeForNonTargetInput(HInstruction input) { |
| 1451 // A division can never return an integer. So don't ask for integer inputs. | 1421 // A division can never return an integer. So don't ask for integer inputs. |
| 1452 if (propagatedType.isInteger()) return HType.UNKNOWN; | 1422 if (propagatedType.isInteger()) return HType.UNKNOWN; |
| 1453 return super.computeDesiredTypeForNonTargetInput(input); | 1423 return super.computeDesiredTypeForNonTargetInput(input); |
| 1454 } | 1424 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1557 | 1527 |
| 1558 // TODO(floitsch): make class abstract instead of adding an abstract method. | 1528 // TODO(floitsch): make class abstract instead of adding an abstract method. |
| 1559 abstract accept(HVisitor visitor); | 1529 abstract accept(HVisitor visitor); |
| 1560 } | 1530 } |
| 1561 | 1531 |
| 1562 class HShiftLeft extends HBinaryBitOp { | 1532 class HShiftLeft extends HBinaryBitOp { |
| 1563 HShiftLeft(HStatic target, HInstruction left, HInstruction right) | 1533 HShiftLeft(HStatic target, HInstruction left, HInstruction right) |
| 1564 : super(target, left, right); | 1534 : super(target, left, right); |
| 1565 accept(HVisitor visitor) => visitor.visitShiftLeft(this); | 1535 accept(HVisitor visitor) => visitor.visitShiftLeft(this); |
| 1566 | 1536 |
| 1537 // Shift left cannot be mapped to the native operator unless the | |
| 1538 // shift count is guaranteed to be an integer in the [0,31] range. | |
| 1539 bool get builtin() { | |
| 1540 if (!left.isInteger() || !right.isConstantInteger()) return false; | |
| 1541 HConstant rightConstant = right; | |
| 1542 int count = rightConstant.constant.value; | |
| 1543 return count >= 0 && count <= 31; | |
| 1544 } | |
| 1545 | |
| 1567 ShiftLeftOperation get operation() => const ShiftLeftOperation(); | 1546 ShiftLeftOperation get operation() => const ShiftLeftOperation(); |
| 1568 int typeCode() => 11; | 1547 int typeCode() => 11; |
| 1569 bool typeEquals(other) => other is HShiftLeft; | 1548 bool typeEquals(other) => other is HShiftLeft; |
| 1570 bool dataEquals(HInstruction other) => true; | 1549 bool dataEquals(HInstruction other) => true; |
| 1571 } | 1550 } |
| 1572 | 1551 |
| 1573 class HShiftRight extends HBinaryBitOp { | 1552 class HShiftRight extends HBinaryBitOp { |
| 1574 HShiftRight(HStatic target, HInstruction left, HInstruction right) | 1553 HShiftRight(HStatic target, HInstruction left, HInstruction right) |
| 1575 : super(target, left, right); | 1554 : super(target, left, right); |
| 1576 accept(HVisitor visitor) => visitor.visitShiftRight(this); | 1555 accept(HVisitor visitor) => visitor.visitShiftRight(this); |
| 1577 | 1556 |
| 1557 // Shift right cannot be mapped to the native operator easily. | |
| 1558 bool get builtin() => false; | |
| 1559 | |
| 1578 ShiftRightOperation get operation() => const ShiftRightOperation(); | 1560 ShiftRightOperation get operation() => const ShiftRightOperation(); |
| 1579 int typeCode() => 12; | 1561 int typeCode() => 12; |
| 1580 bool typeEquals(other) => other is HShiftRight; | 1562 bool typeEquals(other) => other is HShiftRight; |
| 1581 bool dataEquals(HInstruction other) => true; | 1563 bool dataEquals(HInstruction other) => true; |
| 1582 } | 1564 } |
| 1583 | 1565 |
| 1584 class HBitOr extends HBinaryBitOp { | 1566 class HBitOr extends HBinaryBitOp { |
| 1585 HBitOr(HStatic target, HInstruction left, HInstruction right) | 1567 HBitOr(HStatic target, HInstruction left, HInstruction right) |
| 1586 : super(target, left, right); | 1568 : super(target, left, right); |
| 1587 accept(HVisitor visitor) => visitor.visitBitOr(this); | 1569 accept(HVisitor visitor) => visitor.visitBitOr(this); |
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2227 | 2209 |
| 2228 HType get guaranteedType() => HType.BOOLEAN; | 2210 HType get guaranteedType() => HType.BOOLEAN; |
| 2229 | 2211 |
| 2230 accept(HVisitor visitor) => visitor.visitIs(this); | 2212 accept(HVisitor visitor) => visitor.visitIs(this); |
| 2231 | 2213 |
| 2232 toString() => "$expression is $typeExpression"; | 2214 toString() => "$expression is $typeExpression"; |
| 2233 } | 2215 } |
| 2234 | 2216 |
| 2235 class HTypeConversion extends HCheck { | 2217 class HTypeConversion extends HCheck { |
| 2236 HType type; | 2218 HType type; |
| 2237 final bool checked; | 2219 final int kind; |
| 2238 | 2220 |
| 2239 HTypeConversion(HType this.type, | 2221 static final int NO_CHECK = 0; |
| 2240 HInstruction input, | 2222 static final int CHECKED_MODE_CHECK = 1; |
| 2241 [bool this.checked = false]) | 2223 static final int ARGUMENT_TYPE_CHECK = 2; |
| 2242 : super(<HInstruction>[input]) { | 2224 |
| 2243 sourceElement = input.sourceElement; | 2225 HTypeConversion(HType type, HInstruction input) |
| 2226 : this.internal(type, input, NO_CHECK); | |
| 2227 HTypeConversion.checkedModeCheck(HType type, HInstruction input) | |
|
floitsch
2012/06/19 11:15:58
Alternatively we could have 3 subclasses of a HTyp
| |
| 2228 : this.internal(type, input, CHECKED_MODE_CHECK); | |
| 2229 HTypeConversion.argumentTypeCheck(HType type, HInstruction input) | |
| 2230 : this.internal(type, input, ARGUMENT_TYPE_CHECK); | |
| 2231 | |
| 2232 HTypeConversion.internal(this.type, HInstruction input, this.kind) | |
| 2233 : super(<HInstruction>[input]) { | |
| 2234 sourceElement = input.sourceElement; | |
| 2244 } | 2235 } |
| 2245 | 2236 |
| 2237 bool isChecked() => kind != NO_CHECK; | |
| 2238 bool isCheckedModeCheck() => kind == CHECKED_MODE_CHECK; | |
| 2239 bool isArgumentTypeCheck() => kind == ARGUMENT_TYPE_CHECK; | |
| 2240 | |
| 2246 HType get guaranteedType() => type; | 2241 HType get guaranteedType() => type; |
| 2247 | 2242 |
| 2248 accept(HVisitor visitor) => visitor.visitTypeConversion(this); | 2243 accept(HVisitor visitor) => visitor.visitTypeConversion(this); |
| 2249 | 2244 |
| 2250 bool hasSideEffects() => checked; | 2245 bool hasSideEffects() => kind != NO_CHECK; |
| 2246 bool isStatement() => kind == ARGUMENT_TYPE_CHECK; | |
| 2247 bool isControlFlow() => kind == ARGUMENT_TYPE_CHECK; | |
| 2251 } | 2248 } |
| 2252 | 2249 |
| 2253 class HStringConcat extends HInstruction { | 2250 class HStringConcat extends HInstruction { |
| 2254 final Node node; | 2251 final Node node; |
| 2255 HStringConcat(HInstruction left, HInstruction right, this.node) | 2252 HStringConcat(HInstruction left, HInstruction right, this.node) |
| 2256 : super(<HInstruction>[left, right]); | 2253 : super(<HInstruction>[left, right]); |
| 2257 HType get guaranteedType() => HType.STRING; | 2254 HType get guaranteedType() => HType.STRING; |
| 2258 | 2255 |
| 2259 HInstruction get left() => inputs[0]; | 2256 HInstruction get left() => inputs[0]; |
| 2260 HInstruction get right() => inputs[1]; | 2257 HInstruction get right() => inputs[1]; |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2584 HBasicBlock get start() => expression.start; | 2581 HBasicBlock get start() => expression.start; |
| 2585 HBasicBlock get end() { | 2582 HBasicBlock get end() { |
| 2586 // We don't create a switch block if there are no cases. | 2583 // We don't create a switch block if there are no cases. |
| 2587 assert(!statements.isEmpty()); | 2584 assert(!statements.isEmpty()); |
| 2588 return statements.last().end; | 2585 return statements.last().end; |
| 2589 } | 2586 } |
| 2590 | 2587 |
| 2591 bool accept(HStatementInformationVisitor visitor) => | 2588 bool accept(HStatementInformationVisitor visitor) => |
| 2592 visitor.visitSwitchInfo(this); | 2589 visitor.visitSwitchInfo(this); |
| 2593 } | 2590 } |
| OLD | NEW |