Compact prime classext readable/writable flags
To make RClass size smaller, move flags of prime classext readable/writable to: readable - use ns_classext_tbl is NULL or not (if NULL, it's readable) writable - use FL_USER2 of RBasic flags
This commit is contained in:
parent
e81d50207b
commit
ff790c759e
28
class.c
28
class.c
@ -39,7 +39,9 @@
|
|||||||
* This is done for classes defined from C to allow storing them in global variables.
|
* This is done for classes defined from C to allow storing them in global variables.
|
||||||
* 1: RUBY_FL_SINGLETON
|
* 1: RUBY_FL_SINGLETON
|
||||||
* This class is a singleton class.
|
* This class is a singleton class.
|
||||||
* 2: RCLASS_SUPERCLASSES_INCLUDE_SELF // TODO: Delete this
|
* 2: RCLASS_PRIME_CLASSEXT_PRIME_WRITABLE
|
||||||
|
* This class's prime classext is the only classext and writable from any namespaces.
|
||||||
|
* If unset, the prime classext is writable only from the root namespace.
|
||||||
* if !SHAPE_IN_BASIC_FLAGS
|
* if !SHAPE_IN_BASIC_FLAGS
|
||||||
* 4-19: SHAPE_FLAG_MASK
|
* 4-19: SHAPE_FLAG_MASK
|
||||||
* Shape ID for the class.
|
* Shape ID for the class.
|
||||||
@ -48,9 +50,9 @@
|
|||||||
|
|
||||||
/* Flags of T_ICLASS
|
/* Flags of T_ICLASS
|
||||||
*
|
*
|
||||||
* 0: RICLASS_IS_ORIGIN // TODO: Delete this
|
* 2: RCLASS_PRIME_CLASSEXT_PRIME_WRITABLE
|
||||||
* 3: RICLASS_ORIGIN_SHARED_MTBL // TODO: Delete this
|
* This module's prime classext is the only classext and writable from any namespaces.
|
||||||
* The T_ICLASS does not own the method table.
|
* If unset, the prime classext is writable only from the root namespace.
|
||||||
* if !SHAPE_IN_BASIC_FLAGS
|
* if !SHAPE_IN_BASIC_FLAGS
|
||||||
* 4-19: SHAPE_FLAG_MASK
|
* 4-19: SHAPE_FLAG_MASK
|
||||||
* Shape ID. This is set but not used.
|
* Shape ID. This is set but not used.
|
||||||
@ -64,7 +66,9 @@
|
|||||||
* This is done for classes defined from C to allow storing them in global variables.
|
* This is done for classes defined from C to allow storing them in global variables.
|
||||||
* 1: RMODULE_ALLOCATED_BUT_NOT_INITIALIZED
|
* 1: RMODULE_ALLOCATED_BUT_NOT_INITIALIZED
|
||||||
* Module has not been initialized.
|
* Module has not been initialized.
|
||||||
* 2: RCLASS_SUPERCLASSES_INCLUDE_SELF // TODO: Delete this
|
* 2: RCLASS_PRIME_CLASSEXT_PRIME_WRITABLE
|
||||||
|
* This module's prime classext is the only classext and writable from any namespaces.
|
||||||
|
* If unset, the prime classext is writable only from the root namespace.
|
||||||
* 3: RMODULE_IS_REFINEMENT
|
* 3: RMODULE_IS_REFINEMENT
|
||||||
* Module is used for refinements.
|
* Module is used for refinements.
|
||||||
* if !SHAPE_IN_BASIC_FLAGS
|
* if !SHAPE_IN_BASIC_FLAGS
|
||||||
@ -254,7 +258,7 @@ class_duplicate_iclass_classext(VALUE iclass, rb_classext_t *mod_ext, const rb_n
|
|||||||
{
|
{
|
||||||
rb_classext_t *src = RCLASS_EXT(iclass);
|
rb_classext_t *src = RCLASS_EXT(iclass);
|
||||||
rb_classext_t *ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(iclass, ns);
|
rb_classext_t *ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(iclass, ns);
|
||||||
int table_created = 0;
|
int first_set = 0;
|
||||||
|
|
||||||
if (ext) {
|
if (ext) {
|
||||||
// iclass classext for the ns is only for cc/callable_m_tbl if it's created earlier than module's one
|
// iclass classext for the ns is only for cc/callable_m_tbl if it's created earlier than module's one
|
||||||
@ -290,9 +294,9 @@ class_duplicate_iclass_classext(VALUE iclass, rb_classext_t *mod_ext, const rb_n
|
|||||||
|
|
||||||
RCLASSEXT_SET_INCLUDER(ext, iclass, RCLASSEXT_INCLUDER(src));
|
RCLASSEXT_SET_INCLUDER(ext, iclass, RCLASSEXT_INCLUDER(src));
|
||||||
|
|
||||||
table_created = RCLASS_SET_NAMESPACE_CLASSEXT(iclass, ns, ext);
|
first_set = RCLASS_SET_NAMESPACE_CLASSEXT(iclass, ns, ext);
|
||||||
if (table_created) {
|
if (first_set) {
|
||||||
RCLASS_SET_PRIME_CLASSEXT_READWRITE(iclass, false, false);
|
RCLASS_SET_PRIME_CLASSEXT_WRITABLE(iclass, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -825,8 +829,8 @@ rb_class_debug_dump_all_classext(VALUE klass)
|
|||||||
}
|
}
|
||||||
snprintf(buf, 2048,
|
snprintf(buf, 2048,
|
||||||
"classext-dump:\n readable:%s\n writable:%s\n table size:%zu\n",
|
"classext-dump:\n readable:%s\n writable:%s\n table size:%zu\n",
|
||||||
RCLASS(klass)->prime_classext_readable ? "true" : "false",
|
RCLASS_PRIME_CLASSEXT_READABLE_P(klass) ? "true" : "false",
|
||||||
RCLASS(klass)->prime_classext_writable ? "true" : "false",
|
RCLASS_PRIME_CLASSEXT_WRITABLE_P(klass) ? "true" : "false",
|
||||||
RCLASS(klass)->ns_classext_tbl ? st_table_size(RCLASS(klass)->ns_classext_tbl) : 0);
|
RCLASS(klass)->ns_classext_tbl ? st_table_size(RCLASS(klass)->ns_classext_tbl) : 0);
|
||||||
rb_str_cat_cstr(r, buf);
|
rb_str_cat_cstr(r, buf);
|
||||||
rb_str_cat_cstr(r, "========================\n");
|
rb_str_cat_cstr(r, "========================\n");
|
||||||
@ -1151,7 +1155,7 @@ class_alloc(VALUE flags, VALUE klass)
|
|||||||
RCLASS_PRIME_NS((VALUE)obj) = ns;
|
RCLASS_PRIME_NS((VALUE)obj) = ns;
|
||||||
// Classes/Modules defined in user namespaces are
|
// Classes/Modules defined in user namespaces are
|
||||||
// writable directly because it exists only in a namespace.
|
// writable directly because it exists only in a namespace.
|
||||||
RCLASS_SET_PRIME_CLASSEXT_READWRITE((VALUE)obj, true, NAMESPACE_USER_P(ns) ? true : false);
|
RCLASS_SET_PRIME_CLASSEXT_WRITABLE((VALUE)obj, NAMESPACE_USER_P(ns) ? true : false);
|
||||||
|
|
||||||
RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj);
|
RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj);
|
||||||
RCLASS_SET_REFINED_CLASS((VALUE)obj, Qnil);
|
RCLASS_SET_REFINED_CLASS((VALUE)obj, Qnil);
|
||||||
|
@ -136,26 +136,26 @@ STATIC_ASSERT(shape_max_variations, SHAPE_MAX_VARIATIONS < (1 << (sizeof(((rb_cl
|
|||||||
struct RClass {
|
struct RClass {
|
||||||
struct RBasic basic;
|
struct RBasic basic;
|
||||||
st_table *ns_classext_tbl; // ns_object -> (rb_classext_t *)
|
st_table *ns_classext_tbl; // ns_object -> (rb_classext_t *)
|
||||||
bool prime_classext_readable : 1;
|
/*
|
||||||
bool prime_classext_writable : 1;
|
* If ns_classext_tbl is NULL, then the prime classext is readable (because no other classext exists).
|
||||||
|
* For the check whether writable or not, check flag RCLASS_PRIME_CLASSEXT_WRITABLE
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/** TODO: Update or remove this assertion
|
// Assert that classes can be embedded in heaps[2] (which has 160B slot size)
|
||||||
* // Assert that classes can be embedded in heaps[2] (which has 160B slot size)
|
// TODO: check this assertion's validity
|
||||||
* STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t) <= 4 * RVALUE_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_and_rb_classext_t {
|
||||||
struct RClass rclass;
|
struct RClass rclass;
|
||||||
rb_classext_t classext;
|
rb_classext_t classext;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RCLASS_PRIME_READABLE_P(obj) (RCLASS(obj)->prime_classext_readable)
|
|
||||||
#define RCLASS_PRIME_WRITABLE_P(obj) (RCLASS(obj)->prime_classext_writable)
|
|
||||||
|
|
||||||
static inline bool RCLASS_SINGLETON_P(VALUE klass);
|
static inline bool RCLASS_SINGLETON_P(VALUE klass);
|
||||||
|
|
||||||
static inline void RCLASS_SET_PRIME_CLASSEXT_READWRITE(VALUE obj, bool readable, bool writable);
|
static inline bool RCLASS_PRIME_CLASSEXT_READABLE_P(VALUE obj);
|
||||||
|
static inline bool RCLASS_PRIME_CLASSEXT_WRITABLE_P(VALUE obj);
|
||||||
|
static inline void RCLASS_SET_PRIME_CLASSEXT_WRITABLE(VALUE obj, bool writable);
|
||||||
|
|
||||||
#define RCLASS_EXT(c) (&((struct RClass_and_rb_classext_t*)(c))->classext)
|
#define RCLASS_EXT(c) (&((struct RClass_and_rb_classext_t*)(c))->classext)
|
||||||
#define RCLASS_EXT_PRIME_P(ext, c) (&((struct RClass_and_rb_classext_t*)(c))->classext == ext)
|
#define RCLASS_EXT_PRIME_P(ext, c) (&((struct RClass_and_rb_classext_t*)(c))->classext == ext)
|
||||||
@ -217,11 +217,9 @@ static inline void RCLASSEXT_SET_INCLUDER(rb_classext_t *ext, VALUE klass, VALUE
|
|||||||
#define RCLASS_M_TBL(c) (RCLASS_EXT_READABLE(c)->m_tbl)
|
#define RCLASS_M_TBL(c) (RCLASS_EXT_READABLE(c)->m_tbl)
|
||||||
#define RCLASS_CONST_TBL(c) (RCLASS_EXT_READABLE(c)->const_tbl)
|
#define RCLASS_CONST_TBL(c) (RCLASS_EXT_READABLE(c)->const_tbl)
|
||||||
/*
|
/*
|
||||||
* Both cc_tbl/callable_m_tbl are cache and always be changed when referreed,
|
* Both cc_tbl/callable_m_tbl are cache-like and always be changed when referreed,
|
||||||
* so always should be writable.
|
* so always those should be writable.
|
||||||
*/
|
*/
|
||||||
// #define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT_READABLE(c)->callable_m_tbl)
|
|
||||||
// #define RCLASS_CC_TBL(c) (RCLASS_EXT_READABLE(c)->cc_tbl)
|
|
||||||
#define RCLASS_CVC_TBL(c) (RCLASS_EXT_READABLE(c)->cvc_tbl)
|
#define RCLASS_CVC_TBL(c) (RCLASS_EXT_READABLE(c)->cvc_tbl)
|
||||||
#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT_READABLE(c)->superclass_depth)
|
#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT_READABLE(c)->superclass_depth)
|
||||||
#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT_READABLE(c)->superclasses)
|
#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT_READABLE(c)->superclasses)
|
||||||
@ -290,9 +288,10 @@ static inline void RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool perma
|
|||||||
static inline void RCLASS_WRITE_CLASSPATH(VALUE klass, VALUE classpath, bool permanent);
|
static inline void RCLASS_WRITE_CLASSPATH(VALUE klass, VALUE classpath, bool permanent);
|
||||||
|
|
||||||
#define RCLASS_IS_ROOT FL_USER0
|
#define RCLASS_IS_ROOT FL_USER0
|
||||||
// #define RICLASS_IS_ORIGIN FL_USER0 // TODO: Delete this
|
// 1 is for RUBY_FL_SINGLETON or RMODULE_ALLOCATED_BUT_NOT_INITIALIZED (see class.c)
|
||||||
// #define RCLASS_SUPERCLASSES_INCLUD_SELF FL_USER2 // TODO: Delete this
|
#define RCLASS_PRIME_CLASSEXT_WRITABLE FL_USER2
|
||||||
// #define RICLASS_ORIGIN_SHARED_MTBL FL_USER3 // TODO: Delete this
|
// 3 is RMODULE_IS_REFINEMENT for RMODULE
|
||||||
|
// 4-19: SHAPE_FLAG_MASK
|
||||||
|
|
||||||
VALUE rb_class_debug_duplicate_classext(VALUE klass, VALUE namespace); // TODO: only for development
|
VALUE rb_class_debug_duplicate_classext(VALUE klass, VALUE namespace); // TODO: only for development
|
||||||
VALUE rb_class_debug_dump_all_classext(VALUE klass); // TODO: only for development
|
VALUE rb_class_debug_dump_all_classext(VALUE klass); // TODO: only for development
|
||||||
@ -307,23 +306,47 @@ void rb_class_ensure_writable(VALUE obj);
|
|||||||
static inline int
|
static inline int
|
||||||
RCLASS_SET_NAMESPACE_CLASSEXT(VALUE obj, const rb_namespace_t *ns, rb_classext_t *ext)
|
RCLASS_SET_NAMESPACE_CLASSEXT(VALUE obj, const rb_namespace_t *ns, rb_classext_t *ext)
|
||||||
{
|
{
|
||||||
int tbl_created = 0;
|
int first_set = 0;
|
||||||
st_table *tbl = RCLASS_CLASSEXT_TBL(obj);
|
st_table *tbl = RCLASS_CLASSEXT_TBL(obj);
|
||||||
VM_ASSERT(NAMESPACE_USER_P(ns)); // non-prime classext is only for user namespace, with ns_object
|
VM_ASSERT(NAMESPACE_USER_P(ns)); // non-prime classext is only for user namespace, with ns_object
|
||||||
|
VM_ASSERT(ns->ns_object);
|
||||||
VM_ASSERT(RCLASSEXT_NS(ext) == ns);
|
VM_ASSERT(RCLASSEXT_NS(ext) == ns);
|
||||||
if (!tbl) {
|
if (!tbl) {
|
||||||
RCLASS_CLASSEXT_TBL(obj) = tbl = st_init_numtable_with_size(1);
|
RCLASS_CLASSEXT_TBL(obj) = tbl = st_init_numtable_with_size(1);
|
||||||
tbl_created = 1;
|
}
|
||||||
|
if (rb_st_table_size(tbl) == 0) {
|
||||||
|
first_set = 1;
|
||||||
}
|
}
|
||||||
rb_st_insert(tbl, (st_data_t)ns->ns_object, (st_data_t)ext);
|
rb_st_insert(tbl, (st_data_t)ns->ns_object, (st_data_t)ext);
|
||||||
return tbl_created;
|
return first_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
RCLASS_PRIME_CLASSEXT_READABLE_P(VALUE klass)
|
||||||
|
{
|
||||||
|
VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS));
|
||||||
|
// if the lookup table exists, then it means the prime classext is NOT directly readable.
|
||||||
|
return RCLASS_CLASSEXT_TBL(klass) == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
RCLASS_PRIME_CLASSEXT_WRITABLE_P(VALUE klass)
|
||||||
|
{
|
||||||
|
VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS));
|
||||||
|
return FL_TEST(klass, RCLASS_PRIME_CLASSEXT_WRITABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
RCLASS_SET_PRIME_CLASSEXT_READWRITE(VALUE obj, bool readable, bool writable)
|
RCLASS_SET_PRIME_CLASSEXT_WRITABLE(VALUE klass, bool writable)
|
||||||
{
|
{
|
||||||
RCLASS(obj)->prime_classext_readable = readable;
|
VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS));
|
||||||
RCLASS(obj)->prime_classext_writable = writable;
|
|
||||||
|
if (writable) {
|
||||||
|
FL_SET(klass, RCLASS_PRIME_CLASSEXT_WRITABLE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FL_UNSET(klass, RCLASS_PRIME_CLASSEXT_WRITABLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline rb_classext_t *
|
static inline rb_classext_t *
|
||||||
@ -354,7 +377,7 @@ RCLASS_EXT_READABLE_IN_NS(VALUE obj, const rb_namespace_t *ns)
|
|||||||
{
|
{
|
||||||
if (!ns
|
if (!ns
|
||||||
|| NAMESPACE_BUILTIN_P(ns)
|
|| NAMESPACE_BUILTIN_P(ns)
|
||||||
|| RCLASS(obj)->prime_classext_readable) {
|
|| RCLASS_PRIME_CLASSEXT_READABLE_P(obj)) {
|
||||||
return RCLASS_EXT(obj);
|
return RCLASS_EXT(obj);
|
||||||
}
|
}
|
||||||
return RCLASS_EXT_READABLE_LOOKUP(obj, ns);
|
return RCLASS_EXT_READABLE_LOOKUP(obj, ns);
|
||||||
@ -364,7 +387,7 @@ static inline rb_classext_t *
|
|||||||
RCLASS_EXT_READABLE(VALUE obj)
|
RCLASS_EXT_READABLE(VALUE obj)
|
||||||
{
|
{
|
||||||
const rb_namespace_t *ns;
|
const rb_namespace_t *ns;
|
||||||
if (RCLASS(obj)->prime_classext_readable) {
|
if (RCLASS_PRIME_CLASSEXT_READABLE_P(obj)) {
|
||||||
return RCLASS_EXT(obj);
|
return RCLASS_EXT(obj);
|
||||||
}
|
}
|
||||||
// delay namespace loading to optimize for unmodified classes
|
// delay namespace loading to optimize for unmodified classes
|
||||||
@ -379,14 +402,13 @@ static inline rb_classext_t *
|
|||||||
RCLASS_EXT_WRITABLE_LOOKUP(VALUE obj, const rb_namespace_t *ns)
|
RCLASS_EXT_WRITABLE_LOOKUP(VALUE obj, const rb_namespace_t *ns)
|
||||||
{
|
{
|
||||||
rb_classext_t *ext;
|
rb_classext_t *ext;
|
||||||
int table_created = 0;
|
int first_set = 0;
|
||||||
|
|
||||||
ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(obj, ns);
|
ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(obj, ns);
|
||||||
if (ext)
|
if (ext)
|
||||||
return ext;
|
return ext;
|
||||||
|
|
||||||
if (!rb_shape_obj_too_complex_p(obj)) {
|
if (!rb_shape_obj_too_complex_p(obj)) {
|
||||||
// TODO: Handle object shapes properly
|
|
||||||
rb_evict_ivars_to_hash(obj); // fallback to ivptr for ivars from shapes
|
rb_evict_ivars_to_hash(obj); // fallback to ivptr for ivars from shapes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,9 +418,9 @@ RCLASS_EXT_WRITABLE_LOOKUP(VALUE obj, const rb_namespace_t *ns)
|
|||||||
ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(obj, ns);
|
ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(obj, ns);
|
||||||
if (!ext) {
|
if (!ext) {
|
||||||
ext = rb_class_duplicate_classext(RCLASS_EXT(obj), obj, ns);
|
ext = rb_class_duplicate_classext(RCLASS_EXT(obj), obj, ns);
|
||||||
table_created = RCLASS_SET_NAMESPACE_CLASSEXT(obj, ns, ext);
|
first_set = RCLASS_SET_NAMESPACE_CLASSEXT(obj, ns, ext);
|
||||||
if (table_created) {
|
if (first_set) {
|
||||||
RCLASS_SET_PRIME_CLASSEXT_READWRITE(obj, false, false);
|
RCLASS_SET_PRIME_CLASSEXT_WRITABLE(obj, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -411,7 +433,7 @@ RCLASS_EXT_WRITABLE_IN_NS(VALUE obj, const rb_namespace_t *ns)
|
|||||||
{
|
{
|
||||||
if (!ns
|
if (!ns
|
||||||
|| NAMESPACE_BUILTIN_P(ns)
|
|| NAMESPACE_BUILTIN_P(ns)
|
||||||
|| RCLASS(obj)->prime_classext_writable) {
|
|| RCLASS_PRIME_CLASSEXT_WRITABLE_P(obj)) {
|
||||||
return RCLASS_EXT(obj);
|
return RCLASS_EXT(obj);
|
||||||
}
|
}
|
||||||
return RCLASS_EXT_WRITABLE_LOOKUP(obj, ns);
|
return RCLASS_EXT_WRITABLE_LOOKUP(obj, ns);
|
||||||
@ -421,7 +443,7 @@ static inline rb_classext_t *
|
|||||||
RCLASS_EXT_WRITABLE(VALUE obj)
|
RCLASS_EXT_WRITABLE(VALUE obj)
|
||||||
{
|
{
|
||||||
const rb_namespace_t *ns;
|
const rb_namespace_t *ns;
|
||||||
if (RCLASS(obj)->prime_classext_writable) {
|
if (RCLASS_PRIME_CLASSEXT_WRITABLE_P(obj)) {
|
||||||
return RCLASS_EXT(obj);
|
return RCLASS_EXT(obj);
|
||||||
}
|
}
|
||||||
// delay namespace loading to optimize for unmodified classes
|
// delay namespace loading to optimize for unmodified classes
|
||||||
|
@ -527,10 +527,9 @@ namespace_initialize(VALUE namespace)
|
|||||||
|
|
||||||
// Set the Namespace object unique/consistent from any namespaces to have just single
|
// Set the Namespace object unique/consistent from any namespaces to have just single
|
||||||
// constant table from any view of every (including main) namespace.
|
// constant table from any view of every (including main) namespace.
|
||||||
// If a code in the namespace adds a constant, the constant will be visible even from main.
|
// If a code in the namespace adds a constant, the constant will be visible even from root/main.
|
||||||
RCLASS_SET_PRIME_CLASSEXT_READWRITE(namespace, true, true);
|
RCLASS_SET_PRIME_CLASSEXT_WRITABLE(namespace, true);
|
||||||
|
|
||||||
// TODO: Handle object shapes properly
|
|
||||||
// fallback to ivptr for ivars from shapes to manipulate the constant table
|
// fallback to ivptr for ivars from shapes to manipulate the constant table
|
||||||
rb_evict_ivars_to_hash(namespace);
|
rb_evict_ivars_to_hash(namespace);
|
||||||
|
|
||||||
@ -568,7 +567,7 @@ rb_namespace_current(VALUE klass)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_namespace_s_is_builtin_p(VALUE namespace, VALUE klass)
|
rb_namespace_s_is_builtin_p(VALUE namespace, VALUE klass)
|
||||||
{
|
{
|
||||||
if (RCLASS_PRIME_READABLE_P(klass) && !RCLASS_PRIME_WRITABLE_P(klass))
|
if (RCLASS_PRIME_CLASSEXT_READABLE_P(klass) && !RCLASS_PRIME_CLASSEXT_WRITABLE_P(klass))
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user