From 06bce53132a21a78299eca84143aa7b6c5cf96d8 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 25 Feb 2026 10:02:21 +0900 Subject: [PATCH] fix build for MRB_NO_BOXING + MRB_INT64 on 32-bit - array.h: disable embedded arrays when MRB_INT64 makes mrb_value too large to embed (fixes MRB_ARY_EMBED_LEN_MAX assertion) - error.h: enable MRB_USE_RBREAK_VALUE_UNION for all 32-bit no-boxing builds (MRB_USE_FLOAT32 is irrelevant without word/nan boxing) - gc.c: restrict RVALUE 8-byte alignment padding to MRB_WORD_BOXING builds (fixes RVALUE size assertion) - vm.c: guard direct ary->as.ary access with MRB_ARY_NO_EMBED Fixes #6722. Co-authored-by: Claude --- include/mruby/array.h | 2 +- include/mruby/error.h | 2 +- src/gc.c | 4 ++-- src/vm.c | 10 ++++++++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/include/mruby/array.h b/include/mruby/array.h index 1ebba93b8..0a956a8a9 100644 --- a/include/mruby/array.h +++ b/include/mruby/array.h @@ -20,7 +20,7 @@ typedef struct mrb_shared_array { mrb_value *ptr; } mrb_shared_array; -#if defined(MRB_32BIT) && defined(MRB_NO_BOXING) && !defined(MRB_USE_FLOAT32) && !defined(MRB_ARY_NO_EMBED) +#if defined(MRB_32BIT) && defined(MRB_NO_BOXING) && (!defined(MRB_USE_FLOAT32) || defined(MRB_INT64)) && !defined(MRB_ARY_NO_EMBED) # define MRB_ARY_NO_EMBED #endif diff --git a/include/mruby/error.h b/include/mruby/error.h index ba091fcfe..dbff17cd1 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -36,7 +36,7 @@ MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value st #define mrb_exc_new_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit)) MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...); -#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT32) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING) +#if defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING) || defined(MRB_64BIT) #undef MRB_USE_RBREAK_VALUE_UNION #else #define MRB_USE_RBREAK_VALUE_UNION 1 diff --git a/src/gc.c b/src/gc.c index 0dffad10c..69a3d9d2d 100644 --- a/src/gc.c +++ b/src/gc.c @@ -121,7 +121,7 @@ struct free_obj { struct RVALUE_initializer { MRB_OBJECT_HEADER; -#if defined(MRB_32BIT) && defined(MRB_USE_FLOAT32) && !defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE) +#if defined(MRB_WORD_BOXING) && defined(MRB_32BIT) && defined(MRB_USE_FLOAT32) && !defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE) /* inline float word boxing needs 8-byte aligned objects; pad RVALUE to 24 bytes (multiple of 8) on 32-bit */ char padding[sizeof(void*) * 4]; @@ -1600,7 +1600,7 @@ mrb_init_gc(mrb_state *mrb) { struct RClass *gc; -#if defined(MRB_32BIT) && defined(MRB_USE_FLOAT32) && !defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE) +#if defined(MRB_WORD_BOXING) && defined(MRB_32BIT) && defined(MRB_USE_FLOAT32) && !defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE) /* 6 words: padded to 8-byte alignment for inline float word boxing */ mrb_static_assert(sizeof(RVALUE) <= sizeof(void*) * 6, "RVALUE size must be within 6 words"); diff --git a/src/vm.c b/src/vm.c index fad48c61f..b0b0b5b12 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1902,11 +1902,14 @@ RETRY_TRY_BLOCK: mrb_value *ptr; /* Single ARY_EMBED_P check instead of two */ +#ifndef MRB_ARY_NO_EMBED if (ARY_EMBED_P(ary)) { len = ARY_EMBED_LEN(ary); ptr = ary->as.ary; } - else { + else +#endif + { len = ary->as.heap.len; ptr = ary->as.heap.ptr; } @@ -1956,10 +1959,13 @@ RETRY_TRY_BLOCK: if (mrb_likely(tt == MRB_TT_ARRAY)) { struct RArray *ary = mrb_ary_ptr(recv); if (mrb_unlikely(ary->c != mrb->array_class)) goto getidx0_fallback; +#ifndef MRB_ARY_NO_EMBED if (ARY_EMBED_P(ary)) { regs[a] = ARY_EMBED_LEN(ary) > 0 ? ary->as.ary[0] : mrb_nil_value(); } - else { + else +#endif + { regs[a] = ary->as.heap.len > 0 ? ary->as.heap.ptr[0] : mrb_nil_value(); } NEXT;