diff options
| -rw-r--r-- | include/mruby/array.h | 21 | ||||
| -rw-r--r-- | src/array.c | 10 | ||||
| -rw-r--r-- | src/value_array.h | 1 | ||||
| -rw-r--r-- | src/vm.c | 2 |
4 files changed, 29 insertions, 5 deletions
diff --git a/include/mruby/array.h b/include/mruby/array.h index 08cacaa1f..5164efa69 100644 --- a/include/mruby/array.h +++ b/include/mruby/array.h @@ -21,7 +21,14 @@ typedef struct mrb_shared_array { mrb_value *ptr; } 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 { MRB_OBJECT_HEADER; union { @@ -33,7 +40,9 @@ struct RArray { } aux; mrb_value *ptr; } heap; +#ifndef MRB_ARY_NO_EMBED mrb_value ary[MRB_ARY_EMBED_LEN_MAX]; +#endif } as; }; @@ -41,13 +50,21 @@ struct RArray { #define mrb_ary_value(p) mrb_obj_value((void*)(p)) #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 ARY_EMBED_P(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_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) - +#endif + #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 RARRAY_LEN(a) ARY_LEN(RARRAY(a)) diff --git a/src/array.c b/src/array.c index f86743138..285600969 100644 --- a/src/array.c +++ b/src/array.c @@ -1123,8 +1123,14 @@ mrb_ary_clear(mrb_state *mrb, mrb_value self) else if (!ARY_EMBED_P(a)){ 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; } diff --git a/src/value_array.h b/src/value_array.h index bc5f28b06..6089b8aa0 100644 --- a/src/value_array.h +++ b/src/value_array.h @@ -6,6 +6,7 @@ static inline void value_move(mrb_value *s1, const mrb_value *s2, size_t n) { + if (n == 0) return; if (s1 > s2 && s1 < s2 + n) { s1 += n; @@ -1823,7 +1823,7 @@ RETRY_TRY_BLOCK: if (kd) regs[len + 1] = kdict; /* copy mandatory and optional arguments */ - if (argv0 != argv) { + if (argv0 != argv && argv) { value_move(®s[1], argv, argc-mlen); /* m1 + o */ } if (argc < m1) { |
