summaryrefslogtreecommitdiff
path: root/internal/class.h
diff options
context:
space:
mode:
author卜部昌平 <shyouhei@ruby-lang.org>2019-11-29 15:18:34 +0900
committer卜部昌平 <shyouhei@ruby-lang.org>2019-12-26 20:45:12 +0900
commitb739a63eb41f52d33c33f87ebc44dcf89762cc37 (patch)
tree46e00221c40f90e47c9acca04905d9877a84cc10 /internal/class.h
parentba78bf9778082795bdb4735ccd7b692b5c3769f9 (diff)
split internal.h into files
One day, I could not resist the way it was written. I finally started to make the code clean. This changeset is the beginning of a series of housekeeping commits. It is a simple refactoring; split internal.h into files, so that we can divide and concur in the upcoming commits. No lines of codes are either added or removed, except the obvious file headers/footers. The generated binary is identical to the one before.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/2711
Diffstat (limited to 'internal/class.h')
-rw-r--r--internal/class.h143
1 files changed, 143 insertions, 0 deletions
diff --git a/internal/class.h b/internal/class.h
new file mode 100644
index 0000000000..8ba64a094b
--- /dev/null
+++ b/internal/class.h
@@ -0,0 +1,143 @@
+#ifndef INTERNAL_CLASS_H /* -*- C -*- */
+#define INTERNAL_CLASS_H
+/**
+ * @file
+ * @brief Internal header for Class.
+ * @author \@shyouhei
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+
+struct rb_deprecated_classext_struct {
+ char conflict[sizeof(VALUE) * 3];
+};
+
+struct rb_subclass_entry;
+typedef struct rb_subclass_entry rb_subclass_entry_t;
+
+struct rb_subclass_entry {
+ VALUE klass;
+ rb_subclass_entry_t *next;
+};
+
+struct rb_classext_struct {
+ struct st_table *iv_index_tbl;
+ struct st_table *iv_tbl;
+#if SIZEOF_SERIAL_T == SIZEOF_VALUE /* otherwise m_tbl is in struct RClass */
+ struct rb_id_table *m_tbl;
+#endif
+ struct rb_id_table *const_tbl;
+ struct rb_id_table *callable_m_tbl;
+ rb_subclass_entry_t *subclasses;
+ rb_subclass_entry_t **parent_subclasses;
+ /**
+ * In the case that this is an `ICLASS`, `module_subclasses` points to the link
+ * in the module's `subclasses` list that indicates that the klass has been
+ * included. Hopefully that makes sense.
+ */
+ rb_subclass_entry_t **module_subclasses;
+#if SIZEOF_SERIAL_T != SIZEOF_VALUE /* otherwise class_serial is in struct RClass */
+ rb_serial_t class_serial;
+#endif
+ const VALUE origin_;
+ const VALUE refined_class;
+ rb_alloc_func_t allocator;
+ const VALUE includer;
+};
+
+typedef struct rb_classext_struct rb_classext_t;
+
+#undef RClass
+struct RClass {
+ struct RBasic basic;
+ VALUE super;
+ rb_classext_t *ptr;
+#if SIZEOF_SERIAL_T == SIZEOF_VALUE
+ /* Class serial is as wide as VALUE. Place it here. */
+ rb_serial_t class_serial;
+#else
+ /* Class serial does not fit into struct RClass. Place m_tbl instead. */
+ struct rb_id_table *m_tbl;
+#endif
+};
+
+void rb_class_subclass_add(VALUE super, VALUE klass);
+void rb_class_remove_from_super_subclasses(VALUE);
+int rb_singleton_class_internal_p(VALUE sklass);
+/* class.c */
+VALUE rb_class_boot(VALUE);
+VALUE rb_class_inherited(VALUE, VALUE);
+VALUE rb_make_metaclass(VALUE, VALUE);
+VALUE rb_include_class_new(VALUE, VALUE);
+void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE);
+void rb_class_detach_subclasses(VALUE);
+void rb_class_detach_module_subclasses(VALUE);
+void rb_class_remove_from_module_subclasses(VALUE);
+VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj);
+VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj);
+VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj);
+VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj);
+VALUE rb_special_singleton_class(VALUE);
+VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
+VALUE rb_singleton_class_get(VALUE obj);
+
+int rb_class_has_methods(VALUE c);
+void rb_undef_methods_from(VALUE klass, VALUE super);
+
+#define RCLASS_EXT(c) (RCLASS(c)->ptr)
+#define RCLASS_IV_TBL(c) (RCLASS_EXT(c)->iv_tbl)
+#define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
+#if SIZEOF_SERIAL_T == SIZEOF_VALUE
+# define RCLASS_M_TBL(c) (RCLASS_EXT(c)->m_tbl)
+#else
+# define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
+#endif
+#define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
+#define RCLASS_IV_INDEX_TBL(c) (RCLASS_EXT(c)->iv_index_tbl)
+#define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_)
+#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
+#if SIZEOF_SERIAL_T == SIZEOF_VALUE
+# define RCLASS_SERIAL(c) (RCLASS(c)->class_serial)
+#else
+# define RCLASS_SERIAL(c) (RCLASS_EXT(c)->class_serial)
+#endif
+#define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
+
+#define RCLASS_CLONED FL_USER6
+#define RICLASS_IS_ORIGIN FL_USER5
+#define RCLASS_REFINED_BY_ANY FL_USER7
+
+static inline void
+RCLASS_SET_ORIGIN(VALUE klass, VALUE origin)
+{
+ RB_OBJ_WRITE(klass, &RCLASS_ORIGIN(klass), origin);
+ if (klass != origin) FL_SET(origin, RICLASS_IS_ORIGIN);
+}
+
+static inline void
+RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass)
+{
+ RB_OBJ_WRITE(iclass, &RCLASS_INCLUDER(iclass), klass);
+}
+
+#undef RCLASS_SUPER
+static inline VALUE
+RCLASS_SUPER(VALUE klass)
+{
+ return RCLASS(klass)->super;
+}
+
+static inline VALUE
+RCLASS_SET_SUPER(VALUE klass, VALUE super)
+{
+ if (super) {
+ rb_class_remove_from_super_subclasses(klass);
+ rb_class_subclass_add(super, klass);
+ }
+ RB_OBJ_WRITE(klass, &RCLASS(klass)->super, super);
+ return super;
+}
+
+#endif /* INTERNAL_CLASS_H */