Skip array embedding if `MRB_NO_BOXING` and `MRB_32BIT`; fix #4382

On some platforms, `sizeof(mrb_value) > sizeof(void*)*3`, which makes
`MRB_ARY_EMBED_LEN_MAX` zero. And zero sized array cause compile errors.
parent a93ef815
...@@ -21,7 +21,14 @@ typedef struct mrb_shared_array { ...@@ -21,7 +21,14 @@ typedef struct mrb_shared_array {
mrb_value *ptr; mrb_value *ptr;
} mrb_shared_array; } mrb_shared_array;
#define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value))) #if defined(MRB_32BIT) && defined(MRB_NO_BOXING)
# define MRB_ARY_NO_EMBED
# define MRB_ARY_EMBED_LEN_MAX 0
#else
# define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value)))
mrb_static_assert(MRB_ARY_EMBED_LEN_MAX > 0, "MRB_ARY_EMBED_LEN_MAX > 0");
#endif
struct RArray { struct RArray {
MRB_OBJECT_HEADER; MRB_OBJECT_HEADER;
union { union {
...@@ -33,7 +40,9 @@ struct RArray { ...@@ -33,7 +40,9 @@ struct RArray {
} aux; } aux;
mrb_value *ptr; mrb_value *ptr;
} heap; } heap;
#ifndef MRB_ARY_NO_EMBED
mrb_value ary[MRB_ARY_EMBED_LEN_MAX]; mrb_value ary[MRB_ARY_EMBED_LEN_MAX];
#endif
} as; } as;
}; };
...@@ -41,13 +50,21 @@ struct RArray { ...@@ -41,13 +50,21 @@ struct RArray {
#define mrb_ary_value(p) mrb_obj_value((void*)(p)) #define mrb_ary_value(p) mrb_obj_value((void*)(p))
#define RARRAY(v) ((struct RArray*)(mrb_ptr(v))) #define RARRAY(v) ((struct RArray*)(mrb_ptr(v)))
#ifdef MRB_ARY_NO_EMBED
#define ARY_EMBED_P(a) 0
#define ARY_UNSET_EMBED_FLAG(a) (void)0
#define ARY_EMBED_LEN(a) 0
#define ARY_SET_EMBED_LEN(a,len) (void)0
#define ARY_EMBED_PTR(a) 0
#else
#define MRB_ARY_EMBED_MASK 7 #define MRB_ARY_EMBED_MASK 7
#define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED_MASK) #define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED_MASK)
#define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED_MASK)) #define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED_MASK))
#define ARY_EMBED_LEN(a) ((mrb_int)(((a)->flags & MRB_ARY_EMBED_MASK) - 1)) #define ARY_EMBED_LEN(a) ((mrb_int)(((a)->flags & MRB_ARY_EMBED_MASK) - 1))
#define ARY_SET_EMBED_LEN(a,len) ((a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((uint32_t)(len) + 1)) #define ARY_SET_EMBED_LEN(a,len) ((a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((uint32_t)(len) + 1))
#define ARY_EMBED_PTR(a) ((a)->as.ary) #define ARY_EMBED_PTR(a) ((a)->as.ary)
#endif
#define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len) #define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len)
#define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr) #define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr)
#define RARRAY_LEN(a) ARY_LEN(RARRAY(a)) #define RARRAY_LEN(a) ARY_LEN(RARRAY(a))
......
...@@ -1123,8 +1123,14 @@ mrb_ary_clear(mrb_state *mrb, mrb_value self) ...@@ -1123,8 +1123,14 @@ mrb_ary_clear(mrb_state *mrb, mrb_value self)
else if (!ARY_EMBED_P(a)){ else if (!ARY_EMBED_P(a)){
mrb_free(mrb, a->as.heap.ptr); mrb_free(mrb, a->as.heap.ptr);
} }
ARY_SET_EMBED_LEN(a, 0); if (MRB_ARY_EMBED_LEN_MAX > 0) {
ARY_SET_EMBED_LEN(a, 0);
}
else {
a->as.heap.ptr = NULL;
a->as.heap.aux.capa = 0;
ARY_SET_LEN(a, 0);
}
return self; return self;
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
static inline void static inline void
value_move(mrb_value *s1, const mrb_value *s2, size_t n) value_move(mrb_value *s1, const mrb_value *s2, size_t n)
{ {
if (n == 0) return;
if (s1 > s2 && s1 < s2 + n) if (s1 > s2 && s1 < s2 + n)
{ {
s1 += n; s1 += n;
......
...@@ -1823,7 +1823,7 @@ RETRY_TRY_BLOCK: ...@@ -1823,7 +1823,7 @@ RETRY_TRY_BLOCK:
if (kd) regs[len + 1] = kdict; if (kd) regs[len + 1] = kdict;
/* copy mandatory and optional arguments */ /* copy mandatory and optional arguments */
if (argv0 != argv) { if (argv0 != argv && argv) {
value_move(&regs[1], argv, argc-mlen); /* m1 + o */ value_move(&regs[1], argv, argc-mlen); /* m1 + o */
} }
if (argc < m1) { if (argc < m1) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment