Project

General

Profile

Feature #17753 » 0001-Add-Module-namespace.patch

tenderlovemaking (Aaron Patterson), 03/27/2021 09:51 PM

View differences:

gc.c
}
if (!RCLASS_EXT(obj)) break;
gc_mark(objspace, RCLASS_EXT(obj)->namespace);
mark_m_tbl(objspace, RCLASS_M_TBL(obj));
cc_table_mark(objspace, obj);
mark_tbl_no_pin(objspace, RCLASS_IV_TBL(obj));
......
UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
}
if (!RCLASS_EXT(obj)) break;
UPDATE_IF_MOVED(objspace, RCLASS_EXT(obj)->namespace);
update_m_tbl(objspace, RCLASS_M_TBL(obj));
update_cc_tbl(objspace, obj);
internal/class.h
struct rb_id_table *cc_tbl; /* ID -> [[ci, cc1], cc2, ...] */
struct rb_subclass_entry *subclasses;
struct rb_subclass_entry **parent_subclasses;
VALUE namespace;
/**
* 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
object.c
UNREACHABLE_RETURN(Qundef);
}
static VALUE
rb_mod_namespace(VALUE mod)
{
VALUE scope = RCLASS_EXT(mod)->namespace;
if (scope) {
return scope;
}
else {
return Qnil;
}
}
/*
* call-seq:
* obj.instance_variable_get(symbol) -> obj
......
rb_define_method(rb_cModule, "const_set", rb_mod_const_set, 2);
rb_define_method(rb_cModule, "const_defined?", rb_mod_const_defined, -1);
rb_define_method(rb_cModule, "const_source_location", rb_mod_const_source_location, -1);
rb_define_method(rb_cModule, "namespace", rb_mod_namespace, 0);
rb_define_private_method(rb_cModule, "remove_const",
rb_mod_remove_const, 1); /* in variable.c */
rb_define_method(rb_cModule, "const_missing",
test/ruby/test_module.rb
end
ConstLocation = [__FILE__, __LINE__]
class ConstLocationClass; end
module ConstLocationModule; end
def test_const_source_location
assert_equal(ConstLocation, self.class.const_source_location(:ConstLocation))
......
}
end
module Inner; end
module Outer
X = Inner
end
def test_namespace
assert_equal ::Object, ::Object.namespace
assert_equal ::Object, ::Kernel.namespace
assert_equal self.class, ConstLocationClass.namespace
assert_equal self.class, Outer::X.namespace
end
module CloneTestM_simple
C = 1
def self.m; C; end
variable.c
void
rb_const_set(VALUE klass, ID id, VALUE val)
{
rb_const_entry_t *ce;
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class/module to define constant %"PRIsVALUE"",
QUOTE_ID(id));
......
{
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();
ce = ZALLOC(rb_const_entry_t);
rb_id_table_insert(tbl, id, (VALUE)ce);
setup_const_entry(ce, klass, val, CONST_PUBLIC);
}
else {
struct autoload_const ac = {
.mod = klass, .id = id,
.value = val, .flag = CONST_PUBLIC,
/* fill the rest with 0 */
};
const_tbl_update(&ac);
RCLASS_CONST_TBL(klass) = rb_id_table_create(0);
}
struct autoload_const ac = {
.mod = klass, .id = id,
.value = val, .flag = CONST_PUBLIC,
/* fill the rest with 0 */
};
const_tbl_update(&ac);
}
RB_VM_LOCK_LEAVE();
......
ce = ZALLOC(rb_const_entry_t);
rb_id_table_insert(tbl, id, (VALUE)ce);
if (RB_TYPE_P(val, T_MODULE) || RB_TYPE_P(val, T_CLASS)) {
if (!RCLASS_EXT(val)->namespace) {
RB_OBJ_WRITE(val, &RCLASS_EXT(val)->namespace, klass);
}
}
setup_const_entry(ce, klass, val, visibility);
}
}
(2-2/2)