OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 1471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1482 SubtractOperation get operation() => const SubtractOperation(); | 1482 SubtractOperation get operation() => const SubtractOperation(); |
1483 int typeCode() => 9; | 1483 int typeCode() => 9; |
1484 bool typeEquals(other) => other is HSubtract; | 1484 bool typeEquals(other) => other is HSubtract; |
1485 bool dataEquals(HInstruction other) => true; | 1485 bool dataEquals(HInstruction other) => true; |
1486 } | 1486 } |
1487 | 1487 |
1488 /** | 1488 /** |
1489 * An [HSwitch] instruction has one input for the incoming | 1489 * An [HSwitch] instruction has one input for the incoming |
1490 * value, and one input per constant that it can switch on. | 1490 * value, and one input per constant that it can switch on. |
1491 * Its block has one successor per constant, and one for the default. | 1491 * Its block has one successor per constant, and one for the default. |
1492 * If the switch didn't have a default case, the last successor is | |
1493 * the join block. | |
1494 */ | 1492 */ |
1495 class HSwitch extends HControlFlow { | 1493 class HSwitch extends HControlFlow { |
1496 HSwitch(List<HInstruction> inputs) : super(inputs); | 1494 HSwitch(List<HInstruction> inputs) : super(inputs); |
1497 | 1495 |
1498 HConstant constant(int index) => inputs[index + 1]; | 1496 HConstant constant(int index) => inputs[index + 1]; |
1499 HInstruction get expression() => inputs[0]; | 1497 HInstruction get expression() => inputs[0]; |
1500 | 1498 |
| 1499 /** |
| 1500 * Provides the target to jump to if none of the constants match |
| 1501 * the expression. If the switc had no default case, this is the |
| 1502 * following join-block. |
| 1503 */ |
1501 HBasicBlock get defaultTarget() => block.successors.last(); | 1504 HBasicBlock get defaultTarget() => block.successors.last(); |
1502 | 1505 |
1503 accept(HVisitor visitor) => visitor.visitSwitch(this); | 1506 accept(HVisitor visitor) => visitor.visitSwitch(this); |
1504 | 1507 |
1505 String toString() => "HSwitch cases = $inputs"; | 1508 String toString() => "HSwitch cases = $inputs"; |
1506 } | 1509 } |
1507 | 1510 |
1508 class HTruncatingDivide extends HBinaryArithmetic { | 1511 class HTruncatingDivide extends HBinaryArithmetic { |
1509 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right) | 1512 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right) |
1510 : super(target, left, right); | 1513 : super(target, left, right); |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1806 // 'Not' only works on booleans. That's what we want as input. | 1809 // 'Not' only works on booleans. That's what we want as input. |
1807 HType computeDesiredTypeForInput(HInstruction input) => HType.BOOLEAN; | 1810 HType computeDesiredTypeForInput(HInstruction input) => HType.BOOLEAN; |
1808 | 1811 |
1809 accept(HVisitor visitor) => visitor.visitNot(this); | 1812 accept(HVisitor visitor) => visitor.visitNot(this); |
1810 int typeCode() => 18; | 1813 int typeCode() => 18; |
1811 bool typeEquals(other) => other is HNot; | 1814 bool typeEquals(other) => other is HNot; |
1812 bool dataEquals(HInstruction other) => true; | 1815 bool dataEquals(HInstruction other) => true; |
1813 } | 1816 } |
1814 | 1817 |
1815 class HParameterValue extends HInstruction { | 1818 class HParameterValue extends HInstruction { |
1816 HParameterValue(element) : super(<HInstruction>[]) { | 1819 HParameterValue(Element element) : super(<HInstruction>[]) { |
1817 sourceElement = element; | 1820 sourceElement = element; |
1818 } | 1821 } |
1819 | 1822 |
1820 void prepareGvn() { | 1823 void prepareGvn() { |
1821 assert(!hasSideEffects()); | 1824 assert(!hasSideEffects()); |
1822 } | 1825 } |
1823 toString() => 'parameter ${sourceElement.name}'; | 1826 toString() => 'parameter ${sourceElement.name}'; |
1824 accept(HVisitor visitor) => visitor.visitParameterValue(this); | 1827 accept(HVisitor visitor) => visitor.visitParameterValue(this); |
1825 bool isCodeMotionInvariant() => true; | 1828 bool isCodeMotionInvariant() => true; |
1826 } | 1829 } |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2213 HInstruction get typeInfoCall() => inputs[1]; | 2216 HInstruction get typeInfoCall() => inputs[1]; |
2214 | 2217 |
2215 HType get guaranteedType() => HType.BOOLEAN; | 2218 HType get guaranteedType() => HType.BOOLEAN; |
2216 | 2219 |
2217 accept(HVisitor visitor) => visitor.visitIs(this); | 2220 accept(HVisitor visitor) => visitor.visitIs(this); |
2218 | 2221 |
2219 toString() => "$expression is $typeExpression"; | 2222 toString() => "$expression is $typeExpression"; |
2220 } | 2223 } |
2221 | 2224 |
2222 class HTypeConversion extends HCheck { | 2225 class HTypeConversion extends HCheck { |
| 2226 static final int UNCHECKED = 0; |
| 2227 static final int CHECKED = 1; |
| 2228 static final int CAST = 2; |
| 2229 |
2223 HType type; | 2230 HType type; |
2224 final bool checked; | 2231 final int kind; |
2225 | 2232 |
2226 HTypeConversion(HType this.type, | 2233 HTypeConversion(HType this.type, |
2227 HInstruction input, | 2234 HInstruction input, |
2228 [bool this.checked = false]) | 2235 [this.kind = UNCHECKED]) |
2229 : super(<HInstruction>[input]) { | 2236 : super(<HInstruction>[input]) { |
2230 sourceElement = input.sourceElement; | 2237 sourceElement = input.sourceElement; |
2231 } | 2238 } |
2232 | 2239 |
| 2240 bool get checked() => kind != UNCHECKED; |
| 2241 /** |
| 2242 * Whether to use cast-semantics instead of checked-mode assignment semantics |
| 2243 * for the conversion. The difference is that a cast throws on [:null:] and |
| 2244 * throws a different exception on a failed match. |
| 2245 */ |
| 2246 bool get isCast() => kind == CAST; |
| 2247 |
2233 HType get guaranteedType() => type; | 2248 HType get guaranteedType() => type; |
2234 | 2249 |
2235 accept(HVisitor visitor) => visitor.visitTypeConversion(this); | 2250 accept(HVisitor visitor) => visitor.visitTypeConversion(this); |
2236 | 2251 |
2237 bool hasSideEffects() => checked; | 2252 bool hasSideEffects() => checked; |
2238 } | 2253 } |
2239 | 2254 |
2240 class HStringConcat extends HInstruction { | 2255 class HStringConcat extends HInstruction { |
2241 final Node node; | 2256 final Node node; |
2242 HStringConcat(HInstruction left, HInstruction right, this.node) | 2257 HStringConcat(HInstruction left, HInstruction right, this.node) |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2567 HBasicBlock get start() => expression.start; | 2582 HBasicBlock get start() => expression.start; |
2568 HBasicBlock get end() { | 2583 HBasicBlock get end() { |
2569 // We don't create a switch block if there are no cases. | 2584 // We don't create a switch block if there are no cases. |
2570 assert(!statements.isEmpty()); | 2585 assert(!statements.isEmpty()); |
2571 return statements.last().end; | 2586 return statements.last().end; |
2572 } | 2587 } |
2573 | 2588 |
2574 bool accept(HStatementInformationVisitor visitor) => | 2589 bool accept(HStatementInformationVisitor visitor) => |
2575 visitor.visitSwitchInfo(this); | 2590 visitor.visitSwitchInfo(this); |
2576 } | 2591 } |
OLD | NEW |