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 <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-02-25 10:02:21 +09:00
parent 8df9a22a85
commit 06bce53132
4 changed files with 12 additions and 6 deletions
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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");
+8 -2
View File
@@ -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;