| 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 |