Skip to content

[pull] master from mruby:master#177

Merged
pull[bot] merged 16 commits intosysfce2:masterfrom
mruby:master
Jan 13, 2026
Merged

[pull] master from mruby:master#177
pull[bot] merged 16 commits intosysfce2:masterfrom
mruby:master

Conversation

@pull
Copy link

@pull pull bot commented Jan 13, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

matz and others added 16 commits January 13, 2026 12:47
When mpz_or or mpz_xor copies an operand when the other is zero,
the copied mpz_t may have an inflated sz field (larger than actual
allocated limbs). Add trim() after mpz_set to normalize the size.

This is a follow-up fix to commit 61aa223 which addressed the
same issue in shift operations.

Co-authored-by: Claude <noreply@anthropic.com>
Add dc_to_s_scratch_t structure to preallocate work buffers for the
base case of divide-and-conquer decimal string conversion. This
eliminates repeated malloc/free calls in the inner loop where digits
are extracted 9 at a time.

Previously, each iteration of the base case loop allocated and freed
a quotient buffer. Now the same two buffers are reused with pointer
swapping, reducing allocation overhead by ~10-18% for large numbers.

Co-authored-by: Claude <noreply@anthropic.com>
Use scratch buffers for q5, r5, and q5_low in the recursive case of
D&C decimal string conversion. These temporaries are only needed
during the computation of hi and lo values, not during the recursive
calls, so they can be safely reused at each recursion level.

This eliminates 3 allocations per recursion level (approximately
log2(digits/1000) levels for large numbers), providing an additional
2-3% performance improvement on top of the base case optimization.

Co-authored-by: Claude <noreply@anthropic.com>
Add mpn_rshift and mpn_lshift functions that operate directly on limb
arrays, following GMP's mpn layer design. These functions support
in-place operation and return shifted-out bits.

Refactor urshift and ulshift to use these new mpn functions, simplifying
the code and improving reusability.

Co-authored-by: Claude <noreply@anthropic.com>
Add mpn_add_n, mpn_add, mpn_add_1, mpn_sub_n, mpn_sub, and mpn_sub_1
functions that operate directly on limb arrays, following GMP's mpn
layer design. These functions support in-place operation and return
carry/borrow.

Refactor uadd and usub to use these new mpn functions, simplifying the
code significantly (134 lines deleted, replaced with cleaner mpn calls).
Also update limb_sub to delegate to mpn_sub_n.

Co-authored-by: Claude <noreply@anthropic.com>
mpz_to_s_dc_recur fills in exactly num_digits characters but did not
add a null terminator. This caused valgrind errors when strlen was
called on the resulting string.

Co-authored-by: Claude <noreply@anthropic.com>
When converting large numbers to strings using D&C algorithm, the
base case extracts digits in batches of 9 (for 32-bit limbs). The
extraction logic: 1 leading digit + 4 pairs (8 digits) = 9 digits.

The pair extraction loop condition `pos >= 2` exits when pos < 2,
but when the remaining batch still has value and pos == 1, that
final digit was being lost and replaced with '0' by the padding loop.

This caused roundtrip failures (x.to_s.to_i != x) for numbers just
above the D&C threshold (1000 digits), where the split boundary
produced a lo part requiring exactly the right number of digits to
trigger this edge case.

Co-authored-by: Claude <noreply@anthropic.com>
Replace array indexing x.p[i+j] with pointer arithmetic *xp++ in the
hot inner loop of Knuth Algorithm D division. This avoids recalculating
the index i+j on every iteration.

Profiling showed the inner loop accounts for ~80% of udiv execution time,
with the array indexing contributing significant overhead.

Benchmark improvement: ~4% faster (7.80s -> 7.48s for 2.4M bit to_s).

Co-authored-by: Claude <noreply@anthropic.com>
Instead of allocating a separate hi buffer for the upper part of the
split, reuse q5 by shifting it in place after extracting the lower
bits to q5_low.

This eliminates one mpz_t allocation per recursive call:
- Extract q5_low = q5 mod 2^k first (copy lower bits)
- Shift q5 right in place (memmove + mpn_rshift) to get hi
- q5 now serves as hi for the recursive call

Benchmark results (2.4M bit number):
- Memory: -3.5% (5.58MB -> 5.38MB peak heap)
- Instructions: -16.5%
- Speed: unchanged (within measurement noise)

Co-authored-by: Claude <noreply@anthropic.com>
Replace per-call lo allocation with depth-indexed lo_stack buffers
that are reused across recursion levels. Each buffer is allocated
on first use at that depth with appropriate size.

This reduces 493 malloc/free calls (5%) and 580KB of memory (2%)
for large number to_s conversions while maintaining performance.

Co-authored-by: Claude <noreply@anthropic.com>
Replace the two-buffer swap pattern in D&C to_s base case with
in-place division using new mpn_div10_9 function. This eliminates
the q_base scratch buffer and reduces per-iteration overhead.

Compilers optimize the constant division by 10^9 to multiplication
and shift operations for better performance.

Co-authored-by: Claude <noreply@anthropic.com>
The JMPNOT-to-JMPIF optimization assumed fail_pos always came from a
4-byte JMPNOT instruction. When a pinned variable is undefined,
NODE_PAT_PIN generates a 3-byte OP_JMP instead, causing fail_pos - 2
to point into the previous instruction and corrupt its operand.

Add a check to verify the instruction at fail_pos - 2 is actually
OP_JMPNOT before modifying it.

Fixes #6701

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
Remove MRB_TRY/MRB_CATCH exception handling from bigint.c to fix
compilation errors when using mruby-bigint in C++ projects with
MRB_USE_CXX_EXCEPTION enabled.

The exception handling was added for cleanup on error, but it requires
throw.h which doesn't work when a C file is compiled in a C++ context
with C++ exceptions enabled. Accepting potential memory leaks on
exception (rare) is preferable to breaking C++ builds.

Fixes #6702

Co-authored-by: Claude <noreply@anthropic.com>
Use mrb_protect_error API instead of direct MRB_TRY/MRB_CATCH to handle
exceptions in mpz_mul_all_ones and mpz_to_s_dc. This maintains C++
compatibility (issue #6702) while ensuring temporary mpz_t allocations
are properly freed even when exceptions occur.

Co-authored-by: Claude <noreply@anthropic.com>
Document that this header is for mruby core internal use only and
should not be included in user code or mrbgems. When MRB_USE_CXX_EXCEPTION
is defined, C source files including this header fail to compile.
Add example showing mrb_protect_error() as the recommended alternative.

Co-authored-by: Claude <noreply@anthropic.com>
@pull pull bot locked and limited conversation to collaborators Jan 13, 2026
@pull pull bot added the ⤵️ pull label Jan 13, 2026
@pull pull bot merged commit d9a7d1a into sysfce2:master Jan 13, 2026
6 of 13 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant