From ee13b9e67b09c4c78442c902a767d9bafece103f Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 19 Oct 2024 11:12:20 +0900 Subject: [PATCH] mruby-bigint: fix mrb_int optimization bugs for `and`, `or`, `xor` If the operand is a small integer, those functions tried to reduce bigint allocations, but we had some bugs in them. We removed those imperfect optimization altogether. --- mrbgems/mruby-bigint/core/bigint.c | 41 ++++++++++-------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index f481f17ac..afdfd0f8e 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -1789,7 +1789,7 @@ mrb_bint_to_s(mrb_state *mrb, mrb_value x, mrb_int base) mrb_value mrb_bint_and(mrb_state *mrb, mrb_value x, mrb_value y) { - mpz_t a; + mpz_t a, b, c; bint_as_mpz(RBIGINT(x), &a); if (mrb_integer_p(y)) { @@ -1800,47 +1800,32 @@ mrb_bint_and(mrb_state *mrb, mrb_value x, mrb_value y) return mrb_int_value(mrb, z); } if (z == -1) return x; - if (z < 0 && (mp_dbl_limb)-z < DIG_BASE) { - mpz_t b; - mpz_init(mrb, &b); - mpz_set(mrb, &b, &a); - b.p[0] &= (mp_limb)z; - return bint_norm(mrb, bint_new(mrb, &b)); - } } + y = mrb_as_bint(mrb, y); - mpz_t b, z; bint_as_mpz(RBIGINT(y), &b); - mpz_init(mrb, &z); - mpz_and(mrb, &z, &a, &b); - return bint_norm(mrb, bint_new(mrb, &z)); + if (zero_p(&a) || zero_p(&b)) return mrb_fixnum_value(0); + mpz_init(mrb, &c); + mpz_and(mrb, &c, &a, &b); + return bint_norm(mrb, bint_new(mrb, &c)); } mrb_value mrb_bint_or(mrb_state *mrb, mrb_value x, mrb_value y) { - mpz_t a; + mpz_t a, b, c; + bint_as_mpz(RBIGINT(x), &a); if (mrb_integer_p(y)) { mrb_int z = mrb_integer(y); if (z == 0) return x; if (z == -1) return y; - if (z > 0 && (mp_dbl_limb)z < DIG_BASE) { - z |= a.p[0]; - return mrb_int_value(mrb, z); - } - if (z < 0 && (mp_dbl_limb)-z < DIG_BASE) { - mpz_t b; - mpz_init(mrb, &b); - mpz_set(mrb, &b, &a); - b.p[0] |= (mp_limb)z; - return bint_norm(mrb, bint_new(mrb, &b)); - } } y = mrb_as_bint(mrb, y); - mpz_t b, c; bint_as_mpz(RBIGINT(y), &b); + if (zero_p(&a)) return y; + if (zero_p(&b)) return x; mpz_init(mrb, &c); mpz_or(mrb, &c, &b, &a); return bint_norm(mrb, bint_new(mrb, &c)); @@ -1862,7 +1847,7 @@ mrb_bint_neg(mrb_state *mrb, mrb_value x) mrb_value mrb_bint_xor(mrb_state *mrb, mrb_value x, mrb_value y) { - mpz_t a; + mpz_t a, b, c; bint_as_mpz(RBIGINT(x), &a); if (mrb_integer_p(y)) { @@ -1873,9 +1858,11 @@ mrb_bint_xor(mrb_state *mrb, mrb_value x, mrb_value y) return mrb_int_value(mrb, z); } } + y = mrb_as_bint(mrb, y); - mpz_t b, c; bint_as_mpz(RBIGINT(y), &b); + if (zero_p(&a)) return y; + if (zero_p(&b)) return x; mpz_init(mrb, &c); mpz_xor(mrb, &c, &a, &b); return bint_norm(mrb, bint_new(mrb, &c));