summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSatoshi Tagomori <[email protected]>2025-04-30 13:48:02 +0900
committerSatoshi Tagomori <[email protected]>2025-05-11 23:32:50 +0900
commit382645d440d5da66a0c04557f3ff2ca226de3a27 ()
treeb7453449930197237e739d0985561b664f51b0f3
parent49742414f6444960838bb968bab43db27f5872c1 (diff)
namespace on read
-rw-r--r--builtin.c22
-rw-r--r--class.c1191
-rw-r--r--common.mk255
-rw-r--r--dln.c41
-rw-r--r--dln.h1
-rw-r--r--dmydln.c9
-rw-r--r--eval.c80
-rw-r--r--eval_intern.h1
-rw-r--r--ext/-test-/namespace/yay1/extconf.rb1
-rw-r--r--ext/-test-/namespace/yay1/yay1.c28
-rw-r--r--ext/-test-/namespace/yay1/yay1.def4
-rw-r--r--ext/-test-/namespace/yay1/yay1.h4
-rw-r--r--ext/-test-/namespace/yay2/extconf.rb1
-rw-r--r--ext/-test-/namespace/yay2/yay2.c28
-rw-r--r--ext/-test-/namespace/yay2/yay2.def4
-rw-r--r--ext/-test-/namespace/yay2/yay2.h4
-rw-r--r--ext/coverage/depend1
-rw-r--r--ext/objspace/depend3
-rw-r--r--ext/objspace/objspace.c2
-rw-r--r--ext/objspace/objspace_dump.c4
-rw-r--r--ext/ripper/depend1
-rw-r--r--ext/socket/depend15
-rw-r--r--gc.c527
-rw-r--r--imemo.c19
-rw-r--r--include/ruby/internal/globals.h2
-rw-r--r--inits.c1
-rw-r--r--internal/class.h646
-rw-r--r--internal/eval.h7
-rw-r--r--internal/imemo.h3
-rw-r--r--internal/load.h2
-rw-r--r--internal/namespace.h80
-rw-r--r--internal/variable.h2
-rw-r--r--internal/vm.h1
-rw-r--r--iseq.c2
-rw-r--r--lib/rubygems/package.rb2
-rw-r--r--lib/rubygems/safe_yaml.rb2
-rw-r--r--load.c446
-rw-r--r--marshal.c2
-rw-r--r--method.h3
-rw-r--r--mini_builtin.c19
-rw-r--r--namespace.c1139
-rw-r--r--object.c21
-rw-r--r--proc.c20
-rw-r--r--ruby.c3
-rw-r--r--shape.c12
-rw-r--r--spec/ruby/core/module/ancestors_spec.rb15
-rw-r--r--test/-ext-/namespace/test_load_ext.rb97
-rw-r--r--test/-ext-/test_abi.rb12
-rw-r--r--test/ruby/namespace/a.1_1_0.rb17
-rw-r--r--test/ruby/namespace/a.1_2_0.rb17
-rw-r--r--test/ruby/namespace/a.rb15
-rw-r--r--test/ruby/namespace/autoloading.rb8
-rw-r--r--test/ruby/namespace/blank.rb2
-rw-r--r--test/ruby/namespace/blank1.rb2
-rw-r--r--test/ruby/namespace/blank2.rb2
-rw-r--r--test/ruby/namespace/call_proc.rb5
-rw-r--r--test/ruby/namespace/call_toplevel.rb8
-rw-r--r--test/ruby/namespace/consts.rb147
-rw-r--r--test/ruby/namespace/current.rb13
-rw-r--r--test/ruby/namespace/define_toplevel.rb5
-rw-r--r--test/ruby/namespace/global_vars.rb37
-rw-r--r--test/ruby/namespace/line_splitter.rb9
-rw-r--r--test/ruby/namespace/load_path.rb26
-rw-r--r--test/ruby/namespace/ns.rb10
-rw-r--r--test/ruby/namespace/open_class_with_include.rb31
-rw-r--r--test/ruby/namespace/proc_callee.rb14
-rw-r--r--test/ruby/namespace/proc_caller.rb5
-rw-r--r--test/ruby/namespace/procs.rb64
-rw-r--r--test/ruby/namespace/raise.rb3
-rw-r--r--test/ruby/namespace/returns_proc.rb12
-rw-r--r--test/ruby/namespace/singleton_methods.rb65
-rw-r--r--test/ruby/namespace/string_ext.rb13
-rw-r--r--test/ruby/namespace/string_ext_caller.rb5
-rw-r--r--test/ruby/namespace/string_ext_calling.rb1
-rw-r--r--test/ruby/namespace/string_ext_eval_caller.rb12
-rw-r--r--test/ruby/namespace/top_level.rb33
-rw-r--r--test/ruby/test_autoload.rb18
-rw-r--r--test/ruby/test_namespace.rb516
-rw-r--r--test/ruby/test_rubyoptions.rb2
-rw-r--r--variable.c263
-rw-r--r--vm.c63
-rw-r--r--vm_callinfo.h7
-rw-r--r--vm_core.h24
-rw-r--r--vm_eval.c29
-rw-r--r--vm_insnhelper.c45
-rw-r--r--vm_method.c197
86 files changed, 5839 insertions, 691 deletions
@@ -32,8 +32,8 @@ builtin_lookup(const char *feature, size_t *psize)
return bin;
}
-void
-rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table)
{
// search binary
size_t size;
@@ -50,8 +50,22 @@ rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin
ASSUME(iseq); // otherwise an exception should have raised
vm->builtin_function_table = NULL;
// exec
- rb_iseq_eval(rb_iseq_check(iseq));
}
#endif
@@ -71,5 +85,5 @@ Init_builtin(void)
void
Init_builtin_features(void)
{
- rb_load_with_builtin_functions("gem_prelude", NULL);
}
@@ -24,6 +24,7 @@
#include "internal/class.h"
#include "internal/eval.h"
#include "internal/hash.h"
#include "internal/object.h"
#include "internal/string.h"
#include "internal/variable.h"
@@ -38,9 +39,7 @@
* This is done for classes defined from C to allow storing them in global variables.
* 1: RUBY_FL_SINGLETON
* This class is a singleton class.
- * 2: RCLASS_SUPERCLASSES_INCLUDE_SELF
- * The RCLASS_SUPERCLASSES contains the class as the last element.
- * This means that this class owns the RCLASS_SUPERCLASSES list.
* if !SHAPE_IN_BASIC_FLAGS
* 4-19: SHAPE_FLAG_MASK
* Shape ID for the class.
@@ -49,8 +48,8 @@
/* Flags of T_ICLASS
*
- * 0: RICLASS_IS_ORIGIN
- * 3: RICLASS_ORIGIN_SHARED_MTBL
* The T_ICLASS does not own the method table.
* if !SHAPE_IN_BASIC_FLAGS
* 4-19: SHAPE_FLAG_MASK
@@ -65,8 +64,7 @@
* This is done for classes defined from C to allow storing them in global variables.
* 1: RMODULE_ALLOCATED_BUT_NOT_INITIALIZED
* Module has not been initialized.
- * 2: RCLASS_SUPERCLASSES_INCLUDE_SELF
- * See RCLASS_SUPERCLASSES_INCLUDE_SELF in T_CLASS.
* 3: RMODULE_IS_REFINEMENT
* Module is used for refinements.
* if !SHAPE_IN_BASIC_FLAGS
@@ -80,124 +78,996 @@
RUBY_EXTERN rb_serial_t ruby_vm_global_cvar_state;
-static rb_subclass_entry_t *
-push_subclass_entry_to_list(VALUE super, VALUE klass)
{
- rb_subclass_entry_t *entry = ZALLOC(rb_subclass_entry_t);
entry->klass = klass;
RB_VM_LOCK_ENTER();
{
- rb_subclass_entry_t *head = RCLASS_SUBCLASSES(super);
- if (!head) {
- head = ZALLOC(rb_subclass_entry_t);
- RCLASS_SUBCLASSES(super) = head;
- }
- entry->next = head->next;
- entry->prev = head;
-
if (head->next) {
head->next->prev = entry;
}
head->next = entry;
}
RB_VM_LOCK_LEAVE();
- return entry;
}
void
rb_class_subclass_add(VALUE super, VALUE klass)
{
if (super && !UNDEF_P(super)) {
- rb_subclass_entry_t *entry = push_subclass_entry_to_list(super, klass);
- RCLASS_SUBCLASS_ENTRY(klass) = entry;
}
}
static void
rb_module_add_to_subclasses_list(VALUE module, VALUE iclass)
{
- rb_subclass_entry_t *entry = push_subclass_entry_to_list(module, iclass);
- RCLASS_MODULE_SUBCLASS_ENTRY(iclass) = entry;
}
void
-rb_class_remove_subclass_head(VALUE klass)
{
- rb_subclass_entry_t *head = RCLASS_SUBCLASSES(klass);
- if (head) {
- if (head->next) {
- head->next->prev = NULL;
- }
- RCLASS_SUBCLASSES(klass) = NULL;
- xfree(head);
}
}
-void
-rb_class_remove_from_super_subclasses(VALUE klass)
{
- rb_subclass_entry_t *entry = RCLASS_SUBCLASS_ENTRY(klass);
- if (entry) {
- rb_subclass_entry_t *prev = entry->prev, *next = entry->next;
- if (prev) {
- prev->next = next;
- }
- if (next) {
- next->prev = prev;
- }
- xfree(entry);
}
- RCLASS_SUBCLASS_ENTRY(klass) = NULL;
}
void
rb_class_remove_from_module_subclasses(VALUE klass)
{
- rb_subclass_entry_t *entry = RCLASS_MODULE_SUBCLASS_ENTRY(klass);
- if (entry) {
- rb_subclass_entry_t *prev = entry->prev, *next = entry->next;
- if (prev) {
- prev->next = next;
- }
- if (next) {
- next->prev = prev;
- }
xfree(entry);
}
- RCLASS_MODULE_SUBCLASS_ENTRY(klass) = NULL;
}
void
rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE arg)
{
- // RCLASS_SUBCLASSES should always point to our head element which has NULL klass
- rb_subclass_entry_t *cur = RCLASS_SUBCLASSES(klass);
- // if we have a subclasses list, then the head is a placeholder with no valid
- // class. So ignore it and use the next element in the list (if one exists)
- if (cur) {
- RUBY_ASSERT(!cur->klass);
- cur = cur->next;
- }
-
/* do not be tempted to simplify this loop into a for loop, the order of
operations is important here if `f` modifies the linked list */
while (cur) {
VALUE curklass = cur->klass;
- cur = cur->next;
// do not trigger GC during f, otherwise the cur will become
// a dangling pointer if the subclass is collected
f(curklass, arg);
}
}
@@ -225,6 +1095,13 @@ rb_class_detach_module_subclasses(VALUE klass)
rb_class_foreach_subclass(klass, class_detach_module_subclasses, Qnil);
}
/**
* Allocates a struct RClass for a new class.
*
@@ -240,6 +1117,9 @@ rb_class_detach_module_subclasses(VALUE klass)
static VALUE
class_alloc(VALUE flags, VALUE klass)
{
size_t alloc_size = sizeof(struct RClass) + sizeof(rb_classext_t);
flags &= T_MASK;
@@ -253,21 +1133,61 @@ class_alloc(VALUE flags, VALUE klass)
RCLASS_M_TBL(obj) = 0;
RCLASS_FIELDS(obj) = 0;
RCLASS_SET_SUPER((VALUE)obj, 0);
- RCLASS_SUBCLASSES(obj) = NULL;
- RCLASS_PARENT_SUBCLASSES(obj) = NULL;
- RCLASS_MODULE_SUBCLASSES(obj) = NULL;
*/
RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj);
- RB_OBJ_WRITE(obj, &RCLASS_REFINED_CLASS(obj), Qnil);
RCLASS_SET_ALLOCATOR((VALUE)obj, 0);
return (VALUE)obj;
}
static void
-RCLASS_M_TBL_INIT(VALUE c)
{
- RCLASS_M_TBL(c) = rb_id_table_create(0);
}
/**
@@ -284,8 +1204,8 @@ rb_class_boot(VALUE super)
{
VALUE klass = class_alloc(T_CLASS, rb_cClass);
- RCLASS_SET_SUPER(klass, super);
- RCLASS_M_TBL_INIT(klass);
return (VALUE)klass;
}
@@ -293,7 +1213,7 @@ rb_class_boot(VALUE super)
static VALUE *
class_superclasses_including_self(VALUE klass)
{
- if (FL_TEST_RAW(klass, RCLASS_SUPERCLASSES_INCLUDE_SELF))
return RCLASS_SUPERCLASSES(klass);
size_t depth = RCLASS_SUPERCLASS_DEPTH(klass);
@@ -302,14 +1222,14 @@ class_superclasses_including_self(VALUE klass)
memcpy(superclasses, RCLASS_SUPERCLASSES(klass), sizeof(VALUE) * depth);
superclasses[depth] = klass;
- RCLASS_SUPERCLASSES(klass) = superclasses;
- FL_SET_RAW(klass, RCLASS_SUPERCLASSES_INCLUDE_SELF);
return superclasses;
}
void
rb_class_update_superclasses(VALUE klass)
{
VALUE super = RCLASS_SUPER(klass);
if (!RB_TYPE_P(klass, T_CLASS)) return;
@@ -338,8 +1258,14 @@ rb_class_update_superclasses(VALUE klass)
return;
}
- RCLASS_SUPERCLASSES(klass) = class_superclasses_including_self(super);
- RCLASS_SUPERCLASS_DEPTH(klass) = RCLASS_SUPERCLASS_DEPTH(super) + 1;
}
void
@@ -365,7 +1291,7 @@ rb_class_new(VALUE super)
VALUE klass = rb_class_boot(super);
if (super != rb_cObject && super != rb_cBasicObject) {
- RCLASS_EXT(klass)->max_iv_count = RCLASS_EXT(super)->max_iv_count;
}
return klass;
@@ -470,7 +1396,7 @@ copy_tables(VALUE clone, VALUE orig)
{
if (RCLASS_CONST_TBL(clone)) {
rb_free_const_table(RCLASS_CONST_TBL(clone));
- RCLASS_CONST_TBL(clone) = 0;
}
if (RCLASS_CVC_TBL(orig)) {
struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(orig);
@@ -480,10 +1406,10 @@ copy_tables(VALUE clone, VALUE orig)
ctx.clone = clone;
ctx.new_table = rb_cvc_tbl_dup;
rb_id_table_foreach(rb_cvc_tbl, cvc_table_copy, &ctx);
- RCLASS_CVC_TBL(clone) = rb_cvc_tbl_dup;
}
rb_id_table_free(RCLASS_M_TBL(clone));
- RCLASS_M_TBL(clone) = 0;
if (!RB_TYPE_P(clone, T_ICLASS)) {
st_data_t id;
@@ -495,10 +1421,11 @@ copy_tables(VALUE clone, VALUE orig)
}
if (RCLASS_CONST_TBL(orig)) {
struct clone_const_arg arg;
-
- arg.tbl = RCLASS_CONST_TBL(clone) = rb_id_table_create(0);
arg.klass = clone;
rb_id_table_foreach(RCLASS_CONST_TBL(orig), clone_const_i, &arg);
}
}
@@ -550,8 +1477,8 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
/* cloned flag is refer at constant inline cache
* see vm_get_const_key_cref() in vm_insnhelper.c
*/
- RCLASS_EXT(clone)->cloned = true;
- RCLASS_EXT(orig)->cloned = true;
if (!RCLASS_SINGLETON_P(CLASS_OF(clone))) {
RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig));
@@ -563,12 +1490,12 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
struct clone_method_arg arg;
arg.old_klass = orig;
arg.new_klass = clone;
- RCLASS_M_TBL_INIT(clone);
rb_id_table_foreach(RCLASS_M_TBL(orig), clone_method_i, &arg);
}
if (RCLASS_ORIGIN(orig) == orig) {
- RCLASS_SET_SUPER(clone, RCLASS_SUPER(orig));
}
else {
VALUE p = RCLASS_SUPER(orig);
@@ -593,9 +1520,9 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
* that can trigger GC to avoid clone_p from becoming old and
* needing to fire write barriers. */
RCLASS_SET_M_TBL(clone_p, RCLASS_M_TBL(p));
- RCLASS_SET_SUPER(prev_clone_p, clone_p);
prev_clone_p = clone_p;
- RCLASS_CONST_TBL(clone_p) = RCLASS_CONST_TBL(p);
RCLASS_SET_ALLOCATOR(clone_p, RCLASS_ALLOCATOR(p));
if (RB_TYPE_P(clone, T_CLASS)) {
RCLASS_SET_INCLUDER(clone_p, clone);
@@ -608,8 +1535,8 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
}
else if ((origin_len = RARRAY_LEN(origin_stack)) > 1 &&
RARRAY_AREF(origin_stack, origin_len - 1) == p) {
- RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), clone_p);
- RICLASS_SET_ORIGIN_SHARED_MTBL(clone_p);
rb_ary_resize(origin_stack, origin_len);
add_subclass = FALSE;
}
@@ -621,15 +1548,15 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
if (p == orig_origin) {
if (clone_p) {
- RCLASS_SET_SUPER(clone_p, clone_origin);
- RCLASS_SET_SUPER(clone_origin, RCLASS_SUPER(orig_origin));
}
copy_tables(clone_origin, orig_origin);
if (RCLASS_M_TBL(orig_origin)) {
struct clone_method_arg arg;
arg.old_klass = orig;
arg.new_klass = clone;
- RCLASS_M_TBL_INIT(clone_origin);
rb_id_table_foreach(RCLASS_M_TBL(orig_origin), clone_method_i, &arg);
}
}
@@ -680,18 +1607,20 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
RBASIC_SET_CLASS(clone, klass_metaclass_clone);
}
- RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass));
rb_fields_tbl_copy(clone, klass);
if (RCLASS_CONST_TBL(klass)) {
struct clone_const_arg arg;
- arg.tbl = RCLASS_CONST_TBL(clone) = rb_id_table_create(0);
arg.klass = clone;
rb_id_table_foreach(RCLASS_CONST_TBL(klass), clone_const_i, &arg);
}
if (!UNDEF_P(attach)) {
rb_singleton_class_attached(clone, attach);
}
- RCLASS_M_TBL_INIT(clone);
{
struct clone_method_arg arg;
arg.old_klass = klass;
@@ -785,7 +1714,7 @@ make_metaclass(VALUE klass)
super = RCLASS_SUPER(klass);
while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super);
- RCLASS_SET_SUPER(metaclass, super ? ENSURE_EIGENCLASS(super) : rb_cClass);
// Full class ancestry may not have been filled until we reach here.
rb_class_update_superclasses(METACLASS_OF(metaclass));
@@ -985,8 +1914,12 @@ rb_define_class(const char *name, VALUE super)
{
VALUE klass;
ID id;
id = rb_intern(name);
if (rb_const_defined(rb_cObject, id)) {
klass = rb_const_get(rb_cObject, id);
if (!RB_TYPE_P(klass, T_CLASS)) {
@@ -1063,7 +1996,7 @@ VALUE
rb_module_s_alloc(VALUE klass)
{
VALUE mod = class_alloc(T_MODULE, klass);
- RCLASS_M_TBL_INIT(mod);
FL_SET(mod, RMODULE_ALLOCATED_BUT_NOT_INITIALIZED);
return mod;
}
@@ -1072,7 +2005,7 @@ static inline VALUE
module_new(VALUE klass)
{
VALUE mdl = class_alloc(T_MODULE, klass);
- RCLASS_M_TBL_INIT(mdl);
return (VALUE)mdl;
}
@@ -1100,8 +2033,12 @@ rb_define_module(const char *name)
{
VALUE module;
ID id;
id = rb_intern(name);
if (rb_const_defined(rb_cObject, id)) {
module = rb_const_get(rb_cObject, id);
if (!RB_TYPE_P(module, T_MODULE)) {
@@ -1154,21 +2091,23 @@ rb_include_class_new(VALUE module, VALUE super)
{
VALUE klass = class_alloc(T_ICLASS, rb_cClass);
- RCLASS_SET_M_TBL(klass, RCLASS_M_TBL(module));
RCLASS_SET_ORIGIN(klass, klass);
if (BUILTIN_TYPE(module) == T_ICLASS) {
module = METACLASS_OF(module);
}
RUBY_ASSERT(!RB_TYPE_P(module, T_ICLASS));
- if (!RCLASS_CONST_TBL(module)) {
- RCLASS_CONST_TBL(module) = rb_id_table_create(0);
}
- RCLASS_CVC_TBL(klass) = RCLASS_CVC_TBL(module);
- RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
- RCLASS_SET_SUPER(klass, super);
RBASIC_SET_CLASS(klass, module);
return (VALUE)klass;
@@ -1199,13 +2138,7 @@ rb_include_module(VALUE klass, VALUE module)
rb_raise(rb_eArgError, "cyclic include detected");
if (RB_TYPE_P(klass, T_MODULE)) {
- rb_subclass_entry_t *iclass = RCLASS_SUBCLASSES(klass);
- // skip the placeholder subclass entry at the head of the list
- if (iclass) {
- RUBY_ASSERT(!iclass->klass);
- iclass = iclass->next;
- }
-
while (iclass) {
int do_include = 1;
VALUE check_class = iclass->klass;
@@ -1336,7 +2269,7 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super
// setup T_ICLASS for the include/prepend module
iclass = rb_include_class_new(module, super_class);
- c = RCLASS_SET_SUPER(c, iclass);
RCLASS_SET_INCLUDER(iclass, klass);
if (module != RCLASS_ORIGIN(module)) {
if (!origin_stack) origin_stack = rb_ary_hidden_new(2);
@@ -1345,8 +2278,8 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super
}
else if (origin_stack && (origin_len = RARRAY_LEN(origin_stack)) > 1 &&
RARRAY_AREF(origin_stack, origin_len - 1) == module) {
- RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), iclass);
- RICLASS_SET_ORIGIN_SHARED_MTBL(iclass);
rb_ary_resize(origin_stack, origin_len);
}
@@ -1385,7 +2318,7 @@ move_refined_method(ID key, VALUE value, void *data)
if (me->def->type == VM_METHOD_TYPE_REFINED) {
VALUE klass = (VALUE)data;
- struct rb_id_table *tbl = RCLASS_M_TBL(klass);
if (me->def->body.refined.orig_me) {
const rb_method_entry_t *orig_me = me->def->body.refined.orig_me, *new_me;
@@ -1427,10 +2360,10 @@ ensure_origin(VALUE klass)
if (origin == klass) {
origin = class_alloc(T_ICLASS, klass);
RCLASS_SET_M_TBL(origin, RCLASS_M_TBL(klass));
- RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass));
- RCLASS_SET_SUPER(klass, origin);
- RCLASS_SET_ORIGIN(klass, origin);
- RCLASS_M_TBL_INIT(klass);
rb_id_table_foreach(RCLASS_M_TBL(origin), cache_clear_refined_method, (void *)klass);
rb_id_table_foreach(RCLASS_M_TBL(origin), move_refined_method, (void *)klass);
return true;
@@ -1455,13 +2388,7 @@ rb_prepend_module(VALUE klass, VALUE module)
rb_vm_check_redefinition_by_prepend(klass);
}
if (RB_TYPE_P(klass, T_MODULE)) {
- rb_subclass_entry_t *iclass = RCLASS_SUBCLASSES(klass);
- // skip the placeholder subclass entry at the head of the list if it exists
- if (iclass) {
- RUBY_ASSERT(!iclass->klass);
- iclass = iclass->next;
- }
-
VALUE klass_origin = RCLASS_ORIGIN(klass);
struct rb_id_table *klass_m_tbl = RCLASS_M_TBL(klass);
struct rb_id_table *klass_origin_m_tbl = RCLASS_M_TBL(klass_origin);
@@ -1473,11 +2400,11 @@ rb_prepend_module(VALUE klass, VALUE module)
if (klass_had_no_origin && klass_origin_m_tbl == RCLASS_M_TBL(subclass)) {
// backfill an origin iclass to handle refinements and future prepends
rb_id_table_foreach(RCLASS_M_TBL(subclass), clear_module_cache_i, (void *)subclass);
- RCLASS_M_TBL(subclass) = klass_m_tbl;
VALUE origin = rb_include_class_new(klass_origin, RCLASS_SUPER(subclass));
- RCLASS_SET_SUPER(subclass, origin);
RCLASS_SET_INCLUDER(origin, RCLASS_INCLUDER(subclass));
- RCLASS_SET_ORIGIN(subclass, origin);
RICLASS_SET_ORIGIN_SHARED_MTBL(origin);
}
include_modules_at(subclass, subclass, module, FALSE);
@@ -1553,7 +2480,7 @@ rb_mod_include_p(VALUE mod, VALUE mod2)
Check_Type(mod2, T_MODULE);
for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
- if (BUILTIN_TYPE(p) == T_ICLASS && !FL_TEST(p, RICLASS_IS_ORIGIN)) {
if (METACLASS_OF(p) == mod2) return Qtrue;
}
}
@@ -140,6 +140,7 @@ COMMONOBJS = array.$(OBJEXT) \
marshal.$(OBJEXT) \
math.$(OBJEXT) \
memory_view.$(OBJEXT) \
node.$(OBJEXT) \
node_dump.$(OBJEXT) \
numeric.$(OBJEXT) \
@@ -2116,6 +2117,7 @@ array.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
array.$(OBJEXT): $(top_srcdir)/internal/gc.h
array.$(OBJEXT): $(top_srcdir)/internal/hash.h
array.$(OBJEXT): $(top_srcdir)/internal/imemo.h
array.$(OBJEXT): $(top_srcdir)/internal/numeric.h
array.$(OBJEXT): $(top_srcdir)/internal/object.h
array.$(OBJEXT): $(top_srcdir)/internal/proc.h
@@ -2333,6 +2335,7 @@ ast.$(OBJEXT): $(top_srcdir)/internal/complex.h
ast.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
ast.$(OBJEXT): $(top_srcdir)/internal/gc.h
ast.$(OBJEXT): $(top_srcdir)/internal/imemo.h
ast.$(OBJEXT): $(top_srcdir)/internal/numeric.h
ast.$(OBJEXT): $(top_srcdir)/internal/parse.h
ast.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -2572,6 +2575,7 @@ bignum.$(OBJEXT): $(top_srcdir)/internal/complex.h
bignum.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
bignum.$(OBJEXT): $(top_srcdir)/internal/gc.h
bignum.$(OBJEXT): $(top_srcdir)/internal/imemo.h
bignum.$(OBJEXT): $(top_srcdir)/internal/numeric.h
bignum.$(OBJEXT): $(top_srcdir)/internal/object.h
bignum.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -2777,6 +2781,7 @@ builtin.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
builtin.$(OBJEXT): $(top_srcdir)/internal/compilers.h
builtin.$(OBJEXT): $(top_srcdir)/internal/gc.h
builtin.$(OBJEXT): $(top_srcdir)/internal/imemo.h
builtin.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
builtin.$(OBJEXT): $(top_srcdir)/internal/serial.h
builtin.$(OBJEXT): $(top_srcdir)/internal/set_table.h
@@ -3008,6 +3013,7 @@ class.$(OBJEXT): $(top_srcdir)/internal/eval.h
class.$(OBJEXT): $(top_srcdir)/internal/gc.h
class.$(OBJEXT): $(top_srcdir)/internal/hash.h
class.$(OBJEXT): $(top_srcdir)/internal/imemo.h
class.$(OBJEXT): $(top_srcdir)/internal/object.h
class.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
class.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -3408,6 +3414,7 @@ compile.$(OBJEXT): $(top_srcdir)/internal/gc.h
compile.$(OBJEXT): $(top_srcdir)/internal/hash.h
compile.$(OBJEXT): $(top_srcdir)/internal/imemo.h
compile.$(OBJEXT): $(top_srcdir)/internal/io.h
compile.$(OBJEXT): $(top_srcdir)/internal/numeric.h
compile.$(OBJEXT): $(top_srcdir)/internal/object.h
compile.$(OBJEXT): $(top_srcdir)/internal/parse.h
@@ -3669,6 +3676,7 @@ complex.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
complex.$(OBJEXT): $(top_srcdir)/internal/gc.h
complex.$(OBJEXT): $(top_srcdir)/internal/imemo.h
complex.$(OBJEXT): $(top_srcdir)/internal/math.h
complex.$(OBJEXT): $(top_srcdir)/internal/numeric.h
complex.$(OBJEXT): $(top_srcdir)/internal/object.h
complex.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -3881,6 +3889,7 @@ cont.$(OBJEXT): $(top_srcdir)/internal/cont.h
cont.$(OBJEXT): $(top_srcdir)/internal/error.h
cont.$(OBJEXT): $(top_srcdir)/internal/gc.h
cont.$(OBJEXT): $(top_srcdir)/internal/imemo.h
cont.$(OBJEXT): $(top_srcdir)/internal/proc.h
cont.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
cont.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -4120,6 +4129,7 @@ debug.$(OBJEXT): $(top_srcdir)/internal/class.h
debug.$(OBJEXT): $(top_srcdir)/internal/compilers.h
debug.$(OBJEXT): $(top_srcdir)/internal/gc.h
debug.$(OBJEXT): $(top_srcdir)/internal/imemo.h
debug.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
debug.$(OBJEXT): $(top_srcdir)/internal/serial.h
debug.$(OBJEXT): $(top_srcdir)/internal/set_table.h
@@ -4500,6 +4510,7 @@ dir.$(OBJEXT): $(top_srcdir)/internal/file.h
dir.$(OBJEXT): $(top_srcdir)/internal/gc.h
dir.$(OBJEXT): $(top_srcdir)/internal/imemo.h
dir.$(OBJEXT): $(top_srcdir)/internal/io.h
dir.$(OBJEXT): $(top_srcdir)/internal/object.h
dir.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
dir.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -4701,6 +4712,7 @@ dir.$(OBJEXT): {$(VPATH)}vm_core.h
dir.$(OBJEXT): {$(VPATH)}vm_opts.h
dln.$(OBJEXT): $(hdrdir)/ruby/ruby.h
dln.$(OBJEXT): $(top_srcdir)/internal/compilers.h
dln.$(OBJEXT): $(top_srcdir)/internal/warnings.h
dln.$(OBJEXT): {$(VPATH)}assert.h
dln.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -6431,6 +6443,7 @@ enumerator.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/gc.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/hash.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/imemo.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/numeric.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/range.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -6647,6 +6660,7 @@ error.$(OBJEXT): $(top_srcdir)/internal/hash.h
error.$(OBJEXT): $(top_srcdir)/internal/imemo.h
error.$(OBJEXT): $(top_srcdir)/internal/io.h
error.$(OBJEXT): $(top_srcdir)/internal/load.h
error.$(OBJEXT): $(top_srcdir)/internal/object.h
error.$(OBJEXT): $(top_srcdir)/internal/process.h
error.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -6871,6 +6885,7 @@ eval.$(OBJEXT): $(top_srcdir)/internal/hash.h
eval.$(OBJEXT): $(top_srcdir)/internal/imemo.h
eval.$(OBJEXT): $(top_srcdir)/internal/inits.h
eval.$(OBJEXT): $(top_srcdir)/internal/io.h
eval.$(OBJEXT): $(top_srcdir)/internal/object.h
eval.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
eval.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -7350,6 +7365,7 @@ gc.$(OBJEXT): $(top_srcdir)/internal/gc.h
gc.$(OBJEXT): $(top_srcdir)/internal/hash.h
gc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
gc.$(OBJEXT): $(top_srcdir)/internal/io.h
gc.$(OBJEXT): $(top_srcdir)/internal/numeric.h
gc.$(OBJEXT): $(top_srcdir)/internal/object.h
gc.$(OBJEXT): $(top_srcdir)/internal/proc.h
@@ -7614,6 +7630,7 @@ goruby.$(OBJEXT): $(top_srcdir)/internal/complex.h
goruby.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
goruby.$(OBJEXT): $(top_srcdir)/internal/gc.h
goruby.$(OBJEXT): $(top_srcdir)/internal/imemo.h
goruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h
goruby.$(OBJEXT): $(top_srcdir)/internal/parse.h
goruby.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -7855,6 +7872,7 @@ hash.$(OBJEXT): $(top_srcdir)/internal/error.h
hash.$(OBJEXT): $(top_srcdir)/internal/gc.h
hash.$(OBJEXT): $(top_srcdir)/internal/hash.h
hash.$(OBJEXT): $(top_srcdir)/internal/imemo.h
hash.$(OBJEXT): $(top_srcdir)/internal/object.h
hash.$(OBJEXT): $(top_srcdir)/internal/proc.h
hash.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -8478,6 +8496,7 @@ io.$(OBJEXT): $(top_srcdir)/internal/gc.h
io.$(OBJEXT): $(top_srcdir)/internal/imemo.h
io.$(OBJEXT): $(top_srcdir)/internal/inits.h
io.$(OBJEXT): $(top_srcdir)/internal/io.h
io.$(OBJEXT): $(top_srcdir)/internal/numeric.h
io.$(OBJEXT): $(top_srcdir)/internal/object.h
io.$(OBJEXT): $(top_srcdir)/internal/process.h
@@ -8920,6 +8939,7 @@ iseq.$(OBJEXT): $(top_srcdir)/internal/gc.h
iseq.$(OBJEXT): $(top_srcdir)/internal/hash.h
iseq.$(OBJEXT): $(top_srcdir)/internal/imemo.h
iseq.$(OBJEXT): $(top_srcdir)/internal/io.h
iseq.$(OBJEXT): $(top_srcdir)/internal/numeric.h
iseq.$(OBJEXT): $(top_srcdir)/internal/parse.h
iseq.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -9406,12 +9426,14 @@ load.$(OBJEXT): $(top_srcdir)/internal/compilers.h
load.$(OBJEXT): $(top_srcdir)/internal/complex.h
load.$(OBJEXT): $(top_srcdir)/internal/dir.h
load.$(OBJEXT): $(top_srcdir)/internal/error.h
load.$(OBJEXT): $(top_srcdir)/internal/file.h
load.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
load.$(OBJEXT): $(top_srcdir)/internal/gc.h
load.$(OBJEXT): $(top_srcdir)/internal/hash.h
load.$(OBJEXT): $(top_srcdir)/internal/imemo.h
load.$(OBJEXT): $(top_srcdir)/internal/load.h
load.$(OBJEXT): $(top_srcdir)/internal/numeric.h
load.$(OBJEXT): $(top_srcdir)/internal/parse.h
load.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -10156,6 +10178,7 @@ marshal.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
marshal.$(OBJEXT): $(top_srcdir)/internal/gc.h
marshal.$(OBJEXT): $(top_srcdir)/internal/hash.h
marshal.$(OBJEXT): $(top_srcdir)/internal/imemo.h
marshal.$(OBJEXT): $(top_srcdir)/internal/numeric.h
marshal.$(OBJEXT): $(top_srcdir)/internal/object.h
marshal.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -10547,6 +10570,7 @@ memory_view.$(OBJEXT): $(top_srcdir)/internal/compilers.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/gc.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/hash.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/imemo.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/serial.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/set_table.h
@@ -10757,6 +10781,7 @@ miniinit.$(OBJEXT): $(top_srcdir)/internal/complex.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/gc.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/numeric.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/parse.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -11002,6 +11027,206 @@ miniinit.$(OBJEXT): {$(VPATH)}warning.rb
miniinit.$(OBJEXT): {$(VPATH)}yjit.rb
miniinit.$(OBJEXT): {$(VPATH)}yjit_hook.rb
miniinit.$(OBJEXT): {$(VPATH)}zjit.rb
node.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
node.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
node.$(OBJEXT): $(CCAN_DIR)/list/list.h
@@ -11013,6 +11238,7 @@ node.$(OBJEXT): $(top_srcdir)/internal/compilers.h
node.$(OBJEXT): $(top_srcdir)/internal/gc.h
node.$(OBJEXT): $(top_srcdir)/internal/hash.h
node.$(OBJEXT): $(top_srcdir)/internal/imemo.h
node.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
node.$(OBJEXT): $(top_srcdir)/internal/serial.h
node.$(OBJEXT): $(top_srcdir)/internal/set_table.h
@@ -11221,6 +11447,7 @@ node_dump.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/hash.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/numeric.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/parse.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -11436,6 +11663,7 @@ numeric.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
numeric.$(OBJEXT): $(top_srcdir)/internal/gc.h
numeric.$(OBJEXT): $(top_srcdir)/internal/hash.h
numeric.$(OBJEXT): $(top_srcdir)/internal/imemo.h
numeric.$(OBJEXT): $(top_srcdir)/internal/numeric.h
numeric.$(OBJEXT): $(top_srcdir)/internal/object.h
numeric.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -11653,6 +11881,7 @@ object.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
object.$(OBJEXT): $(top_srcdir)/internal/gc.h
object.$(OBJEXT): $(top_srcdir)/internal/imemo.h
object.$(OBJEXT): $(top_srcdir)/internal/inits.h
object.$(OBJEXT): $(top_srcdir)/internal/numeric.h
object.$(OBJEXT): $(top_srcdir)/internal/object.h
object.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -11873,6 +12102,7 @@ pack.$(OBJEXT): $(top_srcdir)/internal/bits.h
pack.$(OBJEXT): $(top_srcdir)/internal/compilers.h
pack.$(OBJEXT): $(top_srcdir)/internal/gc.h
pack.$(OBJEXT): $(top_srcdir)/internal/imemo.h
pack.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
pack.$(OBJEXT): $(top_srcdir)/internal/serial.h
pack.$(OBJEXT): $(top_srcdir)/internal/set_table.h
@@ -12090,6 +12320,7 @@ parse.$(OBJEXT): $(top_srcdir)/internal/gc.h
parse.$(OBJEXT): $(top_srcdir)/internal/hash.h
parse.$(OBJEXT): $(top_srcdir)/internal/imemo.h
parse.$(OBJEXT): $(top_srcdir)/internal/io.h
parse.$(OBJEXT): $(top_srcdir)/internal/numeric.h
parse.$(OBJEXT): $(top_srcdir)/internal/parse.h
parse.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -13368,6 +13599,7 @@ proc.$(OBJEXT): $(top_srcdir)/internal/eval.h
proc.$(OBJEXT): $(top_srcdir)/internal/gc.h
proc.$(OBJEXT): $(top_srcdir)/internal/hash.h
proc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
proc.$(OBJEXT): $(top_srcdir)/internal/object.h
proc.$(OBJEXT): $(top_srcdir)/internal/proc.h
proc.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -13614,6 +13846,7 @@ process.$(OBJEXT): $(top_srcdir)/internal/gc.h
process.$(OBJEXT): $(top_srcdir)/internal/hash.h
process.$(OBJEXT): $(top_srcdir)/internal/imemo.h
process.$(OBJEXT): $(top_srcdir)/internal/io.h
process.$(OBJEXT): $(top_srcdir)/internal/numeric.h
process.$(OBJEXT): $(top_srcdir)/internal/object.h
process.$(OBJEXT): $(top_srcdir)/internal/process.h
@@ -13839,6 +14072,7 @@ ractor.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
ractor.$(OBJEXT): $(top_srcdir)/internal/gc.h
ractor.$(OBJEXT): $(top_srcdir)/internal/hash.h
ractor.$(OBJEXT): $(top_srcdir)/internal/imemo.h
ractor.$(OBJEXT): $(top_srcdir)/internal/numeric.h
ractor.$(OBJEXT): $(top_srcdir)/internal/object.h
ractor.$(OBJEXT): $(top_srcdir)/internal/ractor.h
@@ -14061,6 +14295,7 @@ random.$(OBJEXT): $(top_srcdir)/internal/compilers.h
random.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
random.$(OBJEXT): $(top_srcdir)/internal/gc.h
random.$(OBJEXT): $(top_srcdir)/internal/imemo.h
random.$(OBJEXT): $(top_srcdir)/internal/numeric.h
random.$(OBJEXT): $(top_srcdir)/internal/random.h
random.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -14467,6 +14702,7 @@ rational.$(OBJEXT): $(top_srcdir)/internal/complex.h
rational.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
rational.$(OBJEXT): $(top_srcdir)/internal/gc.h
rational.$(OBJEXT): $(top_srcdir)/internal/imemo.h
rational.$(OBJEXT): $(top_srcdir)/internal/numeric.h
rational.$(OBJEXT): $(top_srcdir)/internal/object.h
rational.$(OBJEXT): $(top_srcdir)/internal/rational.h
@@ -14676,6 +14912,7 @@ re.$(OBJEXT): $(top_srcdir)/internal/encoding.h
re.$(OBJEXT): $(top_srcdir)/internal/gc.h
re.$(OBJEXT): $(top_srcdir)/internal/hash.h
re.$(OBJEXT): $(top_srcdir)/internal/imemo.h
re.$(OBJEXT): $(top_srcdir)/internal/object.h
re.$(OBJEXT): $(top_srcdir)/internal/ractor.h
re.$(OBJEXT): $(top_srcdir)/internal/re.h
@@ -15890,6 +16127,7 @@ ruby.$(OBJEXT): $(top_srcdir)/internal/io.h
ruby.$(OBJEXT): $(top_srcdir)/internal/load.h
ruby.$(OBJEXT): $(top_srcdir)/internal/loadpath.h
ruby.$(OBJEXT): $(top_srcdir)/internal/missing.h
ruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h
ruby.$(OBJEXT): $(top_srcdir)/internal/object.h
ruby.$(OBJEXT): $(top_srcdir)/internal/parse.h
@@ -16321,6 +16559,7 @@ scheduler.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/compilers.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/gc.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/imemo.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/serial.h
scheduler.$(OBJEXT): $(top_srcdir)/internal/set_table.h
@@ -16895,6 +17134,7 @@ shape.$(OBJEXT): $(top_srcdir)/internal/compilers.h
shape.$(OBJEXT): $(top_srcdir)/internal/error.h
shape.$(OBJEXT): $(top_srcdir)/internal/gc.h
shape.$(OBJEXT): $(top_srcdir)/internal/imemo.h
shape.$(OBJEXT): $(top_srcdir)/internal/object.h
shape.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
shape.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -17107,6 +17347,7 @@ signal.$(OBJEXT): $(top_srcdir)/internal/error.h
signal.$(OBJEXT): $(top_srcdir)/internal/eval.h
signal.$(OBJEXT): $(top_srcdir)/internal/gc.h
signal.$(OBJEXT): $(top_srcdir)/internal/imemo.h
signal.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
signal.$(OBJEXT): $(top_srcdir)/internal/serial.h
signal.$(OBJEXT): $(top_srcdir)/internal/set_table.h
@@ -17873,6 +18114,7 @@ string.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
string.$(OBJEXT): $(top_srcdir)/internal/gc.h
string.$(OBJEXT): $(top_srcdir)/internal/hash.h
string.$(OBJEXT): $(top_srcdir)/internal/imemo.h
string.$(OBJEXT): $(top_srcdir)/internal/numeric.h
string.$(OBJEXT): $(top_srcdir)/internal/object.h
string.$(OBJEXT): $(top_srcdir)/internal/proc.h
@@ -18126,6 +18368,7 @@ struct.$(OBJEXT): $(top_srcdir)/internal/error.h
struct.$(OBJEXT): $(top_srcdir)/internal/gc.h
struct.$(OBJEXT): $(top_srcdir)/internal/hash.h
struct.$(OBJEXT): $(top_srcdir)/internal/imemo.h
struct.$(OBJEXT): $(top_srcdir)/internal/object.h
struct.$(OBJEXT): $(top_srcdir)/internal/proc.h
struct.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -18340,6 +18583,7 @@ symbol.$(OBJEXT): $(top_srcdir)/internal/error.h
symbol.$(OBJEXT): $(top_srcdir)/internal/gc.h
symbol.$(OBJEXT): $(top_srcdir)/internal/hash.h
symbol.$(OBJEXT): $(top_srcdir)/internal/imemo.h
symbol.$(OBJEXT): $(top_srcdir)/internal/object.h
symbol.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
symbol.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -18564,6 +18808,7 @@ thread.$(OBJEXT): $(top_srcdir)/internal/gc.h
thread.$(OBJEXT): $(top_srcdir)/internal/hash.h
thread.$(OBJEXT): $(top_srcdir)/internal/imemo.h
thread.$(OBJEXT): $(top_srcdir)/internal/io.h
thread.$(OBJEXT): $(top_srcdir)/internal/object.h
thread.$(OBJEXT): $(top_srcdir)/internal/proc.h
thread.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -18819,6 +19064,7 @@ time.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
time.$(OBJEXT): $(top_srcdir)/internal/gc.h
time.$(OBJEXT): $(top_srcdir)/internal/hash.h
time.$(OBJEXT): $(top_srcdir)/internal/imemo.h
time.$(OBJEXT): $(top_srcdir)/internal/numeric.h
time.$(OBJEXT): $(top_srcdir)/internal/rational.h
time.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -19391,6 +19637,7 @@ variable.$(OBJEXT): $(top_srcdir)/internal/eval.h
variable.$(OBJEXT): $(top_srcdir)/internal/gc.h
variable.$(OBJEXT): $(top_srcdir)/internal/hash.h
variable.$(OBJEXT): $(top_srcdir)/internal/imemo.h
variable.$(OBJEXT): $(top_srcdir)/internal/object.h
variable.$(OBJEXT): $(top_srcdir)/internal/re.h
variable.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
@@ -19608,6 +19855,7 @@ version.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h
version.$(OBJEXT): $(top_srcdir)/internal/compilers.h
version.$(OBJEXT): $(top_srcdir)/internal/gc.h
version.$(OBJEXT): $(top_srcdir)/internal/imemo.h
version.$(OBJEXT): $(top_srcdir)/internal/parse.h
version.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
version.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -19830,6 +20078,7 @@ vm.$(OBJEXT): $(top_srcdir)/internal/hash.h
vm.$(OBJEXT): $(top_srcdir)/internal/imemo.h
vm.$(OBJEXT): $(top_srcdir)/internal/inits.h
vm.$(OBJEXT): $(top_srcdir)/internal/missing.h
vm.$(OBJEXT): $(top_srcdir)/internal/numeric.h
vm.$(OBJEXT): $(top_srcdir)/internal/object.h
vm.$(OBJEXT): $(top_srcdir)/internal/parse.h
@@ -20103,6 +20352,7 @@ vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/compilers.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/error.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/gc.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/imemo.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/set_table.h
@@ -20335,6 +20585,7 @@ vm_dump.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/set_table.h
@@ -20567,6 +20818,7 @@ vm_sync.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/compilers.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/gc.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/imemo.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm_sync.$(OBJEXT): $(top_srcdir)/internal/set_table.h
@@ -20778,6 +21030,7 @@ vm_trace.$(OBJEXT): $(top_srcdir)/internal/compilers.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/gc.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/hash.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/imemo.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/set_table.h
@@ -21016,6 +21269,7 @@ weakmap.$(OBJEXT): $(top_srcdir)/internal/compilers.h
weakmap.$(OBJEXT): $(top_srcdir)/internal/gc.h
weakmap.$(OBJEXT): $(top_srcdir)/internal/hash.h
weakmap.$(OBJEXT): $(top_srcdir)/internal/imemo.h
weakmap.$(OBJEXT): $(top_srcdir)/internal/proc.h
weakmap.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
weakmap.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -21221,6 +21475,7 @@ yjit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
yjit.$(OBJEXT): $(top_srcdir)/internal/gc.h
yjit.$(OBJEXT): $(top_srcdir)/internal/hash.h
yjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
yjit.$(OBJEXT): $(top_srcdir)/internal/numeric.h
yjit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
yjit.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -26,6 +26,7 @@ static void dln_loaderror(const char *format, ...);
#include "dln.h"
#include "internal.h"
#include "internal/compilers.h"
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
@@ -383,9 +384,13 @@ dln_open(const char *file)
# ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
# endif
/* Load file */
- handle = dlopen(file, RTLD_LAZY|RTLD_GLOBAL);
if (handle == NULL) {
error = dln_strerror();
goto failed;
@@ -497,8 +502,8 @@ abi_check_enabled_p(void)
}
#endif
-void *
-dln_load(const char *file)
{
#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
void *handle = dln_open(file);
@@ -512,9 +517,6 @@ dln_load(const char *file)
}
#endif
- char *init_fct_name;
- init_funcname(&init_fct_name, file);
-
/* Call the init code */
dln_sym_callable(void, (void), handle, init_fct_name)();
@@ -524,6 +526,7 @@ dln_load(const char *file)
{
void (*init_fct)(void);
init_fct = (void(*)(void))load((char*)file, 1, 0);
if (init_fct == NULL) {
aix_loaderror(file);
@@ -540,3 +543,29 @@ dln_load(const char *file)
return 0; /* dummy return */
}
@@ -25,6 +25,7 @@ RUBY_SYMBOL_EXPORT_BEGIN
char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
void *dln_load(const char*);
void *dln_symbol(void*,const char*);
RUBY_SYMBOL_EXPORT_END
@@ -12,6 +12,15 @@ dln_load(const char *file)
UNREACHABLE_RETURN(NULL);
}
NORETURN(void *dln_symbol(void*,const char*));
void*
dln_symbol(void *handle, const char *symbol)
@@ -1192,6 +1192,8 @@ rb_mod_append_features(VALUE module, VALUE include)
return module;
}
/*
* call-seq:
* include(module, ...) -> self
@@ -1345,9 +1347,9 @@ rb_using_refinement(rb_cref_t *cref, VALUE klass, VALUE module)
}
superclass = refinement_superclass(superclass);
c = iclass = rb_include_class_new(module, superclass);
- RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
- RCLASS_M_TBL(c) = RCLASS_M_TBL(module);
rb_hash_aset(CREF_REFINEMENTS(cref), klass, iclass);
}
@@ -1402,6 +1404,12 @@ rb_using_module(const rb_cref_t *cref, VALUE module)
rb_clear_all_refinement_method_cache();
}
/*
* call-seq:
* target -> class_or_module
@@ -1442,43 +1450,24 @@ add_activated_refinement(VALUE activated_refinements,
}
superclass = refinement_superclass(superclass);
c = iclass = rb_include_class_new(refinement, superclass);
- RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
refinement = RCLASS_SUPER(refinement);
while (refinement && refinement != klass) {
- c = RCLASS_SET_SUPER(c, rb_include_class_new(refinement, RCLASS_SUPER(c)));
- RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
refinement = RCLASS_SUPER(refinement);
}
rb_hash_aset(activated_refinements, klass, iclass);
}
-/*
- * call-seq:
- * refine(mod) { block } -> module
- *
- * Refine <i>mod</i> in the receiver.
- *
- * Returns a module, where refined methods are defined.
- */
-
-static VALUE
-rb_mod_refine(VALUE module, VALUE klass)
{
VALUE refinement;
ID id_refinements, id_activated_refinements,
id_refined_class, id_defined_at;
VALUE refinements, activated_refinements;
- rb_thread_t *th = GET_THREAD();
- VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
-
- if (block_handler == VM_BLOCK_HANDLER_NONE) {
- rb_raise(rb_eArgError, "no block given");
- }
- if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
- rb_raise(rb_eArgError, "can't pass a Proc as a block to Module#refine");
- }
- ensure_class_or_module(klass);
CONST_ID(id_refinements, "__refinements__");
refinements = rb_attr_get(module, id_refinements);
if (NIL_P(refinements)) {
@@ -1496,7 +1485,7 @@ rb_mod_refine(VALUE module, VALUE klass)
if (NIL_P(refinement)) {
VALUE superclass = refinement_superclass(klass);
refinement = rb_refinement_new();
- RCLASS_SET_SUPER(refinement, superclass);
RUBY_ASSERT(BUILTIN_TYPE(refinement) == T_MODULE);
FL_SET(refinement, RMODULE_IS_REFINEMENT);
CONST_ID(id_refined_class, "__refined_class__");
@@ -1506,8 +1495,41 @@ rb_mod_refine(VALUE module, VALUE klass)
rb_hash_aset(refinements, klass, refinement);
add_activated_refinement(activated_refinements, klass, refinement);
}
- rb_yield_refine_block(refinement, activated_refinements);
- return refinement;
}
static void
@@ -296,6 +296,7 @@ VALUE rb_vm_make_jump_tag_but_local_jump(enum ruby_tag_type state, VALUE val);
rb_cref_t *rb_vm_cref(void);
rb_cref_t *rb_vm_cref_replace_with_duplicated_cref(void);
VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename);
void rb_vm_set_progname(VALUE filename);
VALUE rb_vm_cbase(void);
@@ -0,0 +1 @@
@@ -0,0 +1,28 @@
@@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
@@ -0,0 +1 @@
@@ -0,0 +1,28 @@
@@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
@@ -186,6 +186,7 @@ coverage.o: $(top_srcdir)/internal/compilers.h
coverage.o: $(top_srcdir)/internal/gc.h
coverage.o: $(top_srcdir)/internal/hash.h
coverage.o: $(top_srcdir)/internal/imemo.h
coverage.o: $(top_srcdir)/internal/sanitizers.h
coverage.o: $(top_srcdir)/internal/serial.h
coverage.o: $(top_srcdir)/internal/set_table.h
@@ -183,6 +183,7 @@ object_tracing.o: $(top_srcdir)/internal/basic_operators.h
object_tracing.o: $(top_srcdir)/internal/compilers.h
object_tracing.o: $(top_srcdir)/internal/gc.h
object_tracing.o: $(top_srcdir)/internal/imemo.h
object_tracing.o: $(top_srcdir)/internal/sanitizers.h
object_tracing.o: $(top_srcdir)/internal/serial.h
object_tracing.o: $(top_srcdir)/internal/set_table.h
@@ -392,6 +393,7 @@ objspace.o: $(top_srcdir)/internal/compilers.h
objspace.o: $(top_srcdir)/internal/gc.h
objspace.o: $(top_srcdir)/internal/hash.h
objspace.o: $(top_srcdir)/internal/imemo.h
objspace.o: $(top_srcdir)/internal/sanitizers.h
objspace.o: $(top_srcdir)/internal/serial.h
objspace.o: $(top_srcdir)/internal/set_table.h
@@ -605,6 +607,7 @@ objspace_dump.o: $(top_srcdir)/internal/gc.h
objspace_dump.o: $(top_srcdir)/internal/hash.h
objspace_dump.o: $(top_srcdir)/internal/imemo.h
objspace_dump.o: $(top_srcdir)/internal/io.h
objspace_dump.o: $(top_srcdir)/internal/sanitizers.h
objspace_dump.o: $(top_srcdir)/internal/serial.h
objspace_dump.o: $(top_srcdir)/internal/set_table.h
@@ -792,7 +792,7 @@ objspace_internal_super_of(VALUE self, VALUE obj)
case T_MODULE:
case T_CLASS:
case T_ICLASS:
- super = RCLASS_SUPER(obj);
break;
default:
rb_raise(rb_eArgError, "class or module is expected");
@@ -537,7 +537,7 @@ dump_object(VALUE obj, struct dump_config *dc)
case T_CLASS:
dump_append(dc, ", \"variation_count\":");
- dump_append_d(dc, RCLASS_EXT(obj)->variation_count);
case T_MODULE:
if (rb_class_get_superclass(obj)) {
@@ -560,7 +560,7 @@ dump_object(VALUE obj, struct dump_config *dc)
}
}
- if (RCLASS_SINGLETON_P(obj)) {
dump_append(dc, ", \"singleton\":true");
}
}
@@ -591,6 +591,7 @@ ripper.o: $(top_srcdir)/internal/gc.h
ripper.o: $(top_srcdir)/internal/hash.h
ripper.o: $(top_srcdir)/internal/imemo.h
ripper.o: $(top_srcdir)/internal/io.h
ripper.o: $(top_srcdir)/internal/numeric.h
ripper.o: $(top_srcdir)/internal/parse.h
ripper.o: $(top_srcdir)/internal/rational.h
@@ -200,6 +200,7 @@ ancdata.o: $(top_srcdir)/internal/error.h
ancdata.o: $(top_srcdir)/internal/gc.h
ancdata.o: $(top_srcdir)/internal/imemo.h
ancdata.o: $(top_srcdir)/internal/io.h
ancdata.o: $(top_srcdir)/internal/sanitizers.h
ancdata.o: $(top_srcdir)/internal/serial.h
ancdata.o: $(top_srcdir)/internal/set_table.h
@@ -412,6 +413,7 @@ basicsocket.o: $(top_srcdir)/internal/error.h
basicsocket.o: $(top_srcdir)/internal/gc.h
basicsocket.o: $(top_srcdir)/internal/imemo.h
basicsocket.o: $(top_srcdir)/internal/io.h
basicsocket.o: $(top_srcdir)/internal/sanitizers.h
basicsocket.o: $(top_srcdir)/internal/serial.h
basicsocket.o: $(top_srcdir)/internal/set_table.h
@@ -624,6 +626,7 @@ constants.o: $(top_srcdir)/internal/error.h
constants.o: $(top_srcdir)/internal/gc.h
constants.o: $(top_srcdir)/internal/imemo.h
constants.o: $(top_srcdir)/internal/io.h
constants.o: $(top_srcdir)/internal/sanitizers.h
constants.o: $(top_srcdir)/internal/serial.h
constants.o: $(top_srcdir)/internal/set_table.h
@@ -837,6 +840,7 @@ ifaddr.o: $(top_srcdir)/internal/error.h
ifaddr.o: $(top_srcdir)/internal/gc.h
ifaddr.o: $(top_srcdir)/internal/imemo.h
ifaddr.o: $(top_srcdir)/internal/io.h
ifaddr.o: $(top_srcdir)/internal/sanitizers.h
ifaddr.o: $(top_srcdir)/internal/serial.h
ifaddr.o: $(top_srcdir)/internal/set_table.h
@@ -1049,6 +1053,7 @@ init.o: $(top_srcdir)/internal/error.h
init.o: $(top_srcdir)/internal/gc.h
init.o: $(top_srcdir)/internal/imemo.h
init.o: $(top_srcdir)/internal/io.h
init.o: $(top_srcdir)/internal/sanitizers.h
init.o: $(top_srcdir)/internal/serial.h
init.o: $(top_srcdir)/internal/set_table.h
@@ -1261,6 +1266,7 @@ ipsocket.o: $(top_srcdir)/internal/error.h
ipsocket.o: $(top_srcdir)/internal/gc.h
ipsocket.o: $(top_srcdir)/internal/imemo.h
ipsocket.o: $(top_srcdir)/internal/io.h
ipsocket.o: $(top_srcdir)/internal/sanitizers.h
ipsocket.o: $(top_srcdir)/internal/serial.h
ipsocket.o: $(top_srcdir)/internal/set_table.h
@@ -1473,6 +1479,7 @@ option.o: $(top_srcdir)/internal/error.h
option.o: $(top_srcdir)/internal/gc.h
option.o: $(top_srcdir)/internal/imemo.h
option.o: $(top_srcdir)/internal/io.h
option.o: $(top_srcdir)/internal/sanitizers.h
option.o: $(top_srcdir)/internal/serial.h
option.o: $(top_srcdir)/internal/set_table.h
@@ -1685,6 +1692,7 @@ raddrinfo.o: $(top_srcdir)/internal/error.h
raddrinfo.o: $(top_srcdir)/internal/gc.h
raddrinfo.o: $(top_srcdir)/internal/imemo.h
raddrinfo.o: $(top_srcdir)/internal/io.h
raddrinfo.o: $(top_srcdir)/internal/sanitizers.h
raddrinfo.o: $(top_srcdir)/internal/serial.h
raddrinfo.o: $(top_srcdir)/internal/set_table.h
@@ -1897,6 +1905,7 @@ socket.o: $(top_srcdir)/internal/error.h
socket.o: $(top_srcdir)/internal/gc.h
socket.o: $(top_srcdir)/internal/imemo.h
socket.o: $(top_srcdir)/internal/io.h
socket.o: $(top_srcdir)/internal/sanitizers.h
socket.o: $(top_srcdir)/internal/serial.h
socket.o: $(top_srcdir)/internal/set_table.h
@@ -2109,6 +2118,7 @@ sockssocket.o: $(top_srcdir)/internal/error.h
sockssocket.o: $(top_srcdir)/internal/gc.h
sockssocket.o: $(top_srcdir)/internal/imemo.h
sockssocket.o: $(top_srcdir)/internal/io.h
sockssocket.o: $(top_srcdir)/internal/sanitizers.h
sockssocket.o: $(top_srcdir)/internal/serial.h
sockssocket.o: $(top_srcdir)/internal/set_table.h
@@ -2321,6 +2331,7 @@ tcpserver.o: $(top_srcdir)/internal/error.h
tcpserver.o: $(top_srcdir)/internal/gc.h
tcpserver.o: $(top_srcdir)/internal/imemo.h
tcpserver.o: $(top_srcdir)/internal/io.h
tcpserver.o: $(top_srcdir)/internal/sanitizers.h
tcpserver.o: $(top_srcdir)/internal/serial.h
tcpserver.o: $(top_srcdir)/internal/set_table.h
@@ -2533,6 +2544,7 @@ tcpsocket.o: $(top_srcdir)/internal/error.h
tcpsocket.o: $(top_srcdir)/internal/gc.h
tcpsocket.o: $(top_srcdir)/internal/imemo.h
tcpsocket.o: $(top_srcdir)/internal/io.h
tcpsocket.o: $(top_srcdir)/internal/sanitizers.h
tcpsocket.o: $(top_srcdir)/internal/serial.h
tcpsocket.o: $(top_srcdir)/internal/set_table.h
@@ -2745,6 +2757,7 @@ udpsocket.o: $(top_srcdir)/internal/error.h
udpsocket.o: $(top_srcdir)/internal/gc.h
udpsocket.o: $(top_srcdir)/internal/imemo.h
udpsocket.o: $(top_srcdir)/internal/io.h
udpsocket.o: $(top_srcdir)/internal/sanitizers.h
udpsocket.o: $(top_srcdir)/internal/serial.h
udpsocket.o: $(top_srcdir)/internal/set_table.h
@@ -2957,6 +2970,7 @@ unixserver.o: $(top_srcdir)/internal/error.h
unixserver.o: $(top_srcdir)/internal/gc.h
unixserver.o: $(top_srcdir)/internal/imemo.h
unixserver.o: $(top_srcdir)/internal/io.h
unixserver.o: $(top_srcdir)/internal/sanitizers.h
unixserver.o: $(top_srcdir)/internal/serial.h
unixserver.o: $(top_srcdir)/internal/set_table.h
@@ -3169,6 +3183,7 @@ unixsocket.o: $(top_srcdir)/internal/error.h
unixsocket.o: $(top_srcdir)/internal/gc.h
unixsocket.o: $(top_srcdir)/internal/imemo.h
unixsocket.o: $(top_srcdir)/internal/io.h
unixsocket.o: $(top_srcdir)/internal/sanitizers.h
unixsocket.o: $(top_srcdir)/internal/serial.h
unixsocket.o: $(top_srcdir)/internal/set_table.h
@@ -1210,9 +1210,68 @@ rb_data_free(void *objspace, VALUE obj)
return true;
}
bool
rb_gc_obj_free(void *objspace, VALUE obj)
{
RB_DEBUG_COUNTER_INC(obj_free);
switch (BUILTIN_TYPE(obj)) {
@@ -1242,29 +1301,13 @@ rb_gc_obj_free(void *objspace, VALUE obj)
break;
case T_MODULE:
case T_CLASS:
- rb_id_table_free(RCLASS_M_TBL(obj));
- rb_cc_table_free(obj);
- if (rb_shape_obj_too_complex_p(obj)) {
- st_free_table((st_table *)RCLASS_FIELDS(obj));
- }
- else {
- xfree(RCLASS_FIELDS(obj));
- }
- if (RCLASS_CONST_TBL(obj)) {
- rb_free_const_table(RCLASS_CONST_TBL(obj));
- }
- if (RCLASS_CVC_TBL(obj)) {
- rb_id_table_foreach_values(RCLASS_CVC_TBL(obj), cvar_table_free_i, NULL);
- rb_id_table_free(RCLASS_CVC_TBL(obj));
}
- rb_class_remove_subclass_head(obj);
- rb_class_remove_from_module_subclasses(obj);
- rb_class_remove_from_super_subclasses(obj);
- if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) {
- xfree(RCLASS_SUPERCLASSES(obj));
- }
-
(void)RB_DEBUG_COUNTER_INC_IF(obj_module_ptr, BUILTIN_TYPE(obj) == T_MODULE);
(void)RB_DEBUG_COUNTER_INC_IF(obj_class_ptr, BUILTIN_TYPE(obj) == T_CLASS);
break;
@@ -1363,18 +1406,12 @@ rb_gc_obj_free(void *objspace, VALUE obj)
case T_MOVED:
break;
case T_ICLASS:
- /* Basically , T_ICLASS shares table with the module */
- if (RICLASS_OWNS_M_TBL_P(obj)) {
- /* Method table is not shared for origin iclasses of classes */
- rb_id_table_free(RCLASS_M_TBL(obj));
- }
- if (RCLASS_CALLABLE_M_TBL(obj) != NULL) {
- rb_id_table_free(RCLASS_CALLABLE_M_TBL(obj));
}
- rb_class_remove_subclass_head(obj);
- rb_cc_table_free(obj);
- rb_class_remove_from_module_subclasses(obj);
- rb_class_remove_from_super_subclasses(obj);
RB_DEBUG_COUNTER_INC(obj_iclass_ptr);
break;
@@ -2124,6 +2161,60 @@ cc_table_memsize(struct rb_id_table *cc_table)
return total;
}
size_t
rb_obj_memsize_of(VALUE obj)
{
@@ -2148,23 +2239,16 @@ rb_obj_memsize_of(VALUE obj)
break;
case T_MODULE:
case T_CLASS:
- if (RCLASS_M_TBL(obj)) {
- size += rb_id_table_memsize(RCLASS_M_TBL(obj));
- }
- // class IV sizes are allocated as powers of two
- size += SIZEOF_VALUE << bit_length(RCLASS_FIELDS_COUNT(obj));
- if (RCLASS_CVC_TBL(obj)) {
- size += rb_id_table_memsize(RCLASS_CVC_TBL(obj));
- }
- if (RCLASS_EXT(obj)->const_tbl) {
- size += rb_id_table_memsize(RCLASS_EXT(obj)->const_tbl);
- }
- if (RCLASS_CC_TBL(obj)) {
- size += cc_table_memsize(RCLASS_CC_TBL(obj));
- }
- if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) {
- size += (RCLASS_SUPERCLASS_DEPTH(obj) + 1) * sizeof(VALUE);
}
break;
case T_ICLASS:
if (RICLASS_OWNS_M_TBL_P(obj)) {
@@ -2172,8 +2256,8 @@ rb_obj_memsize_of(VALUE obj)
size += rb_id_table_memsize(RCLASS_M_TBL(obj));
}
}
- if (RCLASS_CC_TBL(obj)) {
- size += cc_table_memsize(RCLASS_CC_TBL(obj));
}
break;
case T_STRING:
@@ -2634,6 +2718,86 @@ mark_m_tbl(void *objspace, struct rb_id_table *tbl)
}
}
#if STACK_GROW_DIRECTION < 0
#define GET_STACK_BOUNDS(start, end, appendix) ((start) = STACK_END, (end) = STACK_START)
#elif STACK_GROW_DIRECTION > 0
@@ -2796,45 +2960,12 @@ rb_mark_tbl_no_pin(st_table *tbl)
gc_mark_tbl_no_pin(tbl);
}
-static enum rb_id_table_iterator_result
-mark_cvc_tbl_i(VALUE cvc_entry, void *objspace)
-{
- struct rb_cvar_class_tbl_entry *entry;
-
- entry = (struct rb_cvar_class_tbl_entry *)cvc_entry;
-
- RUBY_ASSERT(entry->cref == 0 || (BUILTIN_TYPE((VALUE)entry->cref) == T_IMEMO && IMEMO_TYPE_P(entry->cref, imemo_cref)));
- gc_mark_internal((VALUE)entry->cref);
-
- return ID_TABLE_CONTINUE;
-}
-
-static void
-mark_cvc_tbl(void *objspace, VALUE klass)
-{
- struct rb_id_table *tbl = RCLASS_CVC_TBL(klass);
- if (tbl) {
- rb_id_table_foreach_values(tbl, mark_cvc_tbl_i, objspace);
- }
-}
-
static bool
gc_declarative_marking_p(const rb_data_type_t *type)
{
return (type->flags & RUBY_TYPED_DECL_MARKING) != 0;
}
-static enum rb_id_table_iterator_result
-mark_const_table_i(VALUE value, void *objspace)
-{
- const rb_const_entry_t *ce = (const rb_const_entry_t *)value;
-
- gc_mark_internal(ce->value);
- gc_mark_internal(ce->file);
-
- return ID_TABLE_CONTINUE;
-}
-
void
rb_gc_mark_roots(void *objspace, const char **categoryp)
{
@@ -2875,11 +3006,62 @@ rb_gc_mark_roots(void *objspace, const char **categoryp)
#undef MARK_CHECKPOINT
}
#define TYPED_DATA_REFS_OFFSET_LIST(d) (size_t *)(uintptr_t)RTYPEDDATA_TYPE(d)->function.dmark
void
rb_gc_mark_children(void *objspace, VALUE obj)
{
if (FL_TEST_RAW(obj, FL_EXIVAR)) {
rb_mark_generic_ivar(obj);
}
@@ -2920,42 +3102,21 @@ rb_gc_mark_children(void *objspace, VALUE obj)
}
// Continue to the shared T_CLASS/T_MODULE
case T_MODULE:
- if (RCLASS_SUPER(obj)) {
- gc_mark_internal(RCLASS_SUPER(obj));
- }
- mark_m_tbl(objspace, RCLASS_M_TBL(obj));
- mark_cvc_tbl(objspace, obj);
- rb_cc_table_mark(obj);
- if (rb_shape_obj_too_complex_p(obj)) {
- gc_mark_tbl_no_pin((st_table *)RCLASS_FIELDS(obj));
- }
- else {
for (attr_index_t i = 0; i < RCLASS_FIELDS_COUNT(obj); i++) {
- gc_mark_internal(RCLASS_FIELDS(obj)[i]);
}
}
-
- if (RCLASS_CONST_TBL(obj)) {
- rb_id_table_foreach_values(RCLASS_CONST_TBL(obj), mark_const_table_i, objspace);
- }
-
- gc_mark_internal(RCLASS_EXT(obj)->classpath);
break;
case T_ICLASS:
- if (RICLASS_OWNS_M_TBL_P(obj)) {
- mark_m_tbl(objspace, RCLASS_M_TBL(obj));
- }
- if (RCLASS_SUPER(obj)) {
- gc_mark_internal(RCLASS_SUPER(obj));
- }
-
- if (RCLASS_INCLUDER(obj)) {
- gc_mark_internal(RCLASS_INCLUDER(obj));
- }
- mark_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj));
- rb_cc_table_mark(obj);
break;
case T_ARRAY:
@@ -3031,8 +3192,8 @@ rb_gc_mark_children(void *objspace, VALUE obj)
VALUE klass = RBASIC_CLASS(obj);
// Increment max_iv_count if applicable, used to determine size pool allocation
- if (RCLASS_EXT(klass)->max_iv_count < fields_count) {
- RCLASS_EXT(klass)->max_iv_count = fields_count;
}
}
@@ -3482,12 +3643,10 @@ update_cc_tbl_i(VALUE ccs_ptr, void *objspace)
}
static void
-update_cc_tbl(void *objspace, VALUE klass)
{
- struct rb_id_table *tbl = RCLASS_CC_TBL(klass);
- if (tbl) {
- rb_id_table_foreach_values(tbl, update_cc_tbl_i, objspace);
- }
}
static enum rb_id_table_iterator_result
@@ -3507,16 +3666,14 @@ update_cvc_tbl_i(VALUE cvc_entry, void *objspace)
}
static void
-update_cvc_tbl(void *objspace, VALUE klass)
{
- struct rb_id_table *tbl = RCLASS_CVC_TBL(klass);
- if (tbl) {
- rb_id_table_foreach_values(tbl, update_cvc_tbl_i, objspace);
- }
}
static enum rb_id_table_iterator_result
-update_const_table(VALUE value, void *objspace)
{
rb_const_entry_t *ce = (rb_const_entry_t *)value;
@@ -3535,35 +3692,93 @@ static void
update_const_tbl(void *objspace, struct rb_id_table *tbl)
{
if (!tbl) return;
- rb_id_table_foreach_values(tbl, update_const_table, objspace);
}
static void
-update_subclass_entries(void *objspace, rb_subclass_entry_t *entry)
{
while (entry) {
- UPDATE_IF_MOVED(objspace, entry->klass);
entry = entry->next;
}
}
static void
-update_class_ext(void *objspace, rb_classext_t *ext)
{
- UPDATE_IF_MOVED(objspace, ext->origin_);
- UPDATE_IF_MOVED(objspace, ext->includer);
- UPDATE_IF_MOVED(objspace, ext->refined_class);
- update_subclass_entries(objspace, ext->subclasses);
}
static void
-update_superclasses(void *objspace, VALUE obj)
{
- if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) {
- for (size_t i = 0; i < RCLASS_SUPERCLASS_DEPTH(obj) + 1; i++) {
- UPDATE_IF_MOVED(objspace, RCLASS_SUPERCLASSES(obj)[i]);
}
}
}
extern rb_symbols_t ruby_global_symbols;
@@ -3884,6 +4099,8 @@ rb_gc_update_vm_references(void *objspace)
void
rb_gc_update_object_references(void *objspace, VALUE obj)
{
switch (BUILTIN_TYPE(obj)) {
case T_CLASS:
if (FL_TEST_RAW(obj, FL_SINGLETON)) {
@@ -3891,39 +4108,15 @@ rb_gc_update_object_references(void *objspace, VALUE obj)
}
// Continue to the shared T_CLASS/T_MODULE
case T_MODULE:
- if (RCLASS_SUPER((VALUE)obj)) {
- UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
- }
- update_m_tbl(objspace, RCLASS_M_TBL(obj));
- update_cc_tbl(objspace, obj);
- update_cvc_tbl(objspace, obj);
- update_superclasses(objspace, obj);
-
- if (rb_shape_obj_too_complex_p(obj)) {
- gc_ref_update_table_values_only(RCLASS_FIELDS_HASH(obj));
- }
- else {
- for (attr_index_t i = 0; i < RCLASS_FIELDS_COUNT(obj); i++) {
- UPDATE_IF_MOVED(objspace, RCLASS_FIELDS(obj)[i]);
- }
- }
-
- update_class_ext(objspace, RCLASS_EXT(obj));
- update_const_tbl(objspace, RCLASS_CONST_TBL(obj));
-
- UPDATE_IF_MOVED(objspace, RCLASS_EXT(obj)->classpath);
break;
case T_ICLASS:
- if (RICLASS_OWNS_M_TBL_P(obj)) {
- update_m_tbl(objspace, RCLASS_M_TBL(obj));
- }
- if (RCLASS_SUPER((VALUE)obj)) {
- UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
- }
- update_class_ext(objspace, RCLASS_EXT(obj));
- update_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj));
- update_cc_tbl(objspace, obj);
break;
case T_IMEMO:
@@ -170,13 +170,14 @@ rb_imemo_memsize(VALUE obj)
static enum rb_id_table_iterator_result
cc_table_mark_i(VALUE ccs_ptr, void *data)
{
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
VM_ASSERT(vm_ccs_p(ccs));
#if VM_CHECK_MODE > 0
VALUE klass = (VALUE)data;
VALUE lookup_val;
- VM_ASSERT(rb_id_table_lookup(RCLASS_CC_TBL(klass), ccs->cme->called_id, &lookup_val));
VM_ASSERT(lookup_val == ccs_ptr);
#endif
@@ -200,7 +201,8 @@ cc_table_mark_i(VALUE ccs_ptr, void *data)
void
rb_cc_table_mark(VALUE klass)
{
- struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
if (cc_tbl) {
rb_id_table_foreach_values(cc_tbl, cc_table_mark_i, (void *)klass);
}
@@ -492,7 +494,10 @@ cc_table_free_i(VALUE ccs_ptr, void *data)
void
rb_cc_table_free(VALUE klass)
{
- struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
if (cc_tbl) {
rb_id_table_foreach_values(cc_tbl, cc_table_free_i, (void *)klass);
@@ -501,6 +506,14 @@ rb_cc_table_free(VALUE klass)
}
void
rb_imemo_free(VALUE obj)
{
switch (imemo_type(obj)) {
@@ -84,6 +84,8 @@ RUBY_EXTERN VALUE rb_cMethod; /**< `Method` class. */
RUBY_EXTERN VALUE rb_cModule; /**< `Module` class. */
RUBY_EXTERN VALUE rb_cRefinement; /**< `Refinement` class. */
RUBY_EXTERN VALUE rb_cNameErrorMesg; /**< `NameError::Message` class. */
RUBY_EXTERN VALUE rb_cNilClass; /**< `NilClass` class. */
RUBY_EXTERN VALUE rb_cNumeric; /**< `Numeric` class. */
RUBY_EXTERN VALUE rb_cProc; /**< `Proc` class. */
@@ -77,6 +77,7 @@ rb_call_inits(void)
CALL(Prism);
CALL(unicode_version);
CALL(Set);
// enable builtin loading
CALL(builtin);
@@ -10,6 +10,7 @@
*/
#include "id.h"
#include "id_table.h" /* for struct rb_id_table */
#include "internal/serial.h" /* for rb_serial_t */
#include "internal/static_assert.h"
#include "internal/variable.h" /* for rb_class_ivar_set */
@@ -26,6 +27,41 @@
# undef RCLASS_SUPER
#endif
struct rb_subclass_entry {
VALUE klass;
struct rb_subclass_entry *next;
@@ -41,21 +77,36 @@ struct rb_cvar_class_tbl_entry {
};
struct rb_classext_struct {
VALUE *fields; // Fields are either ivar or other internal properties stored inline
struct rb_id_table *const_tbl;
struct rb_id_table *callable_m_tbl;
struct rb_id_table *cc_tbl; /* ID -> [[ci1, cc1], [ci2, cc2] ...] */
struct rb_id_table *cvc_tbl;
size_t superclass_depth;
VALUE *superclasses;
- struct rb_subclass_entry *subclasses;
- struct rb_subclass_entry *subclass_entry;
/**
- * 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.
*/
- struct rb_subclass_entry *module_subclass_entry;
const VALUE origin_;
const VALUE refined_class;
union {
@@ -71,6 +122,11 @@ struct rb_classext_struct {
unsigned char variation_count;
bool permanent_classpath : 1;
bool cloned : 1;
VALUE classpath;
};
typedef struct rb_classext_struct rb_classext_t;
@@ -79,92 +135,333 @@ STATIC_ASSERT(shape_max_variations, SHAPE_MAX_VARIATIONS < (1 << (sizeof(((rb_cl
struct RClass {
struct RBasic basic;
- VALUE super;
- struct rb_id_table *m_tbl;
};
-// Assert that classes can be embedded in heaps[2] (which has 160B slot size)
-STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t) <= 4 * RVALUE_SIZE);
struct RClass_and_rb_classext_t {
struct RClass rclass;
rb_classext_t classext;
};
#define RCLASS_EXT(c) (&((struct RClass_and_rb_classext_t*)(c))->classext)
-#define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
-#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
-#define RCLASS_FIELDS(c) (RCLASS_EXT(c)->fields)
-#define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
-#define RCLASS_CC_TBL(c) (RCLASS_EXT(c)->cc_tbl)
-#define RCLASS_CVC_TBL(c) (RCLASS_EXT(c)->cvc_tbl)
-#define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_)
#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
-#define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
-#define RCLASS_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->subclass_entry)
-#define RCLASS_MODULE_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->module_subclass_entry)
-#define RCLASS_SUBCLASSES(c) (RCLASS_EXT(c)->subclasses)
-#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT(c)->superclass_depth)
-#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT(c)->superclasses)
#define RCLASS_ATTACHED_OBJECT(c) (RCLASS_EXT(c)->as.singleton_class.attached_object)
#define RCLASS_IS_ROOT FL_USER0
-#define RICLASS_IS_ORIGIN FL_USER0
-#define RCLASS_SUPERCLASSES_INCLUDE_SELF FL_USER2
-#define RICLASS_ORIGIN_SHARED_MTBL FL_USER3
-static inline st_table *
-RCLASS_FIELDS_HASH(VALUE obj)
{
- RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
- RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
- return (st_table *)RCLASS_FIELDS(obj);
}
static inline void
-RCLASS_SET_FIELDS_HASH(VALUE obj, const st_table *tbl)
{
- RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
- RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
- RCLASS_FIELDS(obj) = (VALUE *)tbl;
}
-static inline uint32_t
-RCLASS_FIELDS_COUNT(VALUE obj)
{
- RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
- if (rb_shape_obj_too_complex_p(obj)) {
- uint32_t count;
- // "Too complex" classes could have their IV hash mutated in
- // parallel, so lets lock around getting the hash size.
- RB_VM_LOCK_ENTER();
- {
- count = (uint32_t)rb_st_table_size(RCLASS_FIELDS_HASH(obj));
}
- RB_VM_LOCK_LEAVE();
- return count;
}
- else {
- return RSHAPE(RCLASS_SHAPE_ID(obj))->next_field_index;
}
}
static inline void
-RCLASS_SET_M_TBL(VALUE klass, struct rb_id_table *table)
{
- RUBY_ASSERT(!RB_OBJ_PROMOTED(klass));
- RCLASS_M_TBL(klass) = table;
}
/* class.c */
void rb_class_subclass_add(VALUE super, VALUE klass);
void rb_class_remove_from_super_subclasses(VALUE);
void rb_class_update_superclasses(VALUE);
size_t rb_class_superclasses_memsize(VALUE);
void rb_class_remove_subclass_head(VALUE);
int rb_singleton_class_internal_p(VALUE sklass);
VALUE rb_class_boot(VALUE);
VALUE rb_class_s_alloc(VALUE klass);
VALUE rb_module_s_alloc(VALUE klass);
@@ -172,10 +469,6 @@ void rb_module_set_initialized(VALUE module);
void rb_module_check_initializable(VALUE module);
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_define_class_id_under_no_pin(VALUE outer, ID id, VALUE super);
VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj);
VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj);
@@ -186,22 +479,152 @@ VALUE rb_special_singleton_class(VALUE);
VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
VALUE rb_singleton_class_get(VALUE obj);
void rb_undef_methods_from(VALUE klass, VALUE super);
-
-static inline void RCLASS_SET_ORIGIN(VALUE klass, VALUE origin);
-static inline void RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass);
-static inline VALUE RCLASS_SUPER(VALUE klass);
-static inline VALUE RCLASS_SET_SUPER(VALUE klass, VALUE super);
-static inline void RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass);
-
VALUE rb_class_inherited(VALUE, VALUE);
VALUE rb_keyword_error_new(const char *, VALUE);
static inline bool
RCLASS_SINGLETON_P(VALUE klass)
{
return RB_TYPE_P(klass, T_CLASS) && FL_TEST_RAW(klass, FL_SINGLETON);
}
static inline rb_alloc_func_t
RCLASS_ALLOCATOR(VALUE klass)
{
@@ -215,26 +638,42 @@ static inline void
RCLASS_SET_ALLOCATOR(VALUE klass, rb_alloc_func_t allocator)
{
assert(!RCLASS_SINGLETON_P(klass));
- RCLASS_EXT(klass)->as.class.allocator = allocator;
}
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
RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass)
{
- FL_SET(iclass, RICLASS_ORIGIN_SHARED_MTBL);
}
static inline bool
RICLASS_OWNS_M_TBL_P(VALUE iclass)
{
- return FL_TEST_RAW(iclass, RICLASS_IS_ORIGIN | RICLASS_ORIGIN_SHARED_MTBL) == RICLASS_IS_ORIGIN;
}
static inline void
@@ -243,32 +682,61 @@ RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass)
RB_OBJ_WRITE(iclass, &RCLASS_INCLUDER(iclass), klass);
}
-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);
- rb_class_update_superclasses(klass);
- return super;
}
static inline void
RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent)
{
assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE);
assert(classpath == 0 || BUILTIN_TYPE(classpath) == T_STRING);
- RB_OBJ_WRITE(klass, &(RCLASS_EXT(klass)->classpath), classpath);
- RCLASS_EXT(klass)->permanent_classpath = permanent;
}
static inline VALUE
@@ -280,4 +748,22 @@ RCLASS_SET_ATTACHED_OBJECT(VALUE klass, VALUE attached_object)
return attached_object;
}
#endif /* INTERNAL_CLASS_H */
@@ -16,11 +16,18 @@
#define id_status ruby_static_id_status
/* eval.c */
extern ID ruby_static_id_signo;
extern ID ruby_static_id_status;
VALUE rb_refinement_module_get_refined_class(VALUE module);
void rb_class_modify_check(VALUE);
NORETURN(VALUE rb_f_raise(int argc, VALUE *argv));
VALUE rb_top_main_class(const char *method);
/* eval_error.c */
@@ -10,6 +10,7 @@
*/
#include "ruby/internal/config.h"
#include <stddef.h> /* for size_t */
#include "internal/array.h" /* for rb_ary_hidden_new_fill */
#include "ruby/internal/stdbool.h" /* for bool */
#include "ruby/ruby.h" /* for rb_block_call_func_t */
@@ -24,6 +25,7 @@
#define IMEMO_FL_USER3 FL_USER7
#define IMEMO_FL_USER4 FL_USER8
#define IMEMO_FL_USER5 FL_USER9
enum imemo_type {
imemo_env = 0,
@@ -149,6 +151,7 @@ size_t rb_imemo_memsize(VALUE obj);
void rb_cc_table_mark(VALUE klass);
void rb_imemo_mark_and_move(VALUE obj, bool reference_updating);
void rb_cc_table_free(VALUE klass);
void rb_imemo_free(VALUE obj);
RUBY_SYMBOL_EXPORT_BEGIN
@@ -12,6 +12,8 @@
/* load.c */
VALUE rb_get_expanded_load_path(void);
int rb_require_internal(VALUE fname);
NORETURN(void rb_load_fail(VALUE, const char*));
@@ -0,0 +1,80 @@
@@ -23,11 +23,13 @@ VALUE rb_search_class_path(VALUE);
VALUE rb_attr_delete(VALUE, ID);
void rb_autoload_str(VALUE mod, ID id, VALUE file);
VALUE rb_autoload_at_p(VALUE, ID, int);
NORETURN(VALUE rb_mod_const_missing(VALUE,VALUE));
rb_gvar_getter_t *rb_gvar_getter_function_of(ID);
rb_gvar_setter_t *rb_gvar_setter_function_of(ID);
void rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_);
void rb_gvar_ractor_local(const char *name);
/**
* Sets the name of a module.
@@ -77,6 +77,7 @@ void rb_check_stack_overflow(void);
#define RB_BLOCK_NO_USE_PACKED_ARGS 2
VALUE rb_block_call2(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t bl_proc, VALUE data2, long flags);
struct vm_ifunc *rb_current_ifunc(void);
#if USE_YJIT
/* vm_exec.c */
@@ -2919,7 +2919,7 @@ rb_estimate_iv_count(VALUE klass, const rb_iseq_t * initialize_iseq)
attr_index_t count = (attr_index_t)rb_id_table_size(iv_names);
VALUE superclass = rb_class_superclass(klass);
- count += RCLASS_EXT(superclass)->max_iv_count;
rb_id_table_free(iv_names);
@@ -219,6 +219,7 @@ class Gem::Package
# Adds a checksum for each entry in the gem to checksums.yaml.gz.
def add_checksums(tar)
Gem.load_yaml
checksums_by_algorithm = Hash.new {|h, algorithm| h[algorithm] = {} }
@@ -552,6 +553,7 @@ EOM
# Reads and loads checksums.yaml.gz from the tar file +gem+
def read_checksums(gem)
Gem.load_yaml
@checksums = gem.seek "checksums.yaml.gz" do |entry|
@@ -1,5 +1,7 @@
# frozen_string_literal: true
module Gem
###
# This module is used for safely loading YAML specs from a gem. The
@@ -7,9 +7,11 @@
#include "internal.h"
#include "internal/dir.h"
#include "internal/error.h"
#include "internal/file.h"
#include "internal/hash.h"
#include "internal/load.h"
#include "internal/ruby_parser.h"
#include "internal/thread.h"
#include "internal/variable.h"
@@ -19,6 +21,7 @@
#include "ruby/encoding.h"
#include "ruby/util.h"
#include "ractor_core.h"
static VALUE ruby_dln_libmap;
@@ -36,6 +39,38 @@ static VALUE ruby_dln_libmap;
# error Need integer for VALUE
#endif
enum {
loadable_ext_rb = (0+ /* .rb extension is the first in both tables */
1) /* offset by rb_find_file_ext() */
@@ -64,10 +99,11 @@ enum expand_type {
string objects in $LOAD_PATH are frozen.
*/
static void
-rb_construct_expanded_load_path(rb_vm_t *vm, enum expand_type type, int *has_relative, int *has_non_cache)
{
- VALUE load_path = vm->load_path;
- VALUE expanded_load_path = vm->expanded_load_path;
VALUE ary;
long i;
@@ -106,108 +142,117 @@ rb_construct_expanded_load_path(rb_vm_t *vm, enum expand_type type, int *has_rel
rb_ary_push(ary, rb_fstring(expanded_path));
}
rb_ary_freeze(ary);
- vm->expanded_load_path = ary;
- rb_ary_replace(vm->load_path_snapshot, vm->load_path);
}
static VALUE
-get_expanded_load_path(rb_vm_t *vm)
{
const VALUE non_cache = Qtrue;
- if (!rb_ary_shared_with_p(vm->load_path_snapshot, vm->load_path)) {
/* The load path was modified. Rebuild the expanded load path. */
int has_relative = 0, has_non_cache = 0;
- rb_construct_expanded_load_path(vm, EXPAND_ALL, &has_relative, &has_non_cache);
if (has_relative) {
- vm->load_path_check_cache = rb_dir_getwd_ospath();
}
else if (has_non_cache) {
/* Non string object. */
- vm->load_path_check_cache = non_cache;
}
else {
- vm->load_path_check_cache = 0;
}
}
- else if (vm->load_path_check_cache == non_cache) {
int has_relative = 1, has_non_cache = 1;
/* Expand only non-cacheable objects. */
- rb_construct_expanded_load_path(vm, EXPAND_NON_CACHE,
&has_relative, &has_non_cache);
}
- else if (vm->load_path_check_cache) {
int has_relative = 1, has_non_cache = 1;
VALUE cwd = rb_dir_getwd_ospath();
- if (!rb_str_equal(vm->load_path_check_cache, cwd)) {
/* Current working directory or filesystem encoding was changed.
Expand relative load path and non-cacheable objects again. */
- vm->load_path_check_cache = cwd;
- rb_construct_expanded_load_path(vm, EXPAND_RELATIVE,
&has_relative, &has_non_cache);
}
else {
/* Expand only tilde (User HOME) and non-cacheable objects. */
- rb_construct_expanded_load_path(vm, EXPAND_HOME,
&has_relative, &has_non_cache);
}
}
- return vm->expanded_load_path;
}
VALUE
rb_get_expanded_load_path(void)
{
- return get_expanded_load_path(GET_VM());
}
static VALUE
load_path_getter(ID id, VALUE * p)
{
- rb_vm_t *vm = (void *)p;
- return vm->load_path;
}
static VALUE
-get_loaded_features(rb_vm_t *vm)
{
- return vm->loaded_features;
}
static VALUE
-get_loaded_features_realpaths(rb_vm_t *vm)
{
- return vm->loaded_features_realpaths;
}
static VALUE
-get_loaded_features_realpath_map(rb_vm_t *vm)
{
- return vm->loaded_features_realpath_map;
}
static VALUE
get_LOADED_FEATURES(ID _x, VALUE *_y)
{
- return get_loaded_features(GET_VM());
}
static void
-reset_loaded_features_snapshot(rb_vm_t *vm)
{
- rb_ary_replace(vm->loaded_features_snapshot, vm->loaded_features);
}
static struct st_table *
-get_loaded_features_index_raw(rb_vm_t *vm)
{
- return vm->loaded_features_index;
}
static st_table *
-get_loading_table(rb_vm_t *vm)
{
- return vm->loading_table;
}
static st_data_t
@@ -228,7 +273,7 @@ is_rbext_path(VALUE feature_path)
typedef rb_darray(long) feature_indexes_t;
struct features_index_add_single_args {
- rb_vm_t *vm;
VALUE offset;
bool rb;
};
@@ -237,7 +282,7 @@ static int
features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t raw_args, int existing)
{
struct features_index_add_single_args *args = (struct features_index_add_single_args *)raw_args;
- rb_vm_t *vm = args->vm;
VALUE offset = args->offset;
bool rb = args->rb;
@@ -245,7 +290,7 @@ features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t r
VALUE this_feature_index = *value;
if (FIXNUM_P(this_feature_index)) {
- VALUE loaded_features = get_loaded_features(vm);
VALUE this_feature_path = RARRAY_AREF(loaded_features, FIX2LONG(this_feature_index));
feature_indexes_t feature_indexes;
@@ -265,7 +310,7 @@ features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t r
long pos = -1;
if (rb) {
- VALUE loaded_features = get_loaded_features(vm);
for (size_t i = 0; i < rb_darray_size(feature_indexes); ++i) {
long idx = rb_darray_get(feature_indexes, i);
VALUE this_feature_path = RARRAY_AREF(loaded_features, idx);
@@ -297,7 +342,7 @@ features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t r
}
static void
-features_index_add_single(rb_vm_t *vm, const char* str, size_t len, VALUE offset, bool rb)
{
struct st_table *features_index;
st_data_t short_feature_key;
@@ -305,10 +350,10 @@ features_index_add_single(rb_vm_t *vm, const char* str, size_t len, VALUE offset
Check_Type(offset, T_FIXNUM);
short_feature_key = feature_key(str, len);
- features_index = get_loaded_features_index_raw(vm);
struct features_index_add_single_args args = {
- .vm = vm,
.offset = offset,
.rb = rb,
};
@@ -325,7 +370,7 @@ features_index_add_single(rb_vm_t *vm, const char* str, size_t len, VALUE offset
relies on for its fast lookup.
*/
static void
-features_index_add(rb_vm_t *vm, VALUE feature, VALUE offset)
{
const char *feature_str, *feature_end, *ext, *p;
bool rb = false;
@@ -351,14 +396,14 @@ features_index_add(rb_vm_t *vm, VALUE feature, VALUE offset)
if (p < feature_str)
break;
/* Now *p == '/'. We reach this point for every '/' in `feature`. */
- features_index_add_single(vm, p + 1, feature_end - p - 1, offset, false);
if (ext) {
- features_index_add_single(vm, p + 1, ext - p - 1, offset, rb);
}
}
- features_index_add_single(vm, feature_str, feature_end - feature_str, offset, false);
if (ext) {
- features_index_add_single(vm, feature_str, ext - feature_str, offset, rb);
}
}
@@ -375,27 +420,31 @@ loaded_features_index_clear_i(st_data_t key, st_data_t val, st_data_t arg)
void
rb_free_loaded_features_index(rb_vm_t *vm)
{
st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);
st_free_table(vm->loaded_features_index);
}
static st_table *
-get_loaded_features_index(rb_vm_t *vm)
{
- VALUE features;
int i;
- if (!rb_ary_shared_with_p(vm->loaded_features_snapshot, vm->loaded_features)) {
/* The sharing was broken; something (other than us in rb_provide_feature())
modified loaded_features. Rebuild the index. */
- st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);
- VALUE realpaths = vm->loaded_features_realpaths;
- VALUE realpath_map = vm->loaded_features_realpath_map;
VALUE previous_realpath_map = rb_hash_dup(realpath_map);
rb_hash_clear(realpaths);
rb_hash_clear(realpath_map);
- features = vm->loaded_features;
for (i = 0; i < RARRAY_LEN(features); i++) {
VALUE entry, as_str;
as_str = entry = rb_ary_entry(features, i);
@@ -403,11 +452,11 @@ get_loaded_features_index(rb_vm_t *vm)
as_str = rb_fstring(as_str);
if (as_str != entry)
rb_ary_store(features, i, as_str);
- features_index_add(vm, as_str, INT2FIX(i));
}
- reset_loaded_features_snapshot(vm);
- features = rb_ary_dup(vm->loaded_features_snapshot);
long j = RARRAY_LEN(features);
for (i = 0; i < j; i++) {
VALUE as_str = rb_ary_entry(features, i);
@@ -421,7 +470,7 @@ get_loaded_features_index(rb_vm_t *vm)
rb_hash_aset(realpath_map, as_str, realpath);
}
}
- return vm->loaded_features_index;
}
/* This searches `load_path` for a value such that
@@ -506,7 +555,7 @@ loaded_feature_path_i(st_data_t v, st_data_t b, st_data_t f)
* 'u': unsuffixed
*/
static int
-rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn)
{
VALUE features, this_feature_index = Qnil, v, p, load_path = 0;
const char *f, *e;
@@ -527,8 +576,8 @@ rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expa
elen = 0;
type = 0;
}
- features = get_loaded_features(vm);
- features_index = get_loaded_features_index(vm);
key = feature_key(feature, strlen(feature));
/* We search `features` for an entry such that either
@@ -575,7 +624,7 @@ rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expa
if ((n = RSTRING_LEN(v)) < len) continue;
if (strncmp(f, feature, len) != 0) {
if (expanded) continue;
- if (!load_path) load_path = get_expanded_load_path(vm);
if (!(p = loaded_feature_path(f, n, feature, len, type, load_path)))
continue;
expanded = 1;
@@ -595,14 +644,14 @@ rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expa
}
}
- loading_tbl = get_loading_table(vm);
f = 0;
if (!expanded && !rb_is_absolute_path(feature)) {
struct loaded_feature_searching fs;
fs.name = feature;
fs.len = len;
fs.type = type;
- fs.load_path = load_path ? load_path : get_expanded_load_path(vm);
fs.result = 0;
st_foreach(loading_tbl, loaded_feature_path_i, (st_data_t)&fs);
if ((f = fs.result) != 0) {
@@ -657,7 +706,7 @@ rb_provided(const char *feature)
}
static int
-feature_provided(rb_vm_t *vm, const char *feature, const char **loading)
{
const char *ext = strrchr(feature, '.');
VALUE fullpath = 0;
@@ -669,15 +718,15 @@ feature_provided(rb_vm_t *vm, const char *feature, const char **loading)
}
if (ext && !strchr(ext, '/')) {
if (IS_RBEXT(ext)) {
- if (rb_feature_p(vm, feature, ext, TRUE, FALSE, loading)) return TRUE;
return FALSE;
}
else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {
- if (rb_feature_p(vm, feature, ext, FALSE, FALSE, loading)) return TRUE;
return FALSE;
}
}
- if (rb_feature_p(vm, feature, 0, TRUE, FALSE, loading))
return TRUE;
RB_GC_GUARD(fullpath);
return FALSE;
@@ -686,35 +735,41 @@ feature_provided(rb_vm_t *vm, const char *feature, const char **loading)
int
rb_feature_provided(const char *feature, const char **loading)
{
- return feature_provided(GET_VM(), feature, loading);
}
static void
-rb_provide_feature(rb_vm_t *vm, VALUE feature)
{
VALUE features;
- features = get_loaded_features(vm);
if (OBJ_FROZEN(features)) {
rb_raise(rb_eRuntimeError,
"$LOADED_FEATURES is frozen; cannot append feature");
}
feature = rb_fstring(feature);
- get_loaded_features_index(vm);
// If loaded_features and loaded_features_snapshot share the same backing
// array, pushing into it would cause the whole array to be copied.
// To avoid this we first clear loaded_features_snapshot.
- rb_ary_clear(vm->loaded_features_snapshot);
rb_ary_push(features, feature);
- features_index_add(vm, feature, INT2FIX(RARRAY_LEN(features)-1));
- reset_loaded_features_snapshot(vm);
}
void
rb_provide(const char *feature)
{
- rb_provide_feature(GET_VM(), rb_fstring_cstr(feature));
}
NORETURN(static void load_failed(VALUE));
@@ -732,17 +787,34 @@ realpath_internal_cached(VALUE hash, VALUE path)
return realpath;
}
static inline void
load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
{
const rb_iseq_t *iseq = rb_iseq_load_iseq(fname);
if (!iseq) {
rb_execution_context_t *ec = GET_EC();
VALUE v = rb_vm_push_frame_fname(ec, fname);
- rb_thread_t *th = rb_ec_thread_ptr(ec);
- VALUE realpath_map = get_loaded_features_realpath_map(th->vm);
if (rb_ruby_prism_p()) {
pm_parse_result_t result = { 0 };
@@ -786,13 +858,23 @@ load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
RB_GC_GUARD(v);
}
rb_exec_event_hook_script_compiled(ec, iseq, Qnil);
- rb_iseq_eval(iseq);
}
static inline enum ruby_tag_type
load_wrapping(rb_execution_context_t *ec, VALUE fname, VALUE load_wrapper)
{
enum ruby_tag_type state;
rb_thread_t *th = rb_ec_thread_ptr(ec);
volatile VALUE wrapper = th->top_wrapper;
volatile VALUE self = th->top_self;
@@ -803,7 +885,15 @@ load_wrapping(rb_execution_context_t *ec, VALUE fname, VALUE load_wrapper)
ec->errinfo = Qnil; /* ensure */
/* load in module as toplevel */
- th->top_self = rb_obj_clone(rb_vm_top_self());
th->top_wrapper = load_wrapper;
rb_extend_object(th->top_self, th->top_wrapper);
@@ -838,7 +928,9 @@ raise_load_if_failed(rb_execution_context_t *ec, enum ruby_tag_type state)
static void
rb_load_internal(VALUE fname, VALUE wrap)
{
rb_execution_context_t *ec = GET_EC();
enum ruby_tag_type state = TAG_NONE;
if (RTEST(wrap)) {
if (!RB_TYPE_P(wrap, T_MODULE)) {
@@ -846,6 +938,10 @@ rb_load_internal(VALUE fname, VALUE wrap)
}
state = load_wrapping(ec, fname, wrap);
}
else {
load_iseq_eval(ec, fname);
}
@@ -874,6 +970,40 @@ rb_load_protect(VALUE fname, int wrap, int *pstate)
if (state != TAG_NONE) *pstate = state;
}
/*
* call-seq:
* load(filename, wrap=false) -> true
@@ -907,32 +1037,16 @@ rb_load_protect(VALUE fname, int wrap, int *pstate)
static VALUE
rb_f_load(int argc, VALUE *argv, VALUE _)
{
- VALUE fname, wrap, path, orig_fname;
-
rb_scan_args(argc, argv, "11", &fname, &wrap);
-
- orig_fname = rb_get_path_check_to_string(fname);
- fname = rb_str_encode_ospath(orig_fname);
- RUBY_DTRACE_HOOK(LOAD_ENTRY, RSTRING_PTR(orig_fname));
-
- path = rb_find_file(fname);
- if (!path) {
- if (!rb_file_load_ok(RSTRING_PTR(fname)))
- load_failed(orig_fname);
- path = fname;
- }
- rb_load_internal(path, wrap);
-
- RUBY_DTRACE_HOOK(LOAD_RETURN, RSTRING_PTR(orig_fname));
-
- return Qtrue;
}
static char *
-load_lock(rb_vm_t *vm, const char *ftptr, bool warn)
{
st_data_t data;
- st_table *loading_tbl = get_loading_table(vm);
if (!st_lookup(loading_tbl, (st_data_t)ftptr, &data)) {
/* partial state */
@@ -974,11 +1088,11 @@ release_thread_shield(st_data_t *key, st_data_t *value, st_data_t done, int exis
}
static void
-load_unlock(rb_vm_t *vm, const char *ftptr, int done)
{
if (ftptr) {
st_data_t key = (st_data_t)ftptr;
- st_table *loading_tbl = get_loading_table(vm);
st_update(loading_tbl, key, release_thread_shield, done);
}
@@ -1026,9 +1140,22 @@ static VALUE rb_require_string_internal(VALUE fname, bool resurrect);
VALUE
rb_f_require(VALUE obj, VALUE fname)
{
return rb_require_string(fname);
}
/*
* call-seq:
* require_relative(string) -> true or false
@@ -1041,18 +1168,13 @@ rb_f_require(VALUE obj, VALUE fname)
VALUE
rb_f_require_relative(VALUE obj, VALUE fname)
{
- VALUE base = rb_current_realfilepath();
- if (NIL_P(base)) {
- rb_loaderror("cannot infer basepath");
- }
- base = rb_file_dirname(base);
- return rb_require_string_internal(rb_file_absolute_path(fname, base), false);
}
-typedef int (*feature_func)(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn);
static int
-search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_feature_p)
{
VALUE tmp;
char *ext, *ftptr;
@@ -1063,20 +1185,20 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
ext = strrchr(ftptr = RSTRING_PTR(fname), '.');
if (ext && !strchr(ext, '/')) {
if (IS_RBEXT(ext)) {
- if (rb_feature_p(vm, ftptr, ext, TRUE, FALSE, &loading)) {
if (loading) *path = rb_filesystem_str_new_cstr(loading);
return 'r';
}
if ((tmp = rb_find_file(fname)) != 0) {
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
- if (!rb_feature_p(vm, ftptr, ext, TRUE, TRUE, &loading) || loading)
*path = tmp;
return 'r';
}
return 0;
}
else if (IS_SOEXT(ext)) {
- if (rb_feature_p(vm, ftptr, ext, FALSE, FALSE, &loading)) {
if (loading) *path = rb_filesystem_str_new_cstr(loading);
return 's';
}
@@ -1085,25 +1207,25 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
OBJ_FREEZE(tmp);
if ((tmp = rb_find_file(tmp)) != 0) {
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
- if (!rb_feature_p(vm, ftptr, ext, FALSE, TRUE, &loading) || loading)
*path = tmp;
return 's';
}
}
else if (IS_DLEXT(ext)) {
- if (rb_feature_p(vm, ftptr, ext, FALSE, FALSE, &loading)) {
if (loading) *path = rb_filesystem_str_new_cstr(loading);
return 's';
}
if ((tmp = rb_find_file(fname)) != 0) {
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
- if (!rb_feature_p(vm, ftptr, ext, FALSE, TRUE, &loading) || loading)
*path = tmp;
return 's';
}
}
}
- else if ((ft = rb_feature_p(vm, ftptr, 0, FALSE, FALSE, &loading)) == 'r') {
if (loading) *path = rb_filesystem_str_new_cstr(loading);
return 'r';
}
@@ -1112,7 +1234,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
// Check if it's a statically linked extension when
// not already a feature and not found as a dynamic library.
- if (!ft && type != loadable_ext_rb && vm->static_ext_inits) {
VALUE lookup_name = tmp;
// Append ".so" if not already present so for example "etc" can find "etc.so".
// We always register statically linked extensions with a ".so" extension.
@@ -1122,7 +1244,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
rb_str_cat_cstr(lookup_name, ".so");
}
ftptr = RSTRING_PTR(lookup_name);
- if (st_lookup(vm->static_ext_inits, (st_data_t)ftptr, NULL)) {
*path = rb_filesystem_str_new_cstr(ftptr);
RB_GC_GUARD(lookup_name);
return 's';
@@ -1134,7 +1256,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
if (ft)
goto feature_present;
ftptr = RSTRING_PTR(tmp);
- return rb_feature_p(vm, ftptr, 0, FALSE, TRUE, 0);
default:
if (ft) {
@@ -1143,7 +1265,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
/* fall through */
case loadable_ext_rb:
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
- if (rb_feature_p(vm, ftptr, ext, type == loadable_ext_rb, TRUE, &loading) && !loading)
break;
*path = tmp;
}
@@ -1161,10 +1283,15 @@ load_failed(VALUE fname)
}
static VALUE
-load_ext(VALUE path)
{
rb_scope_visibility_set(METHOD_VISI_PUBLIC);
- return (VALUE)dln_load(RSTRING_PTR(path));
}
static bool
@@ -1181,7 +1308,7 @@ run_static_ext_init(rb_vm_t *vm, const char *feature)
}
static int
-no_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn)
{
return 0;
}
@@ -1193,10 +1320,11 @@ rb_resolve_feature_path(VALUE klass, VALUE fname)
VALUE path;
int found;
VALUE sym;
fname = rb_get_path(fname);
path = rb_str_encode_ospath(fname);
- found = search_required(GET_VM(), path, &path, no_feature_p);
switch (found) {
case 'r':
@@ -1231,6 +1359,20 @@ rb_ext_ractor_safe(bool flag)
GET_THREAD()->ext_config.ractor_safe = flag;
}
/*
* returns
* 0: if already loaded (false)
@@ -1250,13 +1392,14 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
th->top_wrapper, th->top_self, ec->errinfo,
ec,
};
enum ruby_tag_type state;
char *volatile ftptr = 0;
VALUE path;
volatile VALUE saved_path;
volatile VALUE realpath = 0;
- VALUE realpaths = get_loaded_features_realpaths(th->vm);
- VALUE realpath_map = get_loaded_features_realpath_map(th->vm);
volatile bool reset_ext_config = false;
struct rb_ext_config prev_ext_config;
@@ -1272,12 +1415,12 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
int found;
RUBY_DTRACE_HOOK(FIND_REQUIRE_ENTRY, RSTRING_PTR(fname));
- found = search_required(th->vm, path, &saved_path, rb_feature_p);
RUBY_DTRACE_HOOK(FIND_REQUIRE_RETURN, RSTRING_PTR(fname));
path = saved_path;
if (found) {
- if (!path || !(ftptr = load_lock(th->vm, RSTRING_PTR(path), warn))) {
result = 0;
}
else if (!*ftptr) {
@@ -1293,15 +1436,30 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
else {
switch (found) {
case 'r':
- load_iseq_eval(saved.ec, path);
break;
case 's':
reset_ext_config = true;
ext_config_push(th, &prev_ext_config);
- handle = rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
- path, VM_BLOCK_HANDLER_NONE, path);
- rb_hash_aset(ruby_dln_libmap, path, SVALUE2NUM((SIGNED_VALUE)handle));
break;
}
result = TAG_RETURN;
@@ -1317,7 +1475,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
if (reset_ext_config) ext_config_pop(th2, &prev_ext_config);
path = saved_path;
- if (ftptr) load_unlock(th2->vm, RSTRING_PTR(path), !state);
if (state) {
if (state == TAG_FATAL || state == TAG_THROW) {
@@ -1343,7 +1501,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
}
if (result == TAG_RETURN) {
- rb_provide_feature(th2->vm, path);
VALUE real = realpath;
if (real) {
real = rb_fstring(real);
@@ -1442,15 +1600,15 @@ void
ruby_init_ext(const char *name, void (*init)(void))
{
st_table *inits_table;
- rb_vm_t *vm = GET_VM();
- if (feature_provided(vm, name, 0))
return;
- inits_table = vm->static_ext_inits;
if (!inits_table) {
inits_table = st_init_strtable();
- vm->static_ext_inits = inits_table;
}
st_update(inits_table, (st_data_t)name, register_init_ext, (st_data_t)init);
}
@@ -1595,6 +1753,7 @@ rb_ext_resolve_symbol(const char* fname, const char* symbol)
VALUE path;
char *ext;
VALUE fname_str = rb_str_new_cstr(fname);
resolved = rb_resolve_feature_path((VALUE)NULL, fname_str);
if (NIL_P(resolved)) {
@@ -1602,7 +1761,7 @@ rb_ext_resolve_symbol(const char* fname, const char* symbol)
if (!ext || !IS_SOEXT(ext)) {
rb_str_cat_cstr(fname_str, ".so");
}
- if (rb_feature_p(GET_VM(), fname, 0, FALSE, FALSE, 0)) {
return dln_symbol(NULL, symbol);
}
return NULL;
@@ -1611,7 +1770,7 @@ rb_ext_resolve_symbol(const char* fname, const char* symbol)
return NULL;
}
path = rb_ary_entry(resolved, 1);
- handle = rb_hash_lookup(ruby_dln_libmap, path);
if (NIL_P(handle)) {
return NULL;
}
@@ -1626,6 +1785,7 @@ Init_load(void)
ID id_load_path = rb_intern2(var_load_path, sizeof(var_load_path)-1);
rb_define_hooked_variable(var_load_path, (VALUE*)vm, load_path_getter, rb_gvar_readonly_setter);
rb_alias_variable(rb_intern_const("$-I"), id_load_path);
rb_alias_variable(rb_intern_const("$LOAD_PATH"), id_load_path);
vm->load_path = rb_ary_new();
@@ -1635,7 +1795,9 @@ Init_load(void)
rb_define_singleton_method(vm->load_path, "resolve_feature_path", rb_resolve_feature_path, 1);
rb_define_virtual_variable("$\"", get_LOADED_FEATURES, 0);
- rb_define_virtual_variable("$LOADED_FEATURES", get_LOADED_FEATURES, 0);
vm->loaded_features = rb_ary_new();
vm->loaded_features_snapshot = rb_ary_hidden_new(0);
vm->loaded_features_index = st_init_numtable();
@@ -531,7 +531,7 @@ w_extended(VALUE klass, struct dump_arg *arg, int check)
klass = RCLASS_SUPER(klass);
}
while (BUILTIN_TYPE(klass) == T_ICLASS) {
- if (!FL_TEST(klass, RICLASS_IS_ORIGIN) ||
BUILTIN_TYPE(RBASIC(klass)->klass) != T_MODULE) {
VALUE path = rb_class_name(RBASIC(klass)->klass);
w_byte(TYPE_EXTENDED, arg);
@@ -197,6 +197,7 @@ struct rb_method_definition_struct {
ID original_id;
uintptr_t method_serial;
};
struct rb_id_table;
@@ -247,6 +248,7 @@ const rb_callable_method_entry_t *rb_method_entry_complement_defined_class(const
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src);
void rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me);
void rb_scope_visibility_set(rb_method_visibility_t);
@@ -254,5 +256,6 @@ VALUE rb_unnamed_parameters(int arity);
void rb_clear_method_cache(VALUE klass_or_module, ID mid);
void rb_clear_all_refinement_method_cache(void);
#endif /* RUBY_METHOD_H */
@@ -1,5 +1,6 @@
#include "internal.h"
#include "internal/array.h"
#include "iseq.h"
#include "vm_core.h"
#include "builtin.h"
@@ -95,9 +96,23 @@ builtin_iseq_load(const char *feature_name, const struct rb_builtin_function *ta
return iseq;
}
void
rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table)
{
- const rb_iseq_t *iseq = builtin_iseq_load(feature_name, table);
- rb_iseq_eval(iseq);
}
@@ -0,0 +1,1139 @@
@@ -121,7 +121,7 @@ rb_obj_reveal(VALUE obj, VALUE klass)
VALUE
rb_class_allocate_instance(VALUE klass)
{
- uint32_t index_tbl_num_entries = RCLASS_EXT(klass)->max_iv_count;
size_t size = rb_obj_embedded_size(index_tbl_num_entries);
if (!rb_gc_size_allocatable_p(size)) {
@@ -2097,7 +2097,7 @@ rb_class_initialize(int argc, VALUE *argv, VALUE klass)
rb_raise(rb_eTypeError, "can't inherit uninitialized class");
}
}
- RCLASS_SET_SUPER(klass, super);
rb_make_metaclass(klass, RBASIC(super)->klass);
rb_class_inherited(super, klass);
rb_mod_initialize_exec(klass);
@@ -2269,17 +2269,21 @@ rb_class_superclass(VALUE klass)
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
VALUE super = RCLASS_SUPER(klass);
if (!super) {
if (klass == rb_cBasicObject) return Qnil;
rb_raise(rb_eTypeError, "uninitialized class");
}
- if (!RCLASS_SUPERCLASS_DEPTH(klass)) {
return Qnil;
}
else {
- super = RCLASS_SUPERCLASSES(klass)[RCLASS_SUPERCLASS_DEPTH(klass) - 1];
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
return super;
}
@@ -2288,7 +2292,7 @@ rb_class_superclass(VALUE klass)
VALUE
rb_class_get_superclass(VALUE klass)
{
- return RCLASS(klass)->super;
}
static const char bad_instance_name[] = "'%1$s' is not allowed as an instance variable name";
@@ -4599,6 +4603,13 @@ InitVM_Object(void)
rb_define_method(rb_cModule, "deprecate_constant", rb_mod_deprecate_constant, -1); /* in variable.c */
rb_define_method(rb_cModule, "singleton_class?", rb_mod_singleton_p, 0);
rb_define_method(rb_singleton_class(rb_cClass), "allocate", rb_class_alloc_m, 0);
rb_define_method(rb_cClass, "allocate", rb_class_alloc_m, 0);
rb_define_method(rb_cClass, "new", rb_class_new_instance_pass_kw, -1);
@@ -678,6 +678,7 @@ cfunc_proc_new(VALUE klass, VALUE ifunc)
{
rb_proc_t *proc;
cfunc_proc_t *sproc;
VALUE procval = TypedData_Make_Struct(klass, cfunc_proc_t, &proc_data_type, sproc);
VALUE *ep;
@@ -692,6 +693,7 @@ cfunc_proc_new(VALUE klass, VALUE ifunc)
/* self? */
RB_OBJ_WRITE(procval, &proc->block.as.captured.code.ifunc, ifunc);
proc->is_lambda = TRUE;
return procval;
}
@@ -727,6 +729,7 @@ sym_proc_new(VALUE klass, VALUE sym)
GetProcPtr(procval, proc);
vm_block_type_set(&proc->block, block_type_symbol);
proc->is_lambda = TRUE;
RB_OBJ_WRITE(procval, &proc->block.as.symbol, sym);
return procval;
@@ -2006,6 +2009,21 @@ method_owner(VALUE obj)
return data->owner;
}
void
rb_method_name_error(VALUE klass, VALUE str)
{
@@ -4466,6 +4484,8 @@ Init_Proc(void)
rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1);
rb_define_method(rb_mKernel, "singleton_method", rb_obj_singleton_method, 1);
/* UnboundMethod */
rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject);
rb_undef_alloc_func(rb_cUnboundMethod);
@@ -1824,6 +1824,9 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
ruby_init_prelude();
// Initialize JITs after prelude because JITing prelude is typically not optimal.
#if USE_YJIT
rb_yjit_init(opt->yjit);
@@ -656,7 +656,7 @@ rb_shape_transition_remove_ivar(VALUE obj, ID id, VALUE *removed)
switch(BUILTIN_TYPE(obj)) {
case T_CLASS:
case T_MODULE:
- fields = RCLASS_FIELDS(obj);
break;
case T_OBJECT:
fields = ROBJECT_FIELDS(obj);
@@ -803,7 +803,7 @@ shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings)
if (BUILTIN_TYPE(obj) == T_OBJECT) {
VALUE klass = rb_obj_class(obj);
- allow_new_shape = RCLASS_EXT(klass)->variation_count < SHAPE_MAX_VARIATIONS;
}
bool variation_created = false;
@@ -812,14 +812,14 @@ shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings)
// Check if we should update max_iv_count on the object's class
if (BUILTIN_TYPE(obj) == T_OBJECT) {
VALUE klass = rb_obj_class(obj);
- if (new_shape->next_field_index > RCLASS_EXT(klass)->max_iv_count) {
- RCLASS_EXT(klass)->max_iv_count = new_shape->next_field_index;
}
if (variation_created) {
- RCLASS_EXT(klass)->variation_count++;
if (emit_warnings && rb_warning_category_enabled_p(RB_WARN_CATEGORY_PERFORMANCE)) {
- if (RCLASS_EXT(klass)->variation_count >= SHAPE_MAX_VARIATIONS) {
rb_category_warn(
RB_WARN_CATEGORY_PERFORMANCE,
"The class %"PRIsVALUE" reached %d shape variations, instance variables accesses will be slower and memory usage increased.\n"
@@ -7,10 +7,17 @@ describe "Module#ancestors" do
ModuleSpecs.ancestors.should == [ModuleSpecs]
ModuleSpecs::Basic.ancestors.should == [ModuleSpecs::Basic]
ModuleSpecs::Super.ancestors.should == [ModuleSpecs::Super, ModuleSpecs::Basic]
- ModuleSpecs.without_test_modules(ModuleSpecs::Parent.ancestors).should ==
- [ModuleSpecs::Parent, Object, Kernel, BasicObject]
- ModuleSpecs.without_test_modules(ModuleSpecs::Child.ancestors).should ==
- [ModuleSpecs::Child, ModuleSpecs::Super, ModuleSpecs::Basic, ModuleSpecs::Parent, Object, Kernel, BasicObject]
end
it "returns only modules and classes" do
@@ -0,0 +1,97 @@
@@ -9,7 +9,11 @@ class TestABI < Test::Unit::TestCase
assert_separately [], <<~RUBY
err = assert_raise(LoadError) { require "-test-/abi" }
assert_match(/incompatible ABI version/, err.message)
- assert_include err.message, "/-test-/abi."
RUBY
end
@@ -27,7 +31,11 @@ class TestABI < Test::Unit::TestCase
assert_separately [{ "RUBY_ABI_CHECK" => "1" }], <<~RUBY
err = assert_raise(LoadError) { require "-test-/abi" }
assert_match(/incompatible ABI version/, err.message)
- assert_include err.message, "/-test-/abi."
RUBY
end
@@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
@@ -0,0 +1,15 @@
@@ -0,0 +1,8 @@
@@ -0,0 +1,2 @@
@@ -0,0 +1,2 @@
@@ -0,0 +1,2 @@
@@ -0,0 +1,5 @@
@@ -0,0 +1,8 @@
@@ -0,0 +1,147 @@
@@ -0,0 +1,13 @@
@@ -0,0 +1,5 @@
@@ -0,0 +1,37 @@
@@ -0,0 +1,9 @@
@@ -0,0 +1,26 @@
@@ -0,0 +1,10 @@
@@ -0,0 +1,31 @@
@@ -0,0 +1,14 @@
@@ -0,0 +1,5 @@
@@ -0,0 +1,64 @@
@@ -0,0 +1,3 @@
@@ -0,0 +1,12 @@
@@ -0,0 +1,65 @@
@@ -0,0 +1,13 @@
@@ -0,0 +1,5 @@
@@ -0,0 +1 @@
@@ -0,0 +1,12 @@
@@ -0,0 +1,33 @@
@@ -224,11 +224,18 @@ p Foo::Bar
Kernel.module_eval do
alias old_require require
end
called_with = []
Kernel.send :define_method, :require do |path|
called_with << path
old_require path
end
yield called_with
ensure
Kernel.module_eval do
@@ -236,6 +243,11 @@ p Foo::Bar
alias require old_require
undef old_require
end
end
def test_require_implemented_in_ruby_is_called
@@ -249,7 +261,8 @@ p Foo::Bar
ensure
remove_autoload_constant
end
- assert_equal [file.path], called_with
}
end
end
@@ -267,7 +280,8 @@ p Foo::Bar
ensure
remove_autoload_constant
end
- assert_equal [a.path, b.path], called_with
end
end
end
@@ -0,0 +1,516 @@
@@ -260,6 +260,8 @@ class TestRubyOptions < Test::Unit::TestCase
end
def test_parser_flag
assert_in_out_err(%w(--parser=prism -e) + ["puts :hi"], "", %w(hi), [])
assert_in_out_err(%w(--parser=prism --dump=parsetree -e _=:hi), "", /"hi"/, [])
@@ -25,6 +25,7 @@
#include "internal/error.h"
#include "internal/eval.h"
#include "internal/hash.h"
#include "internal/object.h"
#include "internal/gc.h"
#include "internal/re.h"
@@ -109,10 +110,10 @@ classname(VALUE klass, bool *permanent)
{
*permanent = false;
- VALUE classpath = RCLASS_EXT(klass)->classpath;
if (classpath == 0) return Qnil;
- *permanent = RCLASS_EXT(klass)->permanent_classpath;
return classpath;
}
@@ -210,7 +211,7 @@ static enum rb_id_table_iterator_result
set_sub_temporary_name_i(ID id, VALUE val, void *data)
{
val = ((rb_const_entry_t *)val)->value;
- if (rb_namespace_p(val) && !RCLASS_EXT(val)->permanent_classpath) {
VALUE arg = (VALUE)data;
struct sub_temporary_name_args *args = data;
args->last = id;
@@ -222,7 +223,7 @@ set_sub_temporary_name_i(ID id, VALUE val, void *data)
static void
set_sub_temporary_name_foreach(VALUE mod, struct sub_temporary_name_args *args, VALUE name)
{
- RCLASS_SET_CLASSPATH(mod, name, FALSE);
struct rb_id_table *tbl = RCLASS_CONST_TBL(mod);
if (!tbl) return;
if (!name) {
@@ -296,7 +297,7 @@ VALUE
rb_mod_set_temporary_name(VALUE mod, VALUE name)
{
// We don't allow setting the name if the classpath is already permanent:
- if (RCLASS_EXT(mod)->permanent_classpath) {
rb_raise(rb_eRuntimeError, "can't change permanent name");
}
@@ -529,6 +530,7 @@ struct rb_global_variable {
rb_gvar_marker_t *marker;
rb_gvar_compact_t *compactor;
struct trace_var *trace;
};
struct rb_global_entry {
@@ -604,6 +606,13 @@ rb_gvar_ractor_local(const char *name)
entry->ractor_local = true;
}
static void
rb_gvar_undef_compactor(void *var)
{
@@ -629,6 +638,7 @@ rb_global_entry(ID id)
var->block_trace = 0;
var->trace = 0;
rb_id_table_insert(rb_global_tbl, id, (VALUE)entry);
}
return entry;
@@ -982,13 +992,27 @@ rb_gvar_set_entry(struct rb_global_entry *entry, VALUE val)
return val;
}
VALUE
rb_gvar_set(ID id, VALUE val)
{
struct rb_global_entry *entry;
entry = rb_global_entry(id);
- return rb_gvar_set_entry(entry, val);
}
VALUE
@@ -1000,9 +1024,27 @@ rb_gv_set(const char *name, VALUE val)
VALUE
rb_gvar_get(ID id)
{
struct rb_global_entry *entry = rb_global_entry(id);
struct rb_global_variable *var = entry->var;
- return (*var->getter)(entry->id, var->data);
}
VALUE
@@ -1056,6 +1098,7 @@ rb_f_global_variables(void)
if (!rb_ractor_main_p()) {
rb_raise(rb_eRactorIsolationError, "can not access global variables from non-main Ractors");
}
rb_id_table_foreach(rb_global_tbl, gvar_i, (void *)ary);
if (!NIL_P(backref)) {
@@ -1335,7 +1378,7 @@ rb_obj_field_get(VALUE obj, rb_shape_t *target_shape)
case T_CLASS:
case T_MODULE:
ASSERT_vm_locking();
- fields = RCLASS_FIELDS(obj);
break;
case T_OBJECT:
fields = ROBJECT_FIELDS(obj);
@@ -1392,7 +1435,7 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
found = rb_shape_get_iv_index(shape, id, &index);
if (found) {
- ivar_list = RCLASS_FIELDS(obj);
RUBY_ASSERT(ivar_list);
val = ivar_list[index];
@@ -1501,7 +1544,7 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef)
switch (BUILTIN_TYPE(obj)) {
case T_CLASS:
case T_MODULE:
- table = RCLASS_FIELDS_HASH(obj);
break;
case T_OBJECT:
@@ -1551,7 +1594,7 @@ obj_transition_too_complex(VALUE obj, st_table *table)
break;
case T_CLASS:
case T_MODULE:
- old_fields = RCLASS_FIELDS(obj);
rb_shape_set_shape_id(obj, shape_id);
RCLASS_SET_FIELDS_HASH(obj, table);
break;
@@ -2124,7 +2167,7 @@ rb_ivar_defined(VALUE obj, ID id)
switch (BUILTIN_TYPE(obj)) {
case T_CLASS:
case T_MODULE:
- table = (st_table *)RCLASS_FIELDS(obj);
break;
case T_OBJECT:
@@ -2188,7 +2231,8 @@ iterate_over_shapes_with_callback(rb_shape_t *shape, rb_ivar_foreach_callback_fu
break;
case T_CLASS:
case T_MODULE:
- iv_list = RCLASS_FIELDS(itr_data->obj);
break;
default:
iv_list = itr_data->fields_tbl->as.shape.fields;
@@ -2280,7 +2324,7 @@ class_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg,
};
if (rb_shape_obj_too_complex_p(obj)) {
- rb_st_foreach(RCLASS_FIELDS_HASH(obj), each_hash_iv, (st_data_t)&itr_data);
}
else {
iterate_over_shapes_with_callback(shape, func, &itr_data);
@@ -2701,7 +2745,7 @@ autoload_data(VALUE mod, ID id)
// If we are called with a non-origin ICLASS, fetch the autoload data from
// the original module.
if (RB_TYPE_P(mod, T_ICLASS)) {
- if (FL_TEST_RAW(mod, RICLASS_IS_ORIGIN)) {
return 0;
}
else {
@@ -2729,6 +2773,10 @@ struct autoload_const {
// The shared "autoload_data" if multiple constants are defined from the same feature.
VALUE autoload_data_value;
// The module we are loading a constant into.
VALUE module;
@@ -2866,6 +2914,70 @@ get_autoload_data(VALUE autoload_const_value, struct autoload_const **autoload_c
return autoload_data;
}
void
rb_autoload(VALUE module, ID name, const char *feature)
{
@@ -2883,6 +2995,7 @@ struct autoload_arguments {
VALUE module;
ID name;
VALUE feature;
};
static VALUE
@@ -2952,6 +3065,7 @@ autoload_synchronized(VALUE _arguments)
{
struct autoload_const *autoload_const;
VALUE autoload_const_value = TypedData_Make_Struct(0, struct autoload_const, &autoload_const_type, autoload_const);
autoload_const->module = arguments->module;
autoload_const->name = arguments->name;
autoload_const->value = Qundef;
@@ -2968,6 +3082,9 @@ autoload_synchronized(VALUE _arguments)
void
rb_autoload_str(VALUE module, ID name, VALUE feature)
{
if (!rb_is_const_id(name)) {
rb_raise(rb_eNameError, "autoload must be constant name: %"PRIsVALUE"", QUOTE_ID(name));
}
@@ -2981,6 +3098,7 @@ rb_autoload_str(VALUE module, ID name, VALUE feature)
.module = module,
.name = name,
.feature = feature,
};
VALUE result = rb_mutex_synchronize(autoload_mutex, autoload_synchronized, (VALUE)&arguments);
@@ -3241,22 +3359,82 @@ autoload_apply_constants(VALUE _arguments)
return Qtrue;
}
static VALUE
autoload_feature_require(VALUE _arguments)
{
struct autoload_load_arguments *arguments = (struct autoload_load_arguments*)_arguments;
struct autoload_const *autoload_const = arguments->autoload_const;
// We save this for later use in autoload_apply_constants:
arguments->autoload_data = rb_check_typeddata(autoload_const->autoload_data_value, &autoload_data_type);
- VALUE result = rb_funcall(rb_vm_top_self(), rb_intern("require"), 1, arguments->autoload_data->feature);
if (RTEST(result)) {
return rb_mutex_synchronize(autoload_mutex, autoload_apply_constants, _arguments);
}
-
return result;
}
@@ -3580,6 +3758,8 @@ rb_mod_remove_const(VALUE mod, VALUE name)
return rb_const_remove(mod, id);
}
VALUE
rb_const_remove(VALUE mod, ID id)
{
@@ -3589,7 +3769,7 @@ rb_const_remove(VALUE mod, ID id)
rb_check_frozen(mod);
ce = rb_const_lookup(mod, id);
- if (!ce || !rb_id_table_delete(RCLASS_CONST_TBL(mod), id)) {
if (rb_const_defined_at(mod, id)) {
rb_name_err_raise("cannot remove %2$s::%1$s", mod, ID2SYM(id));
}
@@ -3607,7 +3787,11 @@ rb_const_remove(VALUE mod, ID id)
val = Qnil;
}
- ruby_xfree(ce);
return val;
}
@@ -3829,8 +4013,8 @@ set_namespace_path_i(ID id, VALUE v, void *payload)
}
set_namespace_path(value, build_const_path(parental_path, id));
- if (!RCLASS_EXT(value)->permanent_classpath) {
- RCLASS_SET_CLASSPATH(value, 0, false);
}
return ID_TABLE_CONTINUE;
@@ -3848,7 +4032,7 @@ set_namespace_path(VALUE named_namespace, VALUE namespace_path)
RB_VM_LOCK_ENTER();
{
- RCLASS_SET_CLASSPATH(named_namespace, namespace_path, true);
if (const_table) {
rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path);
@@ -3884,9 +4068,10 @@ const_set(VALUE klass, ID id, VALUE val)
RB_VM_LOCK_ENTER();
{
- struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
if (!tbl) {
- RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0);
rb_clear_constant_cache_for_id(id);
ce = ZALLOC(rb_const_entry_t);
rb_id_table_insert(tbl, id, (VALUE)ce);
@@ -4010,6 +4195,7 @@ const_tbl_update(struct autoload_const *ac, int autoload_force)
setup_const_entry(ce, klass, val, visibility);
}
else {
rb_clear_constant_cache_for_id(id);
ce = ZALLOC(rb_const_entry_t);
@@ -4172,7 +4358,7 @@ static int
cvar_lookup_at(VALUE klass, ID id, st_data_t *v)
{
if (RB_TYPE_P(klass, T_ICLASS)) {
- if (FL_TEST_RAW(klass, RICLASS_IS_ORIGIN)) {
return 0;
}
else {
@@ -4277,10 +4463,11 @@ rb_cvar_set(VALUE klass, ID id, VALUE val)
int result = rb_class_ivar_set(target, id, val);
- struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(target);
if (!rb_cvc_tbl) {
- rb_cvc_tbl = RCLASS_CVC_TBL(target) = rb_id_table_create(2);
}
struct rb_cvar_class_tbl_entry *ent;
@@ -4304,7 +4491,7 @@ rb_cvar_set(VALUE klass, ID id, VALUE val)
// cvar in this lookup.
if (result == 0) {
if (RB_TYPE_P(target, T_CLASS)) {
- if (RCLASS_SUBCLASSES(target)) {
rb_class_foreach_subclass(target, check_for_cvar_table, id);
}
}
@@ -4538,13 +4725,13 @@ class_ivar_set_shape_fields(VALUE obj, void *_data)
{
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
- return RCLASS_FIELDS(obj);
}
static void
class_ivar_set_shape_resize_fields(VALUE obj, attr_index_t _old_capa, attr_index_t new_capa, void *_data)
{
- REALLOC_N(RCLASS_FIELDS(obj), VALUE, new_capa);
}
static void
@@ -4564,7 +4751,7 @@ class_ivar_set_too_complex_table(VALUE obj, void *_data)
{
RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
- return RCLASS_FIELDS_HASH(obj);
}
int
@@ -4574,6 +4761,8 @@ rb_class_ivar_set(VALUE obj, ID id, VALUE val)
bool existing = false;
rb_check_frozen(obj);
RB_VM_LOCK_ENTER();
{
existing = general_ivar_set(obj, id, val, NULL,
@@ -4620,11 +4809,9 @@ rb_fields_tbl_copy(VALUE dst, VALUE src)
rb_ivar_foreach(src, tbl_copy_i, dst);
}
-rb_const_entry_t *
-rb_const_lookup(VALUE klass, ID id)
{
- struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
-
if (tbl) {
VALUE val;
bool r;
@@ -4638,3 +4825,9 @@ rb_const_lookup(VALUE klass, ID id)
}
return NULL;
}
@@ -21,6 +21,7 @@
#include "internal/gc.h"
#include "internal/inits.h"
#include "internal/missing.h"
#include "internal/object.h"
#include "internal/proc.h"
#include "internal/re.h"
@@ -1164,6 +1165,7 @@ vm_proc_create_from_captured(VALUE klass,
{
VALUE procval = rb_proc_alloc(klass);
rb_proc_t *proc = RTYPEDDATA_DATA(procval);
VM_ASSERT(VM_EP_IN_HEAP_P(GET_EC(), captured->ep));
@@ -1173,6 +1175,7 @@ vm_proc_create_from_captured(VALUE klass,
rb_vm_block_ep_update(procval, &proc->block, captured->ep);
vm_block_type_set(&proc->block, block_type);
proc->is_from_method = is_from_method;
proc->is_lambda = is_lambda;
@@ -1204,10 +1207,12 @@ proc_create(VALUE klass, const struct rb_block *block, int8_t is_from_method, in
{
VALUE procval = rb_proc_alloc(klass);
rb_proc_t *proc = RTYPEDDATA_DATA(procval);
VM_ASSERT(VM_EP_IN_HEAP_P(GET_EC(), vm_block_ep(block)));
rb_vm_block_copy(procval, &proc->block, block);
vm_block_type_set(&proc->block, block->type);
proc->is_from_method = is_from_method;
proc->is_lambda = is_lambda;
@@ -2182,7 +2187,7 @@ static void
rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass)
{
st_data_t bop;
- if (RB_TYPE_P(klass, T_ICLASS) && FL_TEST(klass, RICLASS_IS_ORIGIN) &&
RB_TYPE_P(RBASIC_CLASS(klass), T_CLASS)) {
klass = RBASIC_CLASS(klass);
}
@@ -2871,17 +2876,30 @@ rb_iseq_eval(const rb_iseq_t *iseq)
rb_execution_context_t *ec = GET_EC();
VALUE val;
vm_set_top_stack(ec, iseq);
val = vm_exec(ec);
return val;
}
VALUE
-rb_iseq_eval_main(const rb_iseq_t *iseq)
{
rb_execution_context_t *ec = GET_EC();
VALUE val;
vm_set_main_stack(ec, iseq);
val = vm_exec(ec);
return val;
}
@@ -2934,6 +2952,26 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
return val;
}
/* vm */
void
@@ -2956,6 +2994,7 @@ rb_vm_update_references(void *ptr)
vm->loaded_features_realpaths = rb_gc_location(vm->loaded_features_realpaths);
vm->loaded_features_realpath_map = rb_gc_location(vm->loaded_features_realpath_map);
vm->top_self = rb_gc_location(vm->top_self);
vm->orig_progname = rb_gc_location(vm->orig_progname);
rb_gc_update_values(RUBY_NSIG, vm->trap_list.cmd);
@@ -3027,6 +3066,10 @@ rb_vm_mark(void *ptr)
rb_gc_mark_maybe(*list->varptr);
}
rb_gc_mark_movable(vm->mark_object_ary);
rb_gc_mark_movable(vm->load_path);
rb_gc_mark_movable(vm->load_path_snapshot);
@@ -3036,6 +3079,7 @@ rb_vm_mark(void *ptr)
rb_gc_mark_movable(vm->loaded_features_snapshot);
rb_gc_mark_movable(vm->loaded_features_realpaths);
rb_gc_mark_movable(vm->loaded_features_realpath_map);
rb_gc_mark_movable(vm->top_self);
rb_gc_mark_movable(vm->orig_progname);
rb_gc_mark_movable(vm->coverages);
@@ -3113,7 +3157,8 @@ ruby_vm_destruct(rb_vm_t *vm)
rb_id_table_free(vm->negative_cme_table);
st_free_table(vm->overloaded_cme_table);
- rb_id_table_free(RCLASS(rb_mRubyVMFrozenCore)->m_tbl);
rb_shape_free_all();
@@ -3505,6 +3550,8 @@ thread_mark(void *ptr)
rb_gc_mark(th->pending_interrupt_mask_stack);
rb_gc_mark(th->top_self);
rb_gc_mark(th->top_wrapper);
if (th->root_fiber) rb_fiber_mark_self(th->root_fiber);
RUBY_ASSERT(th->ec == rb_fiberptr_get_ec(th->ec->fiber_ptr));
@@ -3653,6 +3700,8 @@ th_init(rb_thread_t *th, VALUE self, rb_vm_t *vm)
th->last_status = Qnil;
th->top_wrapper = 0;
th->top_self = vm->top_self; // 0 while self == 0
th->value = Qundef;
th->ec->errinfo = Qnil;
@@ -3682,10 +3731,16 @@ th_init(rb_thread_t *th, VALUE self, rb_vm_t *vm)
VALUE
rb_thread_alloc(VALUE klass)
{
VALUE self = thread_alloc(klass);
rb_thread_t *target_th = rb_thread_ptr(self);
target_th->ractor = GET_RACTOR();
th_init(target_th, self, target_th->vm = GET_VM());
return self;
}
@@ -4234,6 +4289,8 @@ Init_VM(void)
th->vm = vm;
th->top_wrapper = 0;
th->top_self = rb_vm_top_self();
rb_vm_register_global_object((VALUE)iseq);
th->ec->cfp->iseq = iseq;
@@ -597,10 +597,13 @@ vm_cc_check_cme(const struct rb_callcache *cc, const rb_callable_method_entry_t
#if 1
// debug print
- fprintf(stderr, "iseq_overload:%d\n", (int)cme->def->iseq_overload);
rp(cme);
rp(vm_cc_cme(cc));
- rb_vm_lookup_overloaded_cme(cme);
#endif
return false;
}
@@ -118,6 +118,7 @@ extern int ruby_assert_critical_section_entered;
#include "internal.h"
#include "internal/array.h"
#include "internal/basic_operators.h"
#include "internal/sanitizers.h"
#include "internal/serial.h"
#include "internal/set_table.h"
@@ -312,6 +313,7 @@ struct rb_calling_info {
int argc;
bool kw_splat;
VALUE heap_argv;
};
#ifndef VM_ARGC_STACK_MAX
@@ -743,6 +745,9 @@ typedef struct rb_vm_struct {
struct global_object_list *global_object_list;
const VALUE special_exceptions[ruby_special_error_count];
/* load */
VALUE top_self;
VALUE load_path;
@@ -818,6 +823,8 @@ typedef struct rb_vm_struct {
size_t fiber_machine_stack_size;
} default_params;
} rb_vm_t;
/* default values */
@@ -1119,6 +1126,9 @@ typedef struct rb_thread_struct {
/* for load(true) */
VALUE top_self;
VALUE top_wrapper;
/* thread control */
@@ -1258,6 +1268,7 @@ RUBY_SYMBOL_EXPORT_END
typedef struct {
const struct rb_block block;
unsigned int is_from_method: 1; /* bool */
unsigned int is_lambda: 1; /* bool */
unsigned int is_isolated: 1; /* bool */
@@ -1349,11 +1360,11 @@ typedef rb_control_frame_t *
enum vm_frame_env_flags {
/* Frame/Environment flag bits:
- * MMMM MMMM MMMM MMMM ____ FFFF FFFE EEEX (LSB)
*
* X : tag for GC marking (It seems as Fixnum)
* EEE : 4 bits Env flags
- * FF..: 7 bits Frame flags
* MM..: 15 bits frame magic (to check frame corruption)
*/
@@ -1378,6 +1389,8 @@ enum vm_frame_env_flags {
VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM = 0x0200,
VM_FRAME_FLAG_CFRAME_KW = 0x0400,
VM_FRAME_FLAG_PASSED = 0x0800,
/* env flag */
VM_ENV_FLAG_LOCAL = 0x0002,
@@ -1476,6 +1489,12 @@ VM_FRAME_RUBYFRAME_P(const rb_control_frame_t *cfp)
return !VM_FRAME_CFRAME_P(cfp);
}
#define RUBYVM_CFUNC_FRAME_P(cfp) \
(VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC)
@@ -1823,6 +1842,7 @@ NORETURN(void rb_bug_for_fatal_signal(ruby_sighandler_t default_sighandler, int
/* functions about thread/vm execution */
RUBY_SYMBOL_EXPORT_BEGIN
VALUE rb_iseq_eval(const rb_iseq_t *iseq);
VALUE rb_iseq_eval_main(const rb_iseq_t *iseq);
VALUE rb_iseq_path(const rb_iseq_t *iseq);
VALUE rb_iseq_realpath(const rb_iseq_t *iseq);
@@ -400,9 +400,9 @@ static inline const rb_callable_method_entry_t *rb_search_method_entry(VALUE rec
static inline enum method_missing_reason rb_method_call_status(rb_execution_context_t *ec, const rb_callable_method_entry_t *me, call_type scope, VALUE self);
static VALUE
-gccct_hash(VALUE klass, ID mid)
{
- return (klass >> 3) ^ (VALUE)mid;
}
NOINLINE(static const struct rb_callcache *gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, unsigned int index, const struct rb_callinfo * ci));
@@ -447,7 +447,8 @@ scope_to_ci(call_type scope, ID mid, int argc, struct rb_callinfo *ci)
static inline const struct rb_callcache *
gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct rb_callinfo *ci)
{
- VALUE klass;
if (!SPECIAL_CONST_P(recv)) {
klass = RBASIC_CLASS(recv);
@@ -457,8 +458,13 @@ gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct
klass = CLASS_OF(recv);
}
// search global method cache
- unsigned int index = (unsigned int)(gccct_hash(klass, mid) % VM_GLOBAL_CC_CACHE_TABLE_SIZE);
rb_vm_t *vm = rb_ec_vm_ptr(ec);
const struct rb_callcache *cc = vm->global_cc_cache_table[index];
@@ -483,6 +489,17 @@ gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct
return gccct_method_search_slowpath(vm, klass, index, ci);
}
/**
* @internal
* calls the specified method.
@@ -1978,6 +1995,7 @@ eval_string_with_cref(VALUE self, VALUE src, rb_cref_t *cref, VALUE file, int li
cref = vm_cref_dup(orig_cref);
}
vm_set_eval_stack(ec, iseq, cref, &block);
/* kick */
return vm_exec(ec);
@@ -2000,6 +2018,8 @@ eval_string_with_scope(VALUE scope, VALUE src, VALUE file, int line)
vm_bind_update_env(scope, bind, vm_make_env_object(ec, ec->cfp));
}
/* kick */
return vm_exec(ec);
}
@@ -2865,6 +2885,7 @@ Init_vm_eval(void)
rb_define_method(rb_eUncaughtThrow, "value", uncaught_throw_value, 0);
rb_define_method(rb_eUncaughtThrow, "to_s", uncaught_throw_to_s, 0);
id_result = rb_intern_const("result");
id_tag = rb_intern_const("tag");
id_value = rb_intern_const("value");
@@ -134,7 +134,7 @@ callable_method_entry_p(const rb_callable_method_entry_t *cme)
return TRUE;
}
else {
- VM_ASSERT(IMEMO_TYPE_P((VALUE)cme, imemo_ment));
if (callable_class_p(cme->defined_class)) {
return TRUE;
@@ -418,7 +418,7 @@ vm_push_frame(rb_execution_context_t *ec,
#if VM_DEBUG_BP_CHECK
.bp_check = sp,
#endif
- .jit_return = NULL
};
/* Ensure the initialization of `*cfp` above never gets reordered with the update of `ec->cfp` below.
@@ -963,7 +963,7 @@ vm_get_const_key_cref(const VALUE *ep)
while (cref) {
if (RCLASS_SINGLETON_P(CREF_CLASS(cref)) ||
- RCLASS_EXT(CREF_CLASS(cref))->cloned) {
return key_cref;
}
cref = CREF_NEXT(cref);
@@ -1256,7 +1256,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call
}
}
- ivar_list = RCLASS_FIELDS(obj);
#if !SHAPE_IN_BASIC_FLAGS
shape_id = RCLASS_SHAPE_ID(obj);
@@ -1335,7 +1335,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call
switch (BUILTIN_TYPE(obj)) {
case T_CLASS:
case T_MODULE:
- table = (st_table *)RCLASS_FIELDS(obj);
break;
case T_OBJECT:
@@ -2079,7 +2079,7 @@ static const struct rb_callcache *
vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
{
const ID mid = vm_ci_mid(ci);
- struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
struct rb_class_cc_entries *ccs = NULL;
VALUE ccs_data;
@@ -2125,7 +2125,8 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
}
}
else {
- cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2);
}
RB_DEBUG_COUNTER_INC(cc_not_found_in_ccs);
@@ -4123,7 +4124,7 @@ rb_find_defined_class_by_owner(VALUE current_class, VALUE target_owner)
VALUE klass = current_class;
/* for prepended Module, then start from cover class */
- if (RB_TYPE_P(klass, T_ICLASS) && FL_TEST(klass, RICLASS_IS_ORIGIN) &&
RB_TYPE_P(RBASIC_CLASS(klass), T_CLASS)) {
klass = RBASIC_CLASS(klass);
}
@@ -5109,6 +5110,20 @@ block_proc_is_lambda(const VALUE procval)
}
}
static VALUE
vm_yield_with_cfunc(rb_execution_context_t *ec,
const struct rb_captured_block *captured,
@@ -5259,11 +5274,16 @@ vm_invoke_iseq_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
VALUE * const rsp = GET_SP() - calling->argc;
VALUE * const argv = rsp;
int opt_pc = vm_callee_setup_block_arg(ec, calling, ci, iseq, argv, is_lambda ? arg_setup_method : arg_setup_block);
SET_SP(rsp);
vm_push_frame(ec, iseq,
- VM_FRAME_MAGIC_BLOCK | (is_lambda ? VM_FRAME_FLAG_LAMBDA : 0),
captured->self,
VM_GUARDED_PREV_EP(captured->ep), 0,
ISEQ_BODY(iseq)->iseq_encoded + opt_pc,
@@ -5362,6 +5382,9 @@ vm_invoke_proc_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
{
while (vm_block_handler_type(block_handler) == block_handler_type_proc) {
VALUE proc = VM_BH_TO_PROC(block_handler);
is_lambda = block_proc_is_lambda(proc);
block_handler = vm_proc_to_block_handler(proc);
}
@@ -5812,6 +5835,7 @@ vm_define_class(ID id, rb_num_t flags, VALUE cbase, VALUE super)
/* find klass */
rb_autoload_load(cbase, id);
if ((klass = vm_const_get_under(id, flags, cbase)) != 0) {
if (!vm_check_if_class(id, flags, super, klass))
unmatched_redefinition("class", cbase, id, klass);
@@ -5913,8 +5937,7 @@ vm_define_method(const rb_execution_context_t *ec, VALUE obj, ID id, VALUE iseqv
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, visi);
// Set max_iv_count on klasses based on number of ivar sets that are in the initialize method
if (id == idInitialize && klass != rb_cObject && RB_TYPE_P(klass, T_CLASS) && (rb_get_alloc_func(klass) == rb_class_allocate_instance)) {
-
- RCLASS_EXT(klass)->max_iv_count = rb_estimate_iv_count(klass, (const rb_iseq_t *)iseqval);
}
if (!is_singleton && vm_scope_module_func_check(ec)) {
@@ -39,7 +39,7 @@ vm_ccs_dump_i(ID mid, VALUE val, void *data)
static void
vm_ccs_dump(VALUE klass, ID target_mid)
{
- struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
if (cc_tbl) {
VALUE ccs;
if (target_mid) {
@@ -87,18 +87,18 @@ vm_mtbl_dump(VALUE klass, ID target_mid)
else {
fprintf(stderr, " MTBL: NULL\n");
}
- if (RCLASS_CALLABLE_M_TBL(klass)) {
if (target_mid != 0) {
- if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, &me)) {
rp_m(" [CM**] ", me);
}
}
else {
fprintf(stderr, " ## RCLASS_CALLABLE_M_TBL\n");
- rb_id_table_foreach(RCLASS_CALLABLE_M_TBL(klass), vm_cme_dump_i, NULL);
}
}
- if (RCLASS_CC_TBL(klass)) {
vm_ccs_dump(klass, target_mid);
}
klass = RCLASS_SUPER(klass);
@@ -166,6 +166,78 @@ const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me)
static const rb_callable_method_entry_t *complemented_callable_method_entry(VALUE klass, ID id);
static const rb_callable_method_entry_t *lookup_overloaded_cme(const rb_callable_method_entry_t *cme);
static void
clear_method_cache_by_id_in_class(VALUE klass, ID mid)
@@ -174,33 +246,24 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
if (rb_objspace_garbage_object_p(klass)) return;
RB_VM_LOCK_ENTER();
- if (LIKELY(RCLASS_SUBCLASSES(klass) == NULL)) {
// no subclasses
// check only current class
- struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
- VALUE ccs_data;
-
// invalidate CCs
- if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
- struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data;
- rb_yjit_cme_invalidate((rb_callable_method_entry_t *)ccs->cme);
- if (NIL_P(ccs->cme->owner)) invalidate_negative_cache(mid);
- rb_vm_ccs_free(ccs);
- rb_id_table_delete(cc_tbl, mid);
- RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_ccs);
}
// remove from callable_m_tbl, if exists
- struct rb_id_table *cm_tbl;
- if ((cm_tbl = RCLASS_CALLABLE_M_TBL(klass)) != NULL) {
- VALUE cme;
- if (rb_yjit_enabled_p && rb_id_table_lookup(cm_tbl, mid, &cme)) {
- rb_yjit_cme_invalidate((rb_callable_method_entry_t *)cme);
- }
- rb_id_table_delete(cm_tbl, mid);
- RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_callable);
}
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf);
}
else {
@@ -223,10 +286,9 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
else {
klass_housing_cme = RCLASS_ORIGIN(owner);
}
- // replace the cme that will be invalid
- VM_ASSERT(lookup_method_table(klass_housing_cme, mid) == (const rb_method_entry_t *)cme);
- const rb_method_entry_t *new_cme = rb_method_entry_clone((const rb_method_entry_t *)cme);
- rb_method_table_insert(klass_housing_cme, RCLASS_M_TBL(klass_housing_cme), mid, new_cme);
}
vm_cme_invalidate((rb_callable_method_entry_t *)cme);
@@ -234,7 +296,7 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
// In case of refinement ME, also invalidate the wrapped ME that
// could be cached at some callsite and is unreachable from any
- // RCLASS_CC_TBL.
if (cme->def->type == VM_METHOD_TYPE_REFINED && cme->def->body.refined.orig_me) {
vm_cme_invalidate((rb_callable_method_entry_t *)cme->def->body.refined.orig_me);
}
@@ -250,11 +312,12 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
// invalidate complement tbl
if (METHOD_ENTRY_COMPLEMENTED(cme)) {
VALUE defined_class = cme->defined_class;
- struct rb_id_table *cm_tbl = RCLASS_CALLABLE_M_TBL(defined_class);
- VM_ASSERT(cm_tbl != NULL);
- int r = rb_id_table_delete(cm_tbl, mid);
- VM_ASSERT(r == TRUE); (void)r;
- RB_DEBUG_COUNTER_INC(cc_invalidate_tree_callable);
}
RB_DEBUG_COUNTER_INC(cc_invalidate_tree);
@@ -263,6 +326,9 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
invalidate_negative_cache(mid);
}
}
RB_VM_LOCK_LEAVE();
}
@@ -302,6 +368,32 @@ rb_clear_method_cache(VALUE klass_or_module, ID mid)
}
}
static int
invalidate_all_refinement_cc(void *vstart, void *vend, size_t stride, void *data)
{
@@ -447,12 +539,17 @@ rb_clear_all_refinement_method_cache(void)
void
rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me)
{
VALUE table_owner = klass;
- if (RB_TYPE_P(klass, T_ICLASS) && !RICLASS_OWNS_M_TBL_P(klass)) {
table_owner = RBASIC(table_owner)->klass;
}
VM_ASSERT_TYPE3(table_owner, T_CLASS, T_ICLASS, T_MODULE);
- VM_ASSERT(table == RCLASS_M_TBL(table_owner));
rb_id_table_insert(table, method_id, (VALUE)me);
RB_OBJ_WRITTEN(table_owner, Qundef, (VALUE)me);
}
@@ -760,6 +857,7 @@ rb_method_definition_create(rb_method_type_t type, ID mid)
def->original_id = mid;
static uintptr_t method_serial = 1;
def->method_serial = method_serial++;
return def;
}
@@ -1003,7 +1101,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil
rb_clear_method_cache(orig_klass, mid);
}
}
- mtbl = RCLASS_M_TBL(klass);
/* check re-definition */
if (rb_id_table_lookup(mtbl, mid, &data)) {
@@ -1331,7 +1429,11 @@ search_method0(VALUE klass, ID id, VALUE *defined_class_ptr, bool skip_refined)
if (me == NULL) RB_DEBUG_COUNTER_INC(mc_search_notfound);
- VM_ASSERT(me == NULL || !METHOD_ENTRY_INVALIDATED(me));
return me;
}
@@ -1366,23 +1468,27 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_
struct rb_id_table *mtbl;
const rb_callable_method_entry_t *cme;
VALUE cme_data;
if (me) {
if (me->defined_class == 0) {
RB_DEBUG_COUNTER_INC(mc_cme_complement);
VM_ASSERT_TYPE2(defined_class, T_ICLASS, T_MODULE);
- mtbl = RCLASS_CALLABLE_M_TBL(defined_class);
-
if (mtbl && rb_id_table_lookup(mtbl, id, &cme_data)) {
cme = (rb_callable_method_entry_t *)cme_data;
RB_DEBUG_COUNTER_INC(mc_cme_complement_hit);
VM_ASSERT(callable_method_entry_p(cme));
VM_ASSERT(!METHOD_ENTRY_INVALIDATED(cme));
}
else if (create) {
if (!mtbl) {
- mtbl = RCLASS_EXT(defined_class)->callable_m_tbl = rb_id_table_create(0);
}
cme = rb_method_entry_complement_defined_class(me, me->called_id, defined_class);
rb_id_table_insert(mtbl, id, (VALUE)cme);
@@ -1418,7 +1524,7 @@ cached_callable_method_entry(VALUE klass, ID mid)
{
ASSERT_vm_locking();
- struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
VALUE ccs_data;
if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
@@ -1446,11 +1552,12 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_
ASSERT_vm_locking();
VM_ASSERT(cme != NULL);
- struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
VALUE ccs_data;
if (!cc_tbl) {
- cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2);
}
if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
@@ -1694,7 +1801,7 @@ remove_method(VALUE klass, ID mid)
rb_clear_method_cache(self, mid);
}
rb_clear_method_cache(klass, mid);
- rb_id_table_delete(RCLASS_M_TBL(klass), mid);
rb_vm_check_redefinition_opt_method(me, klass);