diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/mruby/array.h | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/include/mruby/array.h b/include/mruby/array.h index e553faf92..bd3124d8c 100644 --- a/include/mruby/array.h +++ b/include/mruby/array.h @@ -21,22 +21,48 @@ 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))) struct RArray { MRB_OBJECT_HEADER; - mrb_int len; union { - mrb_int capa; - mrb_shared_array *shared; - } aux; - mrb_value *ptr; + struct { + mrb_int len; + union { + mrb_int capa; + mrb_shared_array *shared; + } aux; + mrb_value *ptr; + } heap; + mrb_value embed[MRB_ARY_EMBED_LEN_MAX]; + } as; }; #define mrb_ary_ptr(v) ((struct RArray*)(mrb_ptr(v))) #define mrb_ary_value(p) mrb_obj_value((void*)(p)) #define RARRAY(v) ((struct RArray*)(mrb_ptr(v))) -#define RARRAY_LEN(a) (RARRAY(a)->len) -#define RARRAY_PTR(a) ((const mrb_value*)RARRAY(a)->ptr) +#define MRB_ARY_EMBED 4 +#define MRB_ARY_EMBED_MASK 3 +#define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED) +#define ARY_SET_EMBED_FLAG(a) ((a)->flags |= MRB_ARY_EMBED) +#define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED|MRB_ARY_EMBED_MASK)) +#define ARY_EMBED_LEN(a) ((a)->flags & MRB_ARY_EMBED_MASK) +#define ARY_SET_EMBED_LEN(a,len) (a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((len)&MRB_ARY_EMBED_MASK); +#define ARY_EMBED_PTR(a) (&((a)->as.embed[0])) + +#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)) +#define RARRAY_PTR(a) ARY_PTR(RARRAY(a)) +#define ARY_SET_LEN(a,n) do {\ + if (ARY_EMBED_P(a)) {\ + mrb_assert((n) <= MRB_ARY_EMBED_LEN_MAX); \ + ARY_SET_EMBED_LEN(a,n);\ + }\ + else\ + (a)->as.heap.len = (n);\ +} while (0) +#define ARY_CAPA(a) (ARY_EMBED_P(a)?MRB_ARY_EMBED_LEN_MAX:(a)->as.heap.aux.capa) #define MRB_ARY_SHARED 256 #define ARY_SHARED_P(a) ((a)->flags & MRB_ARY_SHARED) #define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED) |
