diff --git a/gc.c b/gc.c index 8b6142b139..5a14cb3675 100644 --- a/gc.c +++ b/gc.c @@ -484,21 +484,21 @@ rb_malloc_grow_capa(size_t current, size_t type_size) return new_capacity; } -static inline struct rbimpl_size_mul_overflow_tag +static inline struct rbimpl_size_overflow_tag size_mul_add_overflow(size_t x, size_t y, size_t z) /* x * y + z */ { - struct rbimpl_size_mul_overflow_tag t = rbimpl_size_mul_overflow(x, y); - struct rbimpl_size_mul_overflow_tag u = rbimpl_size_add_overflow(t.right, z); - return (struct rbimpl_size_mul_overflow_tag) { t.left || u.left, u.right }; + struct rbimpl_size_overflow_tag t = rbimpl_size_mul_overflow(x, y); + struct rbimpl_size_overflow_tag u = rbimpl_size_add_overflow(t.result, z); + return (struct rbimpl_size_overflow_tag) { t.overflowed || u.overflowed, u.result }; } -static inline struct rbimpl_size_mul_overflow_tag +static inline struct rbimpl_size_overflow_tag size_mul_add_mul_overflow(size_t x, size_t y, size_t z, size_t w) /* x * y + z * w */ { - struct rbimpl_size_mul_overflow_tag t = rbimpl_size_mul_overflow(x, y); - struct rbimpl_size_mul_overflow_tag u = rbimpl_size_mul_overflow(z, w); - struct rbimpl_size_mul_overflow_tag v = rbimpl_size_add_overflow(t.right, u.right); - return (struct rbimpl_size_mul_overflow_tag) { t.left || u.left || v.left, v.right }; + struct rbimpl_size_overflow_tag t = rbimpl_size_mul_overflow(x, y); + struct rbimpl_size_overflow_tag u = rbimpl_size_mul_overflow(z, w); + struct rbimpl_size_overflow_tag v = rbimpl_size_add_overflow(t.result, u.result); + return (struct rbimpl_size_overflow_tag) { t.overflowed || u.overflowed || v.overflowed, v.result }; } PRINTF_ARGS(NORETURN(static void gc_raise(VALUE, const char*, ...)), 2, 3); @@ -506,9 +506,9 @@ PRINTF_ARGS(NORETURN(static void gc_raise(VALUE, const char*, ...)), 2, 3); static inline size_t size_mul_or_raise(size_t x, size_t y, VALUE exc) { - struct rbimpl_size_mul_overflow_tag t = rbimpl_size_mul_overflow(x, y); - if (LIKELY(!t.left)) { - return t.right; + struct rbimpl_size_overflow_tag t = rbimpl_size_mul_overflow(x, y); + if (LIKELY(!t.overflowed)) { + return t.result; } else if (rb_during_gc()) { rb_memerror(); /* or...? */ @@ -532,9 +532,9 @@ rb_size_mul_or_raise(size_t x, size_t y, VALUE exc) static inline size_t size_mul_add_or_raise(size_t x, size_t y, size_t z, VALUE exc) { - struct rbimpl_size_mul_overflow_tag t = size_mul_add_overflow(x, y, z); - if (LIKELY(!t.left)) { - return t.right; + struct rbimpl_size_overflow_tag t = size_mul_add_overflow(x, y, z); + if (LIKELY(!t.overflowed)) { + return t.result; } else if (rb_during_gc()) { rb_memerror(); /* or...? */ @@ -559,9 +559,9 @@ rb_size_mul_add_or_raise(size_t x, size_t y, size_t z, VALUE exc) static inline size_t size_mul_add_mul_or_raise(size_t x, size_t y, size_t z, size_t w, VALUE exc) { - struct rbimpl_size_mul_overflow_tag t = size_mul_add_mul_overflow(x, y, z, w); - if (LIKELY(!t.left)) { - return t.right; + struct rbimpl_size_overflow_tag t = size_mul_add_mul_overflow(x, y, z, w); + if (LIKELY(!t.overflowed)) { + return t.result; } else if (rb_during_gc()) { rb_memerror(); /* or...? */ @@ -5372,11 +5372,11 @@ ruby_mimcalloc(size_t num, size_t size) { void *mem; #if CALC_EXACT_MALLOC_SIZE - struct rbimpl_size_mul_overflow_tag t = rbimpl_size_mul_overflow(num, size); - if (UNLIKELY(t.left)) { + struct rbimpl_size_overflow_tag t = rbimpl_size_mul_overflow(num, size); + if (UNLIKELY(t.overflowed)) { return NULL; } - size = t.right + sizeof(struct malloc_obj_info); + size = t.result + sizeof(struct malloc_obj_info); mem = calloc1(size); if (!mem) { return NULL; diff --git a/include/ruby/internal/memory.h b/include/ruby/internal/memory.h index 9fc6c39efc..cd099f85db 100644 --- a/include/ruby/internal/memory.h +++ b/include/ruby/internal/memory.h @@ -408,7 +408,8 @@ typedef uint128_t DSIZE_T; /** * @private * - * This is an implementation detail of rbimpl_size_mul_overflow(). + * This is an implementation detail of rbimpl_size_mul_overflow() and + * rbimpl_size_add_overflow(). * * @internal * @@ -416,9 +417,9 @@ typedef uint128_t DSIZE_T; * nothing more than std::variant if we could use recent C++, but * reality is we cannot. */ -struct rbimpl_size_mul_overflow_tag { - bool left; /**< Whether overflow happened or not. */ - size_t right; /**< Multiplication result. */ +struct rbimpl_size_overflow_tag { + bool overflowed; /**< Whether overflow happened or not. */ + size_t result; /**< Calculation result. */ }; RBIMPL_SYMBOL_EXPORT_BEGIN() @@ -572,46 +573,46 @@ RBIMPL_ATTR_CONST() * * @param[in] x Arbitrary value. * @param[in] y Arbitrary value. - * @return `{ left, right }`, where `left` is whether there is an integer - * overflow or not, and `right` is a (possibly overflowed) result - * of `x` * `y`. + * @return `{ overflowed, result }`, where `overflowed` is whether there is + * an integer overflow or not, and `result` is a (possibly + * overflowed) result of `x` * `y`. * * @internal * * This is in fact also an implementation detail of ruby_xmalloc2() etc. */ -static inline struct rbimpl_size_mul_overflow_tag +static inline struct rbimpl_size_overflow_tag rbimpl_size_mul_overflow(size_t x, size_t y) { - struct rbimpl_size_mul_overflow_tag ret = { false, 0, }; + struct rbimpl_size_overflow_tag ret = { false, 0, }; #if defined(ckd_mul) - ret.left = ckd_mul(&ret.right, x, y); + ret.overflowed = ckd_mul(&ret.result, x, y); #elif RBIMPL_HAS_BUILTIN(__builtin_mul_overflow) - ret.left = __builtin_mul_overflow(x, y, &ret.right); + ret.overflowed = __builtin_mul_overflow(x, y, &ret.result); #elif defined(DSIZE_T) RB_GNUC_EXTENSION DSIZE_T dx = x; RB_GNUC_EXTENSION DSIZE_T dy = y; RB_GNUC_EXTENSION DSIZE_T dz = dx * dy; - ret.left = dz > SIZE_MAX; - ret.right = RBIMPL_CAST((size_t)dz); + ret.overflowed = dz > SIZE_MAX; + ret.result = RBIMPL_CAST((size_t)dz); #elif defined(_MSC_VER) && defined(_M_AMD64) unsigned __int64 dp = 0; unsigned __int64 dz = _umul128(x, y, &dp); - ret.left = RBIMPL_CAST((bool)dp); - ret.right = RBIMPL_CAST((size_t)dz); + ret.overflowed = RBIMPL_CAST((bool)dp); + ret.result = RBIMPL_CAST((size_t)dz); #elif defined(_MSC_VER) && defined(_M_ARM64) - ret.left = __umulh(x, y) != 0; - ret.right = x * y; + ret.overflowed = __umulh(x, y) != 0; + ret.result = x * y; #else /* https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap */ - ret.left = (y != 0) && (x > SIZE_MAX / y); - ret.right = x * y; + ret.overflowed = (y != 0) && (x > SIZE_MAX / y); + ret.result = x * y; #endif return ret; @@ -635,11 +636,11 @@ rbimpl_size_mul_overflow(size_t x, size_t y) static inline size_t rbimpl_size_mul_or_raise(size_t x, size_t y) { - struct rbimpl_size_mul_overflow_tag size = + struct rbimpl_size_overflow_tag size = rbimpl_size_mul_overflow(x, y); - if (RB_LIKELY(! size.left)) { - return size.right; + if (RB_LIKELY(! size.overflowed)) { + return size.result; } else { ruby_malloc_size_overflow(x, y); @@ -662,33 +663,33 @@ RBIMPL_ATTR_CONST() * * @param[in] x Arbitrary value. * @param[in] y Arbitrary value. - * @return `{ left, right }`, where `left` is whether there is an integer - * overflow or not, and `right` is a (possibly overflowed) result - * of `x` + `y`. + * @return `{ overflowed, result }`, where `overflowed` is whether there is + * an integer overflow or not, and `result` is a (possibly + * overflowed) result of `x` + `y`. * * @internal */ -static inline struct rbimpl_size_mul_overflow_tag +static inline struct rbimpl_size_overflow_tag rbimpl_size_add_overflow(size_t x, size_t y) { - struct rbimpl_size_mul_overflow_tag ret = { false, 0, }; + struct rbimpl_size_overflow_tag ret = { false, 0, }; #if defined(ckd_add) - ret.left = ckd_add(&ret.right, x, y); + ret.overflowed = ckd_add(&ret.result, x, y); #elif RBIMPL_HAS_BUILTIN(__builtin_add_overflow) - ret.left = __builtin_add_overflow(x, y, &ret.right); + ret.overflowed = __builtin_add_overflow(x, y, &ret.result); #elif defined(DSIZE_T) RB_GNUC_EXTENSION DSIZE_T dx = x; RB_GNUC_EXTENSION DSIZE_T dy = y; RB_GNUC_EXTENSION DSIZE_T dz = dx + dy; - ret.left = dz > SIZE_MAX; - ret.right = (size_t)dz; + ret.overflowed = dz > SIZE_MAX; + ret.result = (size_t)dz; #else - ret.right = x + y; - ret.left = ret.right < y; + ret.result = x + y; + ret.overflowed = ret.result < y; #endif @@ -710,11 +711,11 @@ rbimpl_size_add_overflow(size_t x, size_t y) static inline size_t rbimpl_size_add_or_raise(size_t x, size_t y) { - struct rbimpl_size_mul_overflow_tag size = + struct rbimpl_size_overflow_tag size = rbimpl_size_add_overflow(x, y); - if (RB_LIKELY(!size.left)) { - return size.right; + if (RB_LIKELY(!size.overflowed)) { + return size.result; } else { ruby_malloc_add_size_overflow(x, y); diff --git a/io_buffer.c b/io_buffer.c index 1ee2bc9324..85061076cd 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -1527,8 +1527,8 @@ VALUE rb_io_buffer_free_locked(VALUE self) static bool size_sum_is_bigger_than(size_t a, size_t b, size_t x) { - struct rbimpl_size_mul_overflow_tag size = rbimpl_size_add_overflow(a, b); - return size.left || size.right > x; + struct rbimpl_size_overflow_tag size = rbimpl_size_add_overflow(a, b); + return size.overflowed || size.result > x; } // Validate that access to the buffer is within bounds, assuming you want to