Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion include/mruby/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct RArray {
#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
#define ARY_EMBED_PTR(a) ((mrb_value*)NULL)
#else
#define MRB_ARY_EMBED_MASK 7
#define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED_MASK)
Expand All @@ -71,6 +71,7 @@ struct RArray {
#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 RARRAY_GETMEM(a, ptr, len) ARY_GETMEM(RARRAY(a), ptr, len)
#define ARY_SET_LEN(a,n) do {\
if (ARY_EMBED_P(a)) {\
mrb_assert((n) <= MRB_ARY_EMBED_LEN_MAX); \
Expand All @@ -84,6 +85,17 @@ struct RArray {
#define ARY_SHARED_P(a) ((a)->flags & MRB_ARY_SHARED)
#define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED)
#define ARY_UNSET_SHARED_FLAG(a) ((a)->flags &= ~MRB_ARY_SHARED)
#define ARY_GETMEM(a, ptr, len) do { \
struct RArray *MRB_UNIQNAME(_a_) = (a); \
if (ARY_EMBED_P(MRB_UNIQNAME(_a_))) { \
(len) = ARY_EMBED_LEN(MRB_UNIQNAME(_a_)); \
(ptr) = ARY_EMBED_PTR(MRB_UNIQNAME(_a_)); \
} \
else { \
(len) = MRB_UNIQNAME(_a_)->as.heap.len; \
(ptr) = MRB_UNIQNAME(_a_)->as.heap.ptr; \
} \
} while (0)

MRB_API void mrb_ary_modify(mrb_state*, struct RArray*);
MRB_API mrb_value mrb_ary_dup(mrb_state*, mrb_value ary);
Expand Down
12 changes: 2 additions & 10 deletions src/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1895,15 +1895,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *begin_proc, const mrb_code *iseq
mrb_int len;
mrb_value *ptr;

/* Single ARY_EMBED_P check instead of two */
if (ARY_EMBED_P(ary)) {
len = ARY_EMBED_LEN(ary);
ptr = ary->as.ary;
}
else {
len = ary->as.heap.len;
ptr = ary->as.heap.ptr;
}
ARY_GETMEM(ary, ptr, len);

/* Unsigned comparison: handles negative idx as large positive */
if (mrb_likely((mrb_uint)idx < (mrb_uint)len)) {
Expand Down Expand Up @@ -1951,7 +1943,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *begin_proc, const mrb_code *iseq
struct RArray *ary = mrb_ary_ptr(recv);
if (mrb_unlikely(ary->c != mrb->array_class)) goto getidx0_fallback;
if (ARY_EMBED_P(ary)) {
regs[a] = ARY_EMBED_LEN(ary) > 0 ? ary->as.ary[0] : mrb_nil_value();
regs[a] = ARY_EMBED_LEN(ary) > 0 ? ARY_EMBED_PTR(ary)[0] : mrb_nil_value();
}
else {
regs[a] = ary->as.heap.len > 0 ? ary->as.heap.ptr[0] : mrb_nil_value();
Expand Down
Loading