summaryrefslogtreecommitdiff
path: root/internal/imemo.h
diff options
context:
space:
mode:
Diffstat (limited to 'internal/imemo.h')
-rw-r--r--internal/imemo.h54
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 */