34#include "internal/eval.h"
38#include "internal/variable.h"
42#define id_attached id__attached__
44#define METACLASS_OF(k) RBASIC(k)->klass
45#define SET_METACLASS_OF(k, cls) RBASIC_SET_CLASS(k, cls)
52 if (super && super !=
Qundef) {
69rb_module_add_to_subclasses_list(
VALUE module,
VALUE iclass)
74 entry->
klass = iclass;
111 entry = *
RCLASS_EXT(klass)->module_subclasses;
139class_detach_subclasses(
VALUE klass,
VALUE arg)
151class_detach_module_subclasses(
VALUE klass,
VALUE arg)
198RCLASS_M_TBL_INIT(
VALUE c)
217 RCLASS_SET_SUPER(klass, super);
218 RCLASS_M_TBL_INIT(klass);
233 if (!RB_TYPE_P(super,
T_CLASS)) {
279clone_method_i(
ID key,
VALUE value,
void *data)
361 if (RB_TYPE_P(clone,
T_CLASS)) {
362 class_init_copy_check(clone, orig);
377 copy_tables(clone, orig);
382 RCLASS_M_TBL_INIT(clone);
392 VALUE prev_clone_p = clone;
400 ensure_origin(clone);
403 while (p && p != orig_origin) {
405 rb_bug(
"non iclass between module/class and origin");
407 clone_p = class_alloc(
RBASIC(p)->flags,
RBASIC(p)->klass);
408 RCLASS_SET_SUPER(prev_clone_p, clone_p);
409 prev_clone_p = clone_p;
414 if (RB_TYPE_P(clone,
T_CLASS)) {
415 RCLASS_SET_INCLUDER(clone_p, clone);
423 else if ((origin_len =
RARRAY_LEN(origin_stack)) > 1 &&
425 RCLASS_SET_ORIGIN(
RARRAY_AREF(origin_stack, (origin_len -= 2)), clone_p);
426 RICLASS_SET_ORIGIN_SHARED_MTBL(clone_p);
428 add_subclass =
FALSE;
431 rb_module_add_to_subclasses_list(
RBASIC(p)->klass, clone_p);
436 if (p == orig_origin) {
438 RCLASS_SET_SUPER(clone_p, clone_origin);
439 RCLASS_SET_SUPER(clone_origin,
RCLASS_SUPER(orig_origin));
441 copy_tables(clone_origin, orig_origin);
446 RCLASS_M_TBL_INIT(clone_origin);
451 rb_bug(
"no origin for class that has origin");
480 bool klass_of_clone_is_new;
481 VALUE clone = class_alloc(
RBASIC(klass)->flags, 0);
484 klass_of_clone_is_new =
true;
485 RBASIC_SET_CLASS(clone, clone);
491 klass_of_clone_is_new = (
METACLASS_OF(klass) != klass_metaclass_clone);
492 RBASIC_SET_CLASS(clone, klass_metaclass_clone);
509 RCLASS_M_TBL_INIT(clone);
516 if (klass_of_clone_is_new) {
545#define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == (k))
548rb_singleton_class_has_metaclass_p(
VALUE sklass)
557 !rb_singleton_class_has_metaclass_p(sklass));
565#define HAVE_METACLASS_P(k) \
566 (FL_TEST(METACLASS_OF(k), FL_SINGLETON) && \
567 rb_singleton_class_has_metaclass_p(k))
576#define ENSURE_EIGENCLASS(klass) \
577 (HAVE_METACLASS_P(klass) ? METACLASS_OF(klass) : make_metaclass(klass))
590make_metaclass(
VALUE klass)
622make_singleton_class(
VALUE obj)
628 RBASIC_SET_CLASS(obj, klass);
637boot_defclass(
const char *
name,
VALUE super)
682 return make_metaclass(obj);
685 return make_singleton_class(obj);
727 return rb_funcall(super, inherited, 1, klass);
756 if (!RB_TYPE_P(klass,
T_CLASS)) {
826 if (!RB_TYPE_P(klass,
T_CLASS)) {
859 RCLASS_M_TBL_INIT(mdl);
929 RCLASS_SET_ORIGIN(klass, klass);
931 module =
RBASIC(module)->klass;
943 RCLASS_SET_SUPER(klass, super);
944 RBASIC_SET_CLASS(klass, module);
949static int include_modules_at(
const VALUE klass,
VALUE c,
VALUE module,
int search_super);
956 if (!
NIL_P(rb_refinement_module_get_refined_class(module))) {
966 ensure_includable(klass, module);
980 while (check_class) {
981 if (RB_TYPE_P(check_class,
T_ICLASS) &&
982 (
RBASIC(check_class)->klass == module)) {
993 iclass = iclass->
next;
999add_refined_method_entry_i(
ID key,
VALUE value,
void *data)
1006clear_module_cache_i(
ID id,
VALUE val,
void *data)
1014include_modules_at(
const VALUE klass,
VALUE c,
VALUE module,
int search_super)
1016 VALUE p, iclass, origin_stack = 0;
1017 int method_changed = 0, constant_changed = 0, add_subclass;
1020 VALUE original_klass = klass;
1023 int origin_seen =
FALSE;
1024 int superclass_seen =
FALSE;
1029 if (klass_m_tbl && klass_m_tbl ==
RCLASS_M_TBL(module))
1038 if (!superclass_seen && origin_seen) {
1045 if (!search_super)
break;
1046 superclass_seen =
TRUE;
1056 if (super_class && !RB_TYPE_P(super_class,
T_MODULE)) {
1061 if (!RB_TYPE_P(original_klass,
T_MODULE)) {
1070 c = RCLASS_SET_SUPER(c, iclass);
1071 RCLASS_SET_INCLUDER(iclass, klass);
1072 add_subclass =
TRUE;
1078 else if (origin_stack && (origin_len =
RARRAY_LEN(origin_stack)) > 1 &&
1079 RARRAY_AREF(origin_stack, origin_len - 1) == module) {
1080 RCLASS_SET_ORIGIN(
RARRAY_AREF(origin_stack, (origin_len -= 2)), iclass);
1081 RICLASS_SET_ORIGIN_SHARED_MTBL(iclass);
1083 add_subclass =
FALSE;
1089 if (add_subclass) rb_module_add_to_subclasses_list(m, iclass);
1093 VALUE refined_class =
1094 rb_refinement_module_get_refined_class(klass);
1108 return method_changed;
1112move_refined_method(
ID key,
VALUE value,
void *data)
1139cache_clear_refined_method(
ID key,
VALUE value,
void *data)
1154ensure_origin(
VALUE klass)
1160 RCLASS_SET_SUPER(klass,
origin);
1161 RCLASS_SET_ORIGIN(klass,
origin);
1163 RCLASS_M_TBL_INIT(klass);
1175 ensure_includable(klass, module);
1176 ensure_origin(klass);
1177 changed = include_modules_at(klass, klass, module,
FALSE);
1200 RICLASS_SET_ORIGIN_SHARED_MTBL(
origin);
1205 iclass = iclass->
next;
1331 ins_methods_push(
name, ary);
1341 ins_methods_push(
name, ary);
1350 ins_methods_push(
name, ary);
1359 ins_methods_push(
name, ary);
1370method_entry_i(
ID key,
VALUE value,
void *data)
1405 if (!
mod)
return false;
1425 add_instance_method_list(
mod, &me_arg);
1435 add_instance_method_list(
mod, &me_arg);
1476 return class_instance_method_list(
argc,
argv,
mod, 0, ins_methods_i);
1491 return class_instance_method_list(
argc,
argv,
mod, 0, ins_methods_prot_i);
1514 return class_instance_method_list(
argc,
argv,
mod, 0, ins_methods_priv_i);
1529 return class_instance_method_list(
argc,
argv,
mod, 0, ins_methods_pub_i);
1569 return class_instance_method_list(
argc,
argv,
CLASS_OF(obj), 1, ins_methods_i);
1584 return class_instance_method_list(
argc,
argv,
CLASS_OF(obj), 1, ins_methods_prot_i);
1599 return class_instance_method_list(
argc,
argv,
CLASS_OF(obj), 1, ins_methods_priv_i);
1614 return class_instance_method_list(
argc,
argv,
CLASS_OF(obj), 1, ins_methods_pub_i);
1740#ifdef rb_define_method_id
1741#undef rb_define_method_id
1749#ifdef rb_define_method
1750#undef rb_define_method
1758#ifdef rb_define_protected_method
1759#undef rb_define_protected_method
1767#ifdef rb_define_private_method
1768#undef rb_define_private_method
1808special_singleton_class_of(
VALUE obj)
1814 default:
return Qnil;
1821 return special_singleton_class_of(obj);
1834singleton_class_of(
VALUE obj)
1838 switch (
TYPE(obj)) {
1848 klass = special_singleton_class_of(obj);
1850 rb_bug(
"unknown immediate %p", (
void *)obj);
1859 klass =
RBASIC(obj)->klass;
1867 RB_FL_SET_RAW(klass, RB_OBJ_FROZEN_RAW(obj));
1900 klass =
RBASIC(obj)->klass;
1926 VALUE klass = singleton_class_of(obj);
1943#ifdef rb_define_singleton_method
1944#undef rb_define_singleton_method
1959#ifdef rb_define_module_function
1960#undef rb_define_module_function
1976#ifdef rb_define_global_function
1977#undef rb_define_global_function
2028 if (++i >=
len)
break;
2038rb_keyword_error(
const char *
error,
VALUE keys)
2043NORETURN(
static void unknown_keyword_error(
VALUE hash,
const ID *table,
int keywords));
2045unknown_keyword_error(
VALUE hash,
const ID *table,
int keywords)
2048 for (i = 0; i < keywords; i++) {
2069 VALUE parthash[2] = {0, 0};
2070 VALUE hash = *orighash;
2077 *orighash = parthash[1];
2092#define extract_kwarg(keyword, val) \
2093 (key = (st_data_t)(keyword), values ? \
2094 (rb_hash_stlike_delete(keyword_hash, &key, &(val)) || ((val) = Qundef, 0)) : \
2095 rb_hash_stlike_lookup(keyword_hash, key, NULL))
2097 if (
NIL_P(keyword_hash)) keyword_hash = 0;
2101 optional = -1-optional;
2104 for (; i < required; i++) {
2114 if (!
NIL_P(missing)) {
2115 rb_keyword_error(
"missing", missing);
2119 if (optional && keyword_hash) {
2120 for (i = 0; i < optional; i++) {
2126 if (!rest && keyword_hash) {
2127 if (
RHASH_SIZE(keyword_hash) > (
unsigned int)(values ? 0 : j)) {
2128 unknown_keyword_error(keyword_hash, table, required+optional);
2131 if (values && !keyword_hash) {
2132 for (i = 0; i < required + optional; i++) {
2151rb_scan_args_parse(
int kw_flag,
const char *fmt,
struct rb_scan_args_t *arg)
2153 const char *p = fmt;
2155 memset(arg, 0,
sizeof(*arg));
2162 arg->
n_opt = *p -
'0';
2183 rb_fatal(
"bad scan arg format: %s", fmt);
2192#define rb_scan_args_next_param() va_arg(vargs, VALUE *)
2193 const int kw_flag = arg->
kw_flag;
2194 const int n_lead = arg->
n_lead;
2195 const int n_opt = arg->
n_opt;
2196 const int n_trail = arg->
n_trail;
2197 const int n_mand = n_lead + n_trail;
2198 const bool f_var = arg->
f_var;
2199 const bool f_hash = arg->
f_hash;
2200 const bool f_block = arg->
f_block;
2203 if (f_hash &&
argc > 0) {
2205 if (rb_scan_args_keyword_p(kw_flag,
last)) {
2211 if (
argc < n_mand) {
2216 for (i = 0; i < n_lead; i++) {
2218 if (var) *var =
argv[argi];
2222 for (i = 0; i < n_opt; i++) {
2224 if (argi <
argc - n_trail) {
2225 if (var) *var =
argv[argi];
2229 if (var) *var =
Qnil;
2234 int n_var =
argc - argi - n_trail;
2246 for (i = 0; i < n_trail; i++) {
2248 if (var) *var =
argv[argi];
2254 if (var) *var = hash;
2273#undef rb_scan_args_next_param
2279 const int n_lead = arg->
n_lead;
2280 const int n_opt = arg->
n_opt;
2281 const int n_trail = arg->
n_trail;
2282 const int n_mand = n_lead + n_trail;
2283 const bool f_var = arg->
f_var;
2301 va_start(vargs,fmt);
2304 return rb_scan_args_result(&arg,
argc);
2307#undef rb_scan_args_kw
2313 rb_scan_args_parse(
kw_flag, fmt, &arg);
2314 va_start(vargs,fmt);
2317 return rb_scan_args_result(&arg,
argc);
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_ary_resize(VALUE ary, long len)
expands or shrinks ary to len elements.
VALUE rb_ary_tmp_new(long capa)
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
#define RUBY_ASSERT(expr)
Asserts that the given expression is truthy iff RUBY_DEBUG is truthy.
#define UNREACHABLE_RETURN
#define rb_scan_args_next_param()
#define extract_kwarg(keyword, val)
void rb_free_const_table(struct rb_id_table *tbl)
Our own, locale independent, character handling routines.
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_method_id(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
#define rb_define_protected_method(klass, mid, func, arity)
Defines klass#mid and makes it protected.
#define rb_define_module_function(klass, mid, func, arity)
Defines klass#mid and makes it a module function.
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
#define rb_define_global_function(mid, func, arity)
Defines rb_mKernel #mid.
#define MJIT_FUNC_EXPORTED
int rb_objspace_garbage_object_p(VALUE obj)
void rb_gc_register_mark_object(VALUE obj)
Inform the garbage collector that object is a live Ruby object that should not be moved.
VALUE rb_class_protected_instance_methods(int argc, const VALUE *argv, VALUE mod)
#define SET_METACLASS_OF(k, cls)
void rb_class_foreach_subclass(VALUE klass, void(*f)(VALUE, VALUE), VALUE arg)
void rb_include_module(VALUE klass, VALUE module)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
VALUE rb_class_new(VALUE super)
Creates a new class.
VALUE rb_singleton_class_clone(VALUE obj)
VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj)
void rb_class_subclass_add(VALUE super, VALUE klass)
VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj)
void rb_prepend_module(VALUE klass, VALUE module)
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
void rb_class_detach_subclasses(VALUE klass)
void Init_class_hierarchy(void)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
VALUE rb_include_class_new(VALUE module, VALUE super)
VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj)
VALUE rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
VALUE rb_module_new(void)
#define META_CLASS_OF_CLASS_CLASS_P(k)
whether k is a meta^(n)-class of Class class
int rb_singleton_class_internal_p(VALUE sklass)
VALUE rb_class_instance_methods(int argc, const VALUE *argv, VALUE mod)
void rb_check_inheritable(VALUE super)
Ensures a class can be derived from super.
VALUE rb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod)
VALUE rb_class_boot(VALUE super)
A utility function that wraps class_alloc.
VALUE rb_define_module(const char *name)
void rb_class_modify_check(VALUE klass)
Asserts that klass is not a frozen class.
void rb_class_detach_module_subclasses(VALUE klass)
VALUE rb_special_singleton_class(VALUE obj)
VALUE rb_define_module_id_under(VALUE outer, ID id)
void rb_singleton_class_attached(VALUE klass, VALUE obj)
Attach a object to a singleton class.
void rb_freeze_singleton_class(VALUE x)
VALUE rb_mod_included_modules(VALUE mod)
VALUE rb_define_class_id_under(VALUE outer, ID id, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_mod_ancestors(VALUE mod)
VALUE rb_class_inherited(VALUE super, VALUE klass)
Calls Class::inherited.
VALUE rb_mod_include_p(VALUE mod, VALUE mod2)
VALUE rb_class_private_instance_methods(int argc, const VALUE *argv, VALUE mod)
#define ENSURE_EIGENCLASS(klass)
ensures klass belongs to its own eigenclass.
void rb_class_remove_from_module_subclasses(VALUE klass)
VALUE rb_mod_init_copy(VALUE clone, VALUE orig)
VALUE rb_define_module_under(VALUE outer, const char *name)
VALUE rb_singleton_class_get(VALUE obj)
Returns the singleton class of obj, or nil if obj is not a singleton object.
VALUE rb_make_metaclass(VALUE obj, VALUE unused)
VALUE rb_define_module_id(ID id)
VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj)
VALUE rb_define_class_id(ID id, VALUE super)
Defines a new class.
void rb_class_remove_from_super_subclasses(VALUE klass)
VALUE rb_extract_keywords(VALUE *orighash)
int rb_class_has_methods(VALUE c)
void rb_define_attr(VALUE klass, const char *name, int read, int write)
Defines (a) public accessor method(s) for an attribute.
VALUE rb_keyword_error_new(const char *error, VALUE keys)
void rb_undef_method(VALUE klass, const char *name)
int rb_scan_args_kw(int kw_flag, int argc, const VALUE *argv, const char *fmt,...)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
void rb_undef_methods_from(VALUE klass, VALUE super)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
int rb_block_given_p(void)
Determines if the current method is given a block.
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
void rb_raise(VALUE exc, const char *fmt,...)
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
void rb_bug(const char *fmt,...)
void rb_fatal(const char *fmt,...)
VALUE rb_exc_new_str(VALUE etype, VALUE str)
VALUE rb_cClass
Class class.
VALUE rb_mKernel
Kernel module.
VALUE rb_cObject
Object class.
VALUE rb_cNilClass
NilClass class.
VALUE rb_cFalseClass
FalseClass class.
VALUE rb_obj_class(VALUE)
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_cBasicObject
BasicObject class.
VALUE rb_cModule
Module class.
VALUE rb_class_real(VALUE)
Looks up the nearest ancestor of cl, skipping singleton classes or module inclusions.
VALUE rb_cTrueClass
TrueClass class.
void skip(file *in, unsigned n)
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval)
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
VALUE rb_hash_keys(VALUE hash)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
VALUE rb_hash_dup(VALUE hash)
int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val)
size_t rb_id_table_size(const struct rb_id_table *tbl)
struct rb_id_table * rb_id_table_create(size_t capa)
void rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data)
rb_id_table_iterator_result
Thin wrapper to ruby/config.h.
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
#define UNLIMITED_ARGUMENTS
void rb_error_arity(int, int, int)
#define OBJ_INIT_COPY(obj, orig)
VALUE rb_block_proc(void)
VALUE rb_str_append(VALUE, VALUE)
#define rb_str_cat_cstr(buf, str)
void rb_set_class_path_string(VALUE, VALUE, VALUE)
VALUE rb_const_get(VALUE, ID)
int rb_const_defined_at(VALUE, ID)
VALUE rb_class_path(VALUE)
VALUE rb_const_get_at(VALUE, ID)
void rb_const_set(VALUE, ID, VALUE)
VALUE rb_attr_get(VALUE, ID)
int rb_const_defined(VALUE, ID)
void rb_attr(VALUE, ID, int, int, int)
void rb_clear_constant_cache(void)
void rb_alias(VALUE, ID, ID)
ID rb_intern(const char *)
Internal header for Class.
#define RCLASS_INCLUDER(c)
#define RCLASS_CONST_TBL(c)
#define RCLASS_REFINED_CLASS(c)
#define RICLASS_IS_ORIGIN
Internal header for Hash.
Internal header for Object.
Internal header for String.
#define rb_fstring_lit(str)
void rb_iv_tbl_copy(VALUE dst, VALUE src)
int rb_class_ivar_set(VALUE klass, ID vid, VALUE value)
int rb_vm_add_root_module(VALUE module)
void rb_vm_check_redefinition_by_prepend(VALUE klass)
rb_serial_t rb_next_class_serial(void)
#define MEMCPY(p1, p2, type, n)
const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *me)
void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi)
const rb_method_entry_t * rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me)
void rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi)
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src)
void rb_add_refined_method_entry(VALUE refined_class, ID mid)
void rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me)
rb_method_entry_t * rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_visibility_t noex)
@ VM_METHOD_TYPE_ISEQ
Ruby method.
@ VM_METHOD_TYPE_REFINED
refinement
void rb_clear_method_cache(VALUE klass_or_module, ID mid)
#define UNDEFINED_METHOD_ENTRY_P(me)
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE(*func)(ANYARGS), int argc, rb_method_visibility_t visi)
#define METHOD_ENTRY_VISI(me)
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define RARRAY_AREF(a, i)
#define RMODULE_INCLUDED_INTO_REFINEMENT
#define RMODULE_IS_REFINEMENT
#define RB_OBJ_WRITE(a, slot, b)
WB for new reference from ‘a’ to ‘b’.
#define RGENGC_WB_PROTECTED_CLASS
#define RB_OBJ_WRITTEN(a, oldv, b)
WB for new reference from ‘a’ to ‘b’.
#define RB_SCAN_ARGS_PASS_CALLED_KEYWORDS
unsigned LONG_LONG rb_serial_t
VALUE rb_sprintf(const char *,...)
#define st_is_member(table, key)
union rb_method_definition_struct::@123 body
rb_method_refined_t refined
struct rb_method_definition_struct *const def
rb_cref_t * cref
class reference, should be marked
rb_iseq_t * iseqptr
iseq pointer, should be separated from iseqval
struct rb_method_entry_struct * orig_me
struct rb_subclass_entry * next
void error(const char *msg)
void rb_vm_rewrite_cref(rb_cref_t *node, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr)
int write(ozstream &zs, const T *x, Items items)
int read(izstream &zs, T *x, Items items)
#define ZALLOC(strm, items, size)