summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@shopify.com>2025-12-06 15:55:32 +1300
committerGitHub <noreply@github.com>2025-12-06 15:55:32 +1300
commita7dc53b91c8475323b34d5a332fdb25d190e277d (patch)
tree0a3ae38b9f91bf841b0ee76d877da1711ff4791d /internal
parent8f9838476dc8cc857859a0a93da285d792be7d3b (diff)
Add support for `u128`, `U128`, `s128` and `S128` integers to `IO::Buffer`. (#15399)
Diffstat (limited to 'internal')
-rw-r--r--internal/bignum.h6
-rw-r--r--internal/numeric.h43
2 files changed, 49 insertions, 0 deletions
diff --git a/internal/bignum.h b/internal/bignum.h
index e5b6b42563..0692bafed3 100644
--- a/internal/bignum.h
+++ b/internal/bignum.h
@@ -169,7 +169,13 @@ VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck);
VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags);
RUBY_SYMBOL_EXPORT_END
+#if HAVE_LONG_LONG
+VALUE rb_ull2big(unsigned LONG_LONG n);
+VALUE rb_ll2big(LONG_LONG n);
+#endif
+
#if defined(HAVE_INT128_T)
+VALUE rb_uint128t2big(uint128_t n);
VALUE rb_int128t2big(int128_t n);
#endif
diff --git a/internal/numeric.h b/internal/numeric.h
index 58f42f41ac..75181a7f16 100644
--- a/internal/numeric.h
+++ b/internal/numeric.h
@@ -127,6 +127,49 @@ VALUE rb_int_bit_length(VALUE num);
VALUE rb_int_uminus(VALUE num);
VALUE rb_int_comp(VALUE num);
+// Unified 128-bit integer structures that work with or without native support:
+union rb_uint128 {
+#ifdef WORDS_BIGENDIAN
+ struct {
+ uint64_t high;
+ uint64_t low;
+ } parts;
+#else
+ struct {
+ uint64_t low;
+ uint64_t high;
+ } parts;
+#endif
+#ifdef HAVE_UINT128_T
+ uint128_t value;
+#endif
+};
+typedef union rb_uint128 rb_uint128_t;
+
+union rb_int128 {
+#ifdef WORDS_BIGENDIAN
+ struct {
+ uint64_t high;
+ uint64_t low;
+ } parts;
+#else
+ struct {
+ uint64_t low;
+ uint64_t high;
+ } parts;
+#endif
+#ifdef HAVE_UINT128_T
+ int128_t value;
+#endif
+};
+typedef union rb_int128 rb_int128_t;
+
+// Conversion functions for 128-bit integers:
+rb_uint128_t rb_numeric_to_uint128(VALUE x);
+rb_int128_t rb_numeric_to_int128(VALUE x);
+VALUE rb_uint128_to_numeric(rb_uint128_t n);
+VALUE rb_int128_to_numeric(rb_int128_t n);
+
static inline bool
INT_POSITIVE_P(VALUE num)
{