| ... | ... | @@ -1669,7 +1669,7 @@ pub const Value = extern union { |
| 1669 | 1669 | const rhs_bigint = rhs.toBigInt(&rhs_space); |
| 1670 | 1670 | const limbs = try arena.alloc( |
| 1671 | 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 | 1674 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 1675 | 1675 | result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| ... | ... | @@ -1693,19 +1693,25 @@ pub const Value = extern union { |
| 1693 | 1693 | assert(!lhs.isUndef()); |
| 1694 | 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); |
| 1699 | | if (compare(result, .gt, max, ty)) { |
| 1700 | | return max; |
| 1701 | | } |
| 1698 | var lhs_space: Value.BigIntSpace = undefined; |
| 1699 | var rhs_space: Value.BigIntSpace = undefined; |
| 1700 | const lhs_bigint = lhs.toBigInt(&lhs_space); |
| 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); |
| 1704 | | if (compare(result, .lt, min, ty)) { |
| 1705 | | return min; |
| 1710 | if (result_bigint.positive) { |
| 1711 | return Value.Tag.int_big_positive.create(arena, result_limbs); |
| 1712 | } else { |
| 1713 | return Value.Tag.int_big_negative.create(arena, result_limbs); |
| 1706 | 1714 | } |
| 1707 | | |
| 1708 | | return result; |
| 1709 | 1715 | } |
| 1710 | 1716 | |
| 1711 | 1717 | /// Supports both floats and ints; handles undefined. |
| ... | ... | @@ -1730,7 +1736,7 @@ pub const Value = extern union { |
| 1730 | 1736 | const rhs_bigint = rhs.toBigInt(&rhs_space); |
| 1731 | 1737 | const limbs = try arena.alloc( |
| 1732 | 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 | 1741 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 1736 | 1742 | result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| ... | ... | @@ -1741,7 +1747,6 @@ pub const Value = extern union { |
| 1741 | 1747 | } else { |
| 1742 | 1748 | return Value.Tag.int_big_negative.create(arena, result_limbs); |
| 1743 | 1749 | } |
| 1744 | | |
| 1745 | 1750 | } |
| 1746 | 1751 | |
| 1747 | 1752 | /// Supports integers only; asserts neither operand is undefined. |
| ... | ... | @@ -1755,19 +1760,25 @@ pub const Value = extern union { |
| 1755 | 1760 | assert(!lhs.isUndef()); |
| 1756 | 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); |
| 1761 | | if (compare(result, .gt, max, ty)) { |
| 1762 | | return max; |
| 1763 | | } |
| 1765 | var lhs_space: Value.BigIntSpace = undefined; |
| 1766 | var rhs_space: Value.BigIntSpace = undefined; |
| 1767 | const lhs_bigint = lhs.toBigInt(&lhs_space); |
| 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); |
| 1766 | | if (compare(result, .lt, min, ty)) { |
| 1767 | | return min; |
| 1777 | if (result_bigint.positive) { |
| 1778 | return Value.Tag.int_big_positive.create(arena, result_limbs); |
| 1779 | } else { |
| 1780 | return Value.Tag.int_big_negative.create(arena, result_limbs); |
| 1768 | 1781 | } |
| 1769 | | |
| 1770 | | return result; |
| 1771 | 1782 | } |
| 1772 | 1783 | |
| 1773 | 1784 | /// Supports both floats and ints; handles undefined. |