From 2e45af37a8016df0b7b98c93f1770d6bb831a972 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 25 Jul 2025 12:11:00 +0900 Subject: [PATCH] mruby-bigint: extract core addition algorithm to eliminate duplication Extract multi-limb addition algorithm from uadd() and uadd_pool() into shared uadd_core() helper function. Both functions now use the same core addition logic with carry propagation, eliminating duplication and ensuring consistent behavior. Benefits: - Eliminates ~13 lines of duplicated addition algorithm code - Single source of truth for multi-limb addition with carry handling - Reduces maintenance burden for future optimizations - Maintains all existing functionality and performance Co-authored-by: Claude --- mrbgems/mruby-bigint/core/bigint.c | 57 ++++++++++++++++-------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index 514948cd3..032e28d96 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -337,6 +337,32 @@ trim(mpz_t *x) } +/* Core addition algorithm - extracted from uadd/uadd_pool duplication */ +static void +uadd_core(mpz_t *z, mpz_t *x, mpz_t *y) +{ + /* Core multi-limb addition with carry propagation */ + mp_dbl_limb c = 0; + size_t i; + + /* Add overlapping limbs from both operands */ + for (i = 0; i < x->sz; i++) { + c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i]; + z->p[i] = LOW(c); + c >>= DIG_SIZE; + } + + /* Add remaining limbs from larger operand */ + for (; i < y->sz; i++) { + c += y->p[i]; + z->p[i] = LOW(c); + c >>= DIG_SIZE; + } + + /* Store final carry */ + z->p[y->sz] = (mp_limb)c; +} + /* z = x + y, without regard for sign */ static void uadd(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) @@ -349,19 +375,8 @@ uadd(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* now y->sz >= x->sz */ mpz_realloc(mrb, z, y->sz+1); - mp_dbl_limb c = 0; - size_t i; - for (i=0; isz; i++) { - c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i]; - z->p[i] = LOW(c); - c >>= DIG_SIZE; - } - for (;isz; i++) { - c += y->p[i]; - z->p[i] = LOW(c); - c >>= DIG_SIZE; - } - z->p[y->sz] = (mp_limb)c; + /* Use core addition algorithm */ + uadd_core(z, x, y); } /* Pool-based unsigned addition - uses stack memory for result */ @@ -384,20 +399,8 @@ uadd_pool(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y, mpz_pool_t *pool) /* Try to allocate in pool */ MPZ_POOL_ALLOC(mrb, *z, pool, result_size); - /* Perform addition using pool memory */ - mp_dbl_limb c = 0; - size_t i; - for (i=0; isz; i++) { - c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i]; - z->p[i] = LOW(c); - c >>= DIG_SIZE; - } - for (;isz; i++) { - c += y->p[i]; - z->p[i] = LOW(c); - c >>= DIG_SIZE; - } - z->p[y->sz] = (mp_limb)c; + /* Use core addition algorithm */ + uadd_core(z, x, y); return 1; /* Success - used pool memory */ }