diff options
Diffstat (limited to 'internal/imemo.h')
-rw-r--r-- | internal/imemo.h | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/internal/imemo.h b/internal/imemo.h index 305d12d240..0806baa9a6 100644 --- a/internal/imemo.h +++ b/internal/imemo.h @@ -42,6 +42,7 @@ enum imemo_type { imemo_callinfo = 11, imemo_callcache = 12, imemo_constcache = 13, + imemo_class_fields = 14, }; /* CREF (Class REFerence) is defined in method.h */ @@ -257,4 +258,57 @@ MEMO_V2_SET(struct MEMO *m, VALUE v) RB_OBJ_WRITE(m, &m->v2, v); } +struct rb_class_fields { + struct RBasic basic; + union { + struct { + VALUE fields[1]; + } embed; + struct { + VALUE *ptr; + } external; + struct { + // Note: the st_table could be embedded, but complex T_CLASS should be rare to + // non-existent, so not really worth the trouble. + st_table *table; + } complex; + } as; +}; + +#define OBJ_FIELD_EXTERNAL IMEMO_FL_USER0 +#define IMEMO_OBJ_FIELDS(fields) ((struct rb_class_fields *)fields) + +VALUE rb_imemo_class_fields_new(VALUE klass, size_t capa); +VALUE rb_imemo_class_fields_new_complex(VALUE klass, size_t capa); +VALUE rb_imemo_class_fields_clone(VALUE fields_obj); + +static inline VALUE * +rb_imemo_class_fields_ptr(VALUE obj_fields) +{ + if (!obj_fields) { + return NULL; + } + + RUBY_ASSERT(IMEMO_TYPE_P(obj_fields, imemo_class_fields)); + + if (RB_UNLIKELY(FL_TEST_RAW(obj_fields, OBJ_FIELD_EXTERNAL))) { + return IMEMO_OBJ_FIELDS(obj_fields)->as.external.ptr; + } + else { + return IMEMO_OBJ_FIELDS(obj_fields)->as.embed.fields; + } +} + +static inline st_table * +rb_imemo_class_fields_complex_tbl(VALUE obj_fields) +{ + if (!obj_fields) { + return NULL; + } + + RUBY_ASSERT(IMEMO_TYPE_P(obj_fields, imemo_class_fields)); + + return IMEMO_OBJ_FIELDS(obj_fields)->as.complex.table; +} + #endif /* INTERNAL_IMEMO_H */ |