| ... | @@ -1669,7 +1669,7 @@ pub const Value = extern union { | ... | @@ -1669,7 +1669,7 @@ pub const Value = extern union { |
| 1669 | const rhs_bigint = rhs.toBigInt(&rhs_space); | 1669 | const rhs_bigint = rhs.toBigInt(&rhs_space); |
| 1670 | const limbs = try arena.alloc( | 1670 | const limbs = try arena.alloc( |
| 1671 | std.math.big.Limb, | 1671 | std.math.big.Limb, |
| 1672 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, | 1672 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len), |
| 1673 | ); | 1673 | ); |
| 1674 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 1674 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 1675 | result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); | 1675 | result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| ... | @@ -1693,19 +1693,25 @@ pub const Value = extern union { | ... | @@ -1693,19 +1693,25 @@ pub const Value = extern union { |
| 1693 | assert(!lhs.isUndef()); | 1693 | assert(!lhs.isUndef()); |
| 1694 | assert(!rhs.isUndef()); | 1694 | assert(!rhs.isUndef()); |
| 1695 | | 1695 | |
| 1696 | const result = try intAdd(lhs, rhs, arena); | 1696 | const info = ty.intInfo(target); |
| 1697 | | 1697 | |
| 1698 | const max = try ty.maxInt(arena, target); | 1698 | var lhs_space: Value.BigIntSpace = undefined; |
| 1699 | if (compare(result, .gt, max, ty)) { | 1699 | var rhs_space: Value.BigIntSpace = undefined; |
| 1700 | return max; | 1700 | const lhs_bigint = lhs.toBigInt(&lhs_space); |
| 1701 | } | 1701 | const rhs_bigint = rhs.toBigInt(&rhs_space); |
| | 1702 | const limbs = try arena.alloc( |
| | 1703 | std.math.big.Limb, |
| | 1704 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len), |
| | 1705 | ); |
| | 1706 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| | 1707 | result_bigint.addSat(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| | 1708 | const result_limbs = result_bigint.limbs[0..result_bigint.len]; |
| 1702 | | 1709 | |
| 1703 | const min = try ty.minInt(arena, target); | 1710 | if (result_bigint.positive) { |
| 1704 | if (compare(result, .lt, min, ty)) { | 1711 | return Value.Tag.int_big_positive.create(arena, result_limbs); |
| 1705 | return min; | 1712 | } else { |
| | 1713 | return Value.Tag.int_big_negative.create(arena, result_limbs); |
| 1706 | } | 1714 | } |
| 1707 | | | |
| 1708 | return result; | | |
| 1709 | } | 1715 | } |
| 1710 | | 1716 | |
| 1711 | /// Supports both floats and ints; handles undefined. | 1717 | /// Supports both floats and ints; handles undefined. |
| ... | @@ -1730,7 +1736,7 @@ pub const Value = extern union { | ... | @@ -1730,7 +1736,7 @@ pub const Value = extern union { |
| 1730 | const rhs_bigint = rhs.toBigInt(&rhs_space); | 1736 | const rhs_bigint = rhs.toBigInt(&rhs_space); |
| 1731 | const limbs = try arena.alloc( | 1737 | const limbs = try arena.alloc( |
| 1732 | std.math.big.Limb, | 1738 | std.math.big.Limb, |
| 1733 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, | 1739 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len), |
| 1734 | ); | 1740 | ); |
| 1735 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 1741 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 1736 | result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); | 1742 | result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| ... | @@ -1741,7 +1747,6 @@ pub const Value = extern union { | ... | @@ -1741,7 +1747,6 @@ pub const Value = extern union { |
| 1741 | } else { | 1747 | } else { |
| 1742 | return Value.Tag.int_big_negative.create(arena, result_limbs); | 1748 | return Value.Tag.int_big_negative.create(arena, result_limbs); |
| 1743 | } | 1749 | } |
| 1744 | | | |
| 1745 | } | 1750 | } |
| 1746 | | 1751 | |
| 1747 | /// Supports integers only; asserts neither operand is undefined. | 1752 | /// Supports integers only; asserts neither operand is undefined. |
| ... | @@ -1755,19 +1760,25 @@ pub const Value = extern union { | ... | @@ -1755,19 +1760,25 @@ pub const Value = extern union { |
| 1755 | assert(!lhs.isUndef()); | 1760 | assert(!lhs.isUndef()); |
| 1756 | assert(!rhs.isUndef()); | 1761 | assert(!rhs.isUndef()); |
| 1757 | | 1762 | |
| 1758 | const result = try intSub(lhs, rhs, arena); | 1763 | const info = ty.intInfo(target); |
| 1759 | | 1764 | |
| 1760 | const max = try ty.maxInt(arena, target); | 1765 | var lhs_space: Value.BigIntSpace = undefined; |
| 1761 | if (compare(result, .gt, max, ty)) { | 1766 | var rhs_space: Value.BigIntSpace = undefined; |
| 1762 | return max; | 1767 | const lhs_bigint = lhs.toBigInt(&lhs_space); |
| 1763 | } | 1768 | const rhs_bigint = rhs.toBigInt(&rhs_space); |
| | 1769 | const limbs = try arena.alloc( |
| | 1770 | std.math.big.Limb, |
| | 1771 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len), |
| | 1772 | ); |
| | 1773 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| | 1774 | result_bigint.subSat(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| | 1775 | const result_limbs = result_bigint.limbs[0..result_bigint.len]; |
| 1764 | | 1776 | |
| 1765 | const min = try ty.minInt(arena, target); | 1777 | if (result_bigint.positive) { |
| 1766 | if (compare(result, .lt, min, ty)) { | 1778 | return Value.Tag.int_big_positive.create(arena, result_limbs); |
| 1767 | return min; | 1779 | } else { |
| | 1780 | return Value.Tag.int_big_negative.create(arena, result_limbs); |
| 1768 | } | 1781 | } |
| 1769 | | | |
| 1770 | return result; | | |
| 1771 | } | 1782 | } |
| 1772 | | 1783 | |
| 1773 | /// Supports both floats and ints; handles undefined. | 1784 | /// Supports both floats and ints; handles undefined. |