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 import '../closure.dart'; | 5 import '../closure.dart'; |
6 import '../common.dart'; | 6 import '../common.dart'; |
7 import '../common/backend_api.dart' show BackendClasses; | 7 import '../common/backend_api.dart' show BackendClasses; |
8 import '../compiler.dart' show Compiler; | 8 import '../compiler.dart' show Compiler; |
9 import '../constants/constant_system.dart'; | 9 import '../constants/constant_system.dart'; |
10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 isBooleanOrNull(closedWorld) || | 1114 isBooleanOrNull(closedWorld) || |
1115 isNull(); | 1115 isNull(); |
1116 } | 1116 } |
1117 | 1117 |
1118 /** | 1118 /** |
1119 * Type of the instruction. | 1119 * Type of the instruction. |
1120 */ | 1120 */ |
1121 TypeMask instructionType; | 1121 TypeMask instructionType; |
1122 | 1122 |
1123 Selector get selector => null; | 1123 Selector get selector => null; |
1124 HInstruction getDartReceiver(Compiler compiler) => null; | 1124 HInstruction getDartReceiver(ClosedWorld closedWorld) => null; |
1125 bool onlyThrowsNSM() => false; | 1125 bool onlyThrowsNSM() => false; |
1126 | 1126 |
1127 bool isInBasicBlock() => block != null; | 1127 bool isInBasicBlock() => block != null; |
1128 | 1128 |
1129 bool gvnEquals(HInstruction other) { | 1129 bool gvnEquals(HInstruction other) { |
1130 assert(useGvn() && other.useGvn()); | 1130 assert(useGvn() && other.useGvn()); |
1131 // Check that the type and the sideEffects match. | 1131 // Check that the type and the sideEffects match. |
1132 bool hasSameType = typeEquals(other); | 1132 bool hasSameType = typeEquals(other); |
1133 assert(hasSameType == (typeCode() == other.typeCode())); | 1133 assert(hasSameType == (typeCode() == other.typeCode())); |
1134 if (!hasSameType) return false; | 1134 if (!hasSameType) return false; |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1297 bool isConstantBoolean() => false; | 1297 bool isConstantBoolean() => false; |
1298 bool isConstantNull() => false; | 1298 bool isConstantNull() => false; |
1299 bool isConstantNumber() => false; | 1299 bool isConstantNumber() => false; |
1300 bool isConstantInteger() => false; | 1300 bool isConstantInteger() => false; |
1301 bool isConstantString() => false; | 1301 bool isConstantString() => false; |
1302 bool isConstantList() => false; | 1302 bool isConstantList() => false; |
1303 bool isConstantMap() => false; | 1303 bool isConstantMap() => false; |
1304 bool isConstantFalse() => false; | 1304 bool isConstantFalse() => false; |
1305 bool isConstantTrue() => false; | 1305 bool isConstantTrue() => false; |
1306 | 1306 |
1307 bool isInterceptor(Compiler compiler) => false; | 1307 bool isInterceptor(ClosedWorld closedWorld) => false; |
1308 | 1308 |
1309 bool isValid() { | 1309 bool isValid() { |
1310 HValidator validator = new HValidator(); | 1310 HValidator validator = new HValidator(); |
1311 validator.currentBlock = block; | 1311 validator.currentBlock = block; |
1312 validator.visitInstruction(this); | 1312 validator.visitInstruction(this); |
1313 return validator.isValid; | 1313 return validator.isValid; |
1314 } | 1314 } |
1315 | 1315 |
1316 bool isCodeMotionInvariant() => false; | 1316 bool isCodeMotionInvariant() => false; |
1317 | 1317 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1537 HInvokeDynamic(Selector selector, this.mask, this.element, | 1537 HInvokeDynamic(Selector selector, this.mask, this.element, |
1538 List<HInstruction> inputs, TypeMask type, | 1538 List<HInstruction> inputs, TypeMask type, |
1539 [bool isIntercepted = false]) | 1539 [bool isIntercepted = false]) |
1540 : super(inputs, type), | 1540 : super(inputs, type), |
1541 this.selector = selector, | 1541 this.selector = selector, |
1542 specializer = isIntercepted | 1542 specializer = isIntercepted |
1543 ? InvokeDynamicSpecializer.lookupSpecializer(selector) | 1543 ? InvokeDynamicSpecializer.lookupSpecializer(selector) |
1544 : const InvokeDynamicSpecializer(); | 1544 : const InvokeDynamicSpecializer(); |
1545 toString() => 'invoke dynamic: selector=$selector, mask=$mask'; | 1545 toString() => 'invoke dynamic: selector=$selector, mask=$mask'; |
1546 HInstruction get receiver => inputs[0]; | 1546 HInstruction get receiver => inputs[0]; |
1547 HInstruction getDartReceiver(Compiler compiler) { | 1547 HInstruction getDartReceiver(ClosedWorld closedWorld) { |
1548 return isCallOnInterceptor(compiler) ? inputs[1] : inputs[0]; | 1548 return isCallOnInterceptor(closedWorld) ? inputs[1] : inputs[0]; |
1549 } | 1549 } |
1550 | 1550 |
1551 /** | 1551 /** |
1552 * Returns whether this call is on an interceptor object. | 1552 * Returns whether this call is on an interceptor object. |
1553 */ | 1553 */ |
1554 bool isCallOnInterceptor(Compiler compiler) { | 1554 bool isCallOnInterceptor(ClosedWorld closedWorld) { |
1555 return isInterceptedCall && receiver.isInterceptor(compiler); | 1555 return isInterceptedCall && receiver.isInterceptor(closedWorld); |
1556 } | 1556 } |
1557 | 1557 |
1558 int typeCode() => HInstruction.INVOKE_DYNAMIC_TYPECODE; | 1558 int typeCode() => HInstruction.INVOKE_DYNAMIC_TYPECODE; |
1559 bool typeEquals(other) => other is HInvokeDynamic; | 1559 bool typeEquals(other) => other is HInvokeDynamic; |
1560 bool dataEquals(HInvokeDynamic other) { | 1560 bool dataEquals(HInvokeDynamic other) { |
1561 // Use the name and the kind instead of [Selector.operator==] | 1561 // Use the name and the kind instead of [Selector.operator==] |
1562 // because we don't need to check the arity (already checked in | 1562 // because we don't need to check the arity (already checked in |
1563 // [gvnEquals]), and the receiver types may not be in sync. | 1563 // [gvnEquals]), and the receiver types may not be in sync. |
1564 return selector.name == other.selector.name && | 1564 return selector.name == other.selector.name && |
1565 selector.kind == other.selector.kind; | 1565 selector.kind == other.selector.kind; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1642 final Selector selector; | 1642 final Selector selector; |
1643 | 1643 |
1644 HInvokeSuper(MemberEntity element, this.caller, this.selector, inputs, type, | 1644 HInvokeSuper(MemberEntity element, this.caller, this.selector, inputs, type, |
1645 SourceInformation sourceInformation, | 1645 SourceInformation sourceInformation, |
1646 {this.isSetter}) | 1646 {this.isSetter}) |
1647 : super(element, inputs, type) { | 1647 : super(element, inputs, type) { |
1648 this.sourceInformation = sourceInformation; | 1648 this.sourceInformation = sourceInformation; |
1649 } | 1649 } |
1650 | 1650 |
1651 HInstruction get receiver => inputs[0]; | 1651 HInstruction get receiver => inputs[0]; |
1652 HInstruction getDartReceiver(Compiler compiler) { | 1652 HInstruction getDartReceiver(ClosedWorld closedWorld) { |
1653 return isCallOnInterceptor(compiler) ? inputs[1] : inputs[0]; | 1653 return isCallOnInterceptor(closedWorld) ? inputs[1] : inputs[0]; |
1654 } | 1654 } |
1655 | 1655 |
1656 /** | 1656 /** |
1657 * Returns whether this call is on an interceptor object. | 1657 * Returns whether this call is on an interceptor object. |
1658 */ | 1658 */ |
1659 bool isCallOnInterceptor(Compiler compiler) { | 1659 bool isCallOnInterceptor(ClosedWorld closedWorld) { |
1660 return isInterceptedCall && receiver.isInterceptor(compiler); | 1660 return isInterceptedCall && receiver.isInterceptor(closedWorld); |
1661 } | 1661 } |
1662 | 1662 |
1663 toString() => 'invoke super: $element'; | 1663 toString() => 'invoke super: $element'; |
1664 accept(HVisitor visitor) => visitor.visitInvokeSuper(this); | 1664 accept(HVisitor visitor) => visitor.visitInvokeSuper(this); |
1665 | 1665 |
1666 HInstruction get value { | 1666 HInstruction get value { |
1667 assert(isSetter); | 1667 assert(isSetter); |
1668 // The 'inputs' are [receiver, value] or [interceptor, receiver, value]. | 1668 // The 'inputs' are [receiver, value] or [interceptor, receiver, value]. |
1669 return inputs.last; | 1669 return inputs.last; |
1670 } | 1670 } |
(...skipping 29 matching lines...) Expand all Loading... |
1700 (isAssignable != null) ? isAssignable : element.isAssignable, | 1700 (isAssignable != null) ? isAssignable : element.isAssignable, |
1701 super(element, <HInstruction>[receiver], type) { | 1701 super(element, <HInstruction>[receiver], type) { |
1702 sideEffects.clearAllSideEffects(); | 1702 sideEffects.clearAllSideEffects(); |
1703 sideEffects.clearAllDependencies(); | 1703 sideEffects.clearAllDependencies(); |
1704 setUseGvn(); | 1704 setUseGvn(); |
1705 if (this.isAssignable) { | 1705 if (this.isAssignable) { |
1706 sideEffects.setDependsOnInstancePropertyStore(); | 1706 sideEffects.setDependsOnInstancePropertyStore(); |
1707 } | 1707 } |
1708 } | 1708 } |
1709 | 1709 |
1710 bool isInterceptor(Compiler compiler) { | 1710 bool isInterceptor(ClosedWorld closedWorld) { |
1711 if (sourceElement == null) return false; | 1711 if (sourceElement == null) return false; |
1712 // In case of a closure inside an interceptor class, [:this:] is | 1712 // In case of a closure inside an interceptor class, [:this:] is |
1713 // stored in the generated closure class, and accessed through a | 1713 // stored in the generated closure class, and accessed through a |
1714 // [HFieldGet]. | 1714 // [HFieldGet]. |
1715 JavaScriptBackend backend = compiler.backend; | |
1716 if (sourceElement is ThisLocal) { | 1715 if (sourceElement is ThisLocal) { |
1717 ThisLocal thisLocal = sourceElement; | 1716 ThisLocal thisLocal = sourceElement; |
1718 return backend.isInterceptorClass(thisLocal.enclosingClass); | 1717 return closedWorld.backendClasses |
| 1718 .isInterceptorClass(thisLocal.enclosingClass); |
1719 } | 1719 } |
1720 return false; | 1720 return false; |
1721 } | 1721 } |
1722 | 1722 |
1723 bool canThrow() => receiver.canBeNull(); | 1723 bool canThrow() => receiver.canBeNull(); |
1724 | 1724 |
1725 HInstruction getDartReceiver(Compiler compiler) => receiver; | 1725 HInstruction getDartReceiver(ClosedWorld closedWorld) => receiver; |
1726 bool onlyThrowsNSM() => true; | 1726 bool onlyThrowsNSM() => true; |
1727 bool get isNullCheck => element == null; | 1727 bool get isNullCheck => element == null; |
1728 | 1728 |
1729 accept(HVisitor visitor) => visitor.visitFieldGet(this); | 1729 accept(HVisitor visitor) => visitor.visitFieldGet(this); |
1730 | 1730 |
1731 int typeCode() => HInstruction.FIELD_GET_TYPECODE; | 1731 int typeCode() => HInstruction.FIELD_GET_TYPECODE; |
1732 bool typeEquals(other) => other is HFieldGet; | 1732 bool typeEquals(other) => other is HFieldGet; |
1733 bool dataEquals(HFieldGet other) => element == other.element; | 1733 bool dataEquals(HFieldGet other) => element == other.element; |
1734 String toString() => "FieldGet $element"; | 1734 String toString() => "FieldGet $element"; |
1735 } | 1735 } |
1736 | 1736 |
1737 class HFieldSet extends HFieldAccess { | 1737 class HFieldSet extends HFieldAccess { |
1738 HFieldSet(MemberEntity element, HInstruction receiver, HInstruction value) | 1738 HFieldSet(MemberEntity element, HInstruction receiver, HInstruction value) |
1739 : super(element, <HInstruction>[receiver, value], | 1739 : super(element, <HInstruction>[receiver, value], |
1740 const TypeMask.nonNullEmpty()) { | 1740 const TypeMask.nonNullEmpty()) { |
1741 sideEffects.clearAllSideEffects(); | 1741 sideEffects.clearAllSideEffects(); |
1742 sideEffects.clearAllDependencies(); | 1742 sideEffects.clearAllDependencies(); |
1743 sideEffects.setChangesInstanceProperty(); | 1743 sideEffects.setChangesInstanceProperty(); |
1744 } | 1744 } |
1745 | 1745 |
1746 bool canThrow() => receiver.canBeNull(); | 1746 bool canThrow() => receiver.canBeNull(); |
1747 | 1747 |
1748 HInstruction getDartReceiver(Compiler compiler) => receiver; | 1748 HInstruction getDartReceiver(ClosedWorld closedWorld) => receiver; |
1749 bool onlyThrowsNSM() => true; | 1749 bool onlyThrowsNSM() => true; |
1750 | 1750 |
1751 HInstruction get value => inputs[1]; | 1751 HInstruction get value => inputs[1]; |
1752 accept(HVisitor visitor) => visitor.visitFieldSet(this); | 1752 accept(HVisitor visitor) => visitor.visitFieldSet(this); |
1753 | 1753 |
1754 bool isJsStatement() => true; | 1754 bool isJsStatement() => true; |
1755 String toString() => "FieldSet $element"; | 1755 String toString() => "FieldSet $element"; |
1756 } | 1756 } |
1757 | 1757 |
1758 /** | 1758 /** |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1790 : this._(element, jsOp, POST_OP, <HInstruction>[receiver], type); | 1790 : this._(element, jsOp, POST_OP, <HInstruction>[receiver], type); |
1791 | 1791 |
1792 HInstruction get receiver => inputs[0]; | 1792 HInstruction get receiver => inputs[0]; |
1793 | 1793 |
1794 bool get isPreOp => opKind == PRE_OP; | 1794 bool get isPreOp => opKind == PRE_OP; |
1795 bool get isPostOp => opKind == POST_OP; | 1795 bool get isPostOp => opKind == POST_OP; |
1796 bool get isAssignOp => opKind == ASSIGN_OP; | 1796 bool get isAssignOp => opKind == ASSIGN_OP; |
1797 | 1797 |
1798 bool canThrow() => receiver.canBeNull(); | 1798 bool canThrow() => receiver.canBeNull(); |
1799 | 1799 |
1800 HInstruction getDartReceiver(Compiler compiler) => receiver; | 1800 HInstruction getDartReceiver(ClosedWorld closedWorld) => receiver; |
1801 bool onlyThrowsNSM() => true; | 1801 bool onlyThrowsNSM() => true; |
1802 | 1802 |
1803 HInstruction get value => inputs[1]; | 1803 HInstruction get value => inputs[1]; |
1804 accept(HVisitor visitor) => visitor.visitReadModifyWrite(this); | 1804 accept(HVisitor visitor) => visitor.visitReadModifyWrite(this); |
1805 | 1805 |
1806 bool isJsStatement() => isAssignOp; | 1806 bool isJsStatement() => isAssignOp; |
1807 String toString() => "ReadModifyWrite $jsOp $opKind $element"; | 1807 String toString() => "ReadModifyWrite $jsOp $opKind $element"; |
1808 } | 1808 } |
1809 | 1809 |
1810 abstract class HLocalAccess extends HInstruction { | 1810 abstract class HLocalAccess extends HInstruction { |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2247 bool isConstantBoolean() => constant.isBool; | 2247 bool isConstantBoolean() => constant.isBool; |
2248 bool isConstantNull() => constant.isNull; | 2248 bool isConstantNull() => constant.isNull; |
2249 bool isConstantNumber() => constant.isNum; | 2249 bool isConstantNumber() => constant.isNum; |
2250 bool isConstantInteger() => constant.isInt; | 2250 bool isConstantInteger() => constant.isInt; |
2251 bool isConstantString() => constant.isString; | 2251 bool isConstantString() => constant.isString; |
2252 bool isConstantList() => constant.isList; | 2252 bool isConstantList() => constant.isList; |
2253 bool isConstantMap() => constant.isMap; | 2253 bool isConstantMap() => constant.isMap; |
2254 bool isConstantFalse() => constant.isFalse; | 2254 bool isConstantFalse() => constant.isFalse; |
2255 bool isConstantTrue() => constant.isTrue; | 2255 bool isConstantTrue() => constant.isTrue; |
2256 | 2256 |
2257 bool isInterceptor(Compiler compiler) => constant.isInterceptor; | 2257 bool isInterceptor(ClosedWorld closedWorld) => constant.isInterceptor; |
2258 | 2258 |
2259 // Maybe avoid this if the literal is big? | 2259 // Maybe avoid this if the literal is big? |
2260 bool isCodeMotionInvariant() => true; | 2260 bool isCodeMotionInvariant() => true; |
2261 | 2261 |
2262 set instructionType(type) { | 2262 set instructionType(type) { |
2263 // Only lists can be specialized. The SSA builder uses the | 2263 // Only lists can be specialized. The SSA builder uses the |
2264 // inferrer for finding the type of a constant list. We should | 2264 // inferrer for finding the type of a constant list. We should |
2265 // have the constant know its type instead. | 2265 // have the constant know its type instead. |
2266 if (!isConstantList()) return; | 2266 if (!isConstantList()) return; |
2267 super.instructionType = type; | 2267 super.instructionType = type; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2313 | 2313 |
2314 class HThis extends HParameterValue { | 2314 class HThis extends HParameterValue { |
2315 HThis(ThisLocal element, TypeMask type) : super(element, type); | 2315 HThis(ThisLocal element, TypeMask type) : super(element, type); |
2316 | 2316 |
2317 ThisLocal get sourceElement => super.sourceElement; | 2317 ThisLocal get sourceElement => super.sourceElement; |
2318 | 2318 |
2319 accept(HVisitor visitor) => visitor.visitThis(this); | 2319 accept(HVisitor visitor) => visitor.visitThis(this); |
2320 | 2320 |
2321 bool isCodeMotionInvariant() => true; | 2321 bool isCodeMotionInvariant() => true; |
2322 | 2322 |
2323 bool isInterceptor(Compiler compiler) { | 2323 bool isInterceptor(ClosedWorld closedWorld) { |
2324 JavaScriptBackend backend = compiler.backend; | 2324 return closedWorld.backendClasses |
2325 return backend.isInterceptorClass(sourceElement.enclosingClass); | 2325 .isInterceptorClass(sourceElement.enclosingClass); |
2326 } | 2326 } |
2327 | 2327 |
2328 String toString() => 'this'; | 2328 String toString() => 'this'; |
2329 } | 2329 } |
2330 | 2330 |
2331 class HPhi extends HInstruction { | 2331 class HPhi extends HInstruction { |
2332 static const IS_NOT_LOGICAL_OPERATOR = 0; | 2332 static const IS_NOT_LOGICAL_OPERATOR = 0; |
2333 static const IS_AND = 1; | 2333 static const IS_AND = 1; |
2334 static const IS_OR = 2; | 2334 static const IS_OR = 2; |
2335 | 2335 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2521 accept(HVisitor visitor) => visitor.visitInterceptor(this); | 2521 accept(HVisitor visitor) => visitor.visitInterceptor(this); |
2522 HInstruction get receiver => inputs[0]; | 2522 HInstruction get receiver => inputs[0]; |
2523 | 2523 |
2524 bool get isConditionalConstantInterceptor => inputs.length == 2; | 2524 bool get isConditionalConstantInterceptor => inputs.length == 2; |
2525 HInstruction get conditionalConstantInterceptor => inputs[1]; | 2525 HInstruction get conditionalConstantInterceptor => inputs[1]; |
2526 void set conditionalConstantInterceptor(HConstant constant) { | 2526 void set conditionalConstantInterceptor(HConstant constant) { |
2527 assert(!isConditionalConstantInterceptor); | 2527 assert(!isConditionalConstantInterceptor); |
2528 inputs.add(constant); | 2528 inputs.add(constant); |
2529 } | 2529 } |
2530 | 2530 |
2531 bool isInterceptor(Compiler compiler) => true; | 2531 bool isInterceptor(ClosedWorld closedWorld) => true; |
2532 | 2532 |
2533 int typeCode() => HInstruction.INTERCEPTOR_TYPECODE; | 2533 int typeCode() => HInstruction.INTERCEPTOR_TYPECODE; |
2534 bool typeEquals(other) => other is HInterceptor; | 2534 bool typeEquals(other) => other is HInterceptor; |
2535 bool dataEquals(HInterceptor other) { | 2535 bool dataEquals(HInterceptor other) { |
2536 return interceptedClasses == other.interceptedClasses || | 2536 return interceptedClasses == other.interceptedClasses || |
2537 (interceptedClasses.length == other.interceptedClasses.length && | 2537 (interceptedClasses.length == other.interceptedClasses.length && |
2538 interceptedClasses.containsAll(other.interceptedClasses)); | 2538 interceptedClasses.containsAll(other.interceptedClasses)); |
2539 } | 2539 } |
2540 } | 2540 } |
2541 | 2541 |
2542 /** | 2542 /** |
2543 * A "one-shot" interceptor is a call to a synthetized method that | 2543 * A "one-shot" interceptor is a call to a synthetized method that |
2544 * will fetch the interceptor of its first parameter, and make a call | 2544 * will fetch the interceptor of its first parameter, and make a call |
2545 * on a given selector with the remaining parameters. | 2545 * on a given selector with the remaining parameters. |
2546 * | 2546 * |
2547 * In order to share the same optimizations with regular interceptor | 2547 * In order to share the same optimizations with regular interceptor |
2548 * calls, this class extends [HInvokeDynamic] and also has the null | 2548 * calls, this class extends [HInvokeDynamic] and also has the null |
2549 * constant as the first input. | 2549 * constant as the first input. |
2550 */ | 2550 */ |
2551 class HOneShotInterceptor extends HInvokeDynamic { | 2551 class HOneShotInterceptor extends HInvokeDynamic { |
2552 Set<ClassEntity> interceptedClasses; | 2552 Set<ClassEntity> interceptedClasses; |
2553 HOneShotInterceptor(Selector selector, TypeMask mask, | 2553 HOneShotInterceptor(Selector selector, TypeMask mask, |
2554 List<HInstruction> inputs, TypeMask type, this.interceptedClasses) | 2554 List<HInstruction> inputs, TypeMask type, this.interceptedClasses) |
2555 : super(selector, mask, null, inputs, type, true) { | 2555 : super(selector, mask, null, inputs, type, true) { |
2556 assert(inputs[0] is HConstant); | 2556 assert(inputs[0] is HConstant); |
2557 assert(inputs[0].isNull()); | 2557 assert(inputs[0].isNull()); |
2558 } | 2558 } |
2559 bool isCallOnInterceptor(Compiler compiler) => true; | 2559 bool isCallOnInterceptor(ClosedWorld closedWorld) => true; |
2560 | 2560 |
2561 String toString() => 'one shot interceptor: selector=$selector, mask=$mask'; | 2561 String toString() => 'one shot interceptor: selector=$selector, mask=$mask'; |
2562 accept(HVisitor visitor) => visitor.visitOneShotInterceptor(this); | 2562 accept(HVisitor visitor) => visitor.visitOneShotInterceptor(this); |
2563 } | 2563 } |
2564 | 2564 |
2565 /** An [HLazyStatic] is a static that is initialized lazily at first read. */ | 2565 /** An [HLazyStatic] is a static that is initialized lazily at first read. */ |
2566 class HLazyStatic extends HInstruction { | 2566 class HLazyStatic extends HInstruction { |
2567 final FieldEntity element; | 2567 final FieldEntity element; |
2568 HLazyStatic(this.element, type) : super(<HInstruction>[], type) { | 2568 HLazyStatic(this.element, type) : super(<HInstruction>[], type) { |
2569 // TODO(4931): The first access has side-effects, but we afterwards we | 2569 // TODO(4931): The first access has side-effects, but we afterwards we |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2624 String toString() => 'index operator'; | 2624 String toString() => 'index operator'; |
2625 accept(HVisitor visitor) => visitor.visitIndex(this); | 2625 accept(HVisitor visitor) => visitor.visitIndex(this); |
2626 | 2626 |
2627 HInstruction get receiver => inputs[0]; | 2627 HInstruction get receiver => inputs[0]; |
2628 HInstruction get index => inputs[1]; | 2628 HInstruction get index => inputs[1]; |
2629 | 2629 |
2630 // Implicit dependency on HBoundsCheck or constraints on index. | 2630 // Implicit dependency on HBoundsCheck or constraints on index. |
2631 // TODO(27272): Make HIndex dependent on bounds checking. | 2631 // TODO(27272): Make HIndex dependent on bounds checking. |
2632 bool get isMovable => false; | 2632 bool get isMovable => false; |
2633 | 2633 |
2634 HInstruction getDartReceiver(Compiler compiler) => receiver; | 2634 HInstruction getDartReceiver(ClosedWorld closedWorld) => receiver; |
2635 bool onlyThrowsNSM() => true; | 2635 bool onlyThrowsNSM() => true; |
2636 bool canThrow() => receiver.canBeNull(); | 2636 bool canThrow() => receiver.canBeNull(); |
2637 | 2637 |
2638 int typeCode() => HInstruction.INDEX_TYPECODE; | 2638 int typeCode() => HInstruction.INDEX_TYPECODE; |
2639 bool typeEquals(HInstruction other) => other is HIndex; | 2639 bool typeEquals(HInstruction other) => other is HIndex; |
2640 bool dataEquals(HIndex other) => true; | 2640 bool dataEquals(HIndex other) => true; |
2641 } | 2641 } |
2642 | 2642 |
2643 /** | 2643 /** |
2644 * The primitive array assignment operation. Note that this instruction | 2644 * The primitive array assignment operation. Note that this instruction |
(...skipping 13 matching lines...) Expand all Loading... |
2658 accept(HVisitor visitor) => visitor.visitIndexAssign(this); | 2658 accept(HVisitor visitor) => visitor.visitIndexAssign(this); |
2659 | 2659 |
2660 HInstruction get receiver => inputs[0]; | 2660 HInstruction get receiver => inputs[0]; |
2661 HInstruction get index => inputs[1]; | 2661 HInstruction get index => inputs[1]; |
2662 HInstruction get value => inputs[2]; | 2662 HInstruction get value => inputs[2]; |
2663 | 2663 |
2664 // Implicit dependency on HBoundsCheck or constraints on index. | 2664 // Implicit dependency on HBoundsCheck or constraints on index. |
2665 // TODO(27272): Make HIndex dependent on bounds checking. | 2665 // TODO(27272): Make HIndex dependent on bounds checking. |
2666 bool get isMovable => false; | 2666 bool get isMovable => false; |
2667 | 2667 |
2668 HInstruction getDartReceiver(Compiler compiler) => receiver; | 2668 HInstruction getDartReceiver(ClosedWorld closedWorld) => receiver; |
2669 bool onlyThrowsNSM() => true; | 2669 bool onlyThrowsNSM() => true; |
2670 bool canThrow() => receiver.canBeNull(); | 2670 bool canThrow() => receiver.canBeNull(); |
2671 } | 2671 } |
2672 | 2672 |
2673 class HIs extends HInstruction { | 2673 class HIs extends HInstruction { |
2674 /// A check against a raw type: 'o is int', 'o is A'. | 2674 /// A check against a raw type: 'o is int', 'o is A'. |
2675 static const int RAW_CHECK = 0; | 2675 static const int RAW_CHECK = 0; |
2676 | 2676 |
2677 /// A check against a type with type arguments: 'o is List<int>', 'o is C<T>'. | 2677 /// A check against a type with type arguments: 'o is List<int>', 'o is C<T>'. |
2678 static const int COMPOUND_CHECK = 1; | 2678 static const int COMPOUND_CHECK = 1; |
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3447 class HDynamicType extends HRuntimeType { | 3447 class HDynamicType extends HRuntimeType { |
3448 HDynamicType(DynamicType dartType, TypeMask instructionType) | 3448 HDynamicType(DynamicType dartType, TypeMask instructionType) |
3449 : super(const <HInstruction>[], dartType, instructionType); | 3449 : super(const <HInstruction>[], dartType, instructionType); |
3450 | 3450 |
3451 accept(HVisitor visitor) => visitor.visitDynamicType(this); | 3451 accept(HVisitor visitor) => visitor.visitDynamicType(this); |
3452 | 3452 |
3453 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; | 3453 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; |
3454 | 3454 |
3455 bool typeEquals(HInstruction other) => other is HDynamicType; | 3455 bool typeEquals(HInstruction other) => other is HDynamicType; |
3456 } | 3456 } |
OLD | NEW |