mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
array.h: introduce ARY_GETMEM/RARRAY_GETMEM and type ARY_EMBED_PTR
Adds two API helpers that mirror CRuby's RSTRING_GETMEM idiom:
- ARY_GETMEM(a, ptr, len): inside-mruby helper that takes a
struct RArray* and assigns ptr/len from the embed or heap form.
- RARRAY_GETMEM(a, ptr, len): public wrapper on an mrb_value.
Both expand to a single ARY_EMBED_P check, with a uniqued local so
the array argument is evaluated only once (callers can safely pass
expressions with side effects).
Also type the ARY_NO_EMBED stub of ARY_EMBED_PTR as
((mrb_value*)NULL) instead of integer 0, so it composes cleanly in
pointer expressions like the new ARY_GETMEM.
The build-error issue this originated from (compilation with
MRB_ARY_NO_EMBED) was already fixed differently in master via
#ifndef guards (commit 78658d67e). These additions stand on their
own as new API for downstream gems.
Closes #6712, picked from PR by dearblue.
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
committed by
Yukihiro "Matz" Matsumoto
parent
91b60802db
commit
df74d57857
+13
-1
@@ -67,7 +67,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)
|
||||
@@ -81,6 +81,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); \
|
||||
@@ -94,6 +95,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);
|
||||
|
||||
Reference in New Issue
Block a user