Move FL_SINGLETON to FL_USER1

This frees FL_USER0 on both T_MODULE and T_CLASS.

Note: prior to this, FL_SINGLETON was never set on T_MODULE,
so checking for `FL_SINGLETON` without first checking that
`FL_TYPE` was `T_CLASS` was valid. That's no longer the case.
This commit is contained in:
Jean Boussier 2024-03-06 11:04:22 -05:00 committed by Peter Zhu
parent b88973165a
commit b4a69351ec
23 changed files with 76 additions and 56 deletions

30
class.c
View File

@ -32,7 +32,7 @@
/* Flags of T_CLASS
*
* 0: RUBY_FL_SINGLETON
* 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.
@ -340,7 +340,7 @@ rb_check_inheritable(VALUE super)
rb_raise(rb_eTypeError, "superclass must be an instance of Class (given an instance of %"PRIsVALUE")",
rb_obj_class(super));
}
if (RBASIC(super)->flags & FL_SINGLETON) {
if (RCLASS_SINGLETON_P(super)) {
rb_raise(rb_eTypeError, "can't make subclass of singleton class");
}
if (super == rb_cClass) {
@ -426,7 +426,7 @@ class_init_copy_check(VALUE clone, VALUE orig)
if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) {
rb_raise(rb_eTypeError, "already initialized class");
}
if (FL_TEST(orig, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(orig)) {
rb_raise(rb_eTypeError, "can't copy singleton class");
}
}
@ -544,7 +544,7 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
RCLASS_EXT(clone)->cloned = true;
RCLASS_EXT(orig)->cloned = true;
if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
if (!RCLASS_SINGLETON_P(CLASS_OF(clone))) {
RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig));
rb_singleton_class_attached(METACLASS_OF(clone), (VALUE)clone);
}
@ -650,7 +650,7 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
// attached to an object other than `obj`. In which case `obj` does not have
// a material singleton class attached yet and there is no singleton class
// to clone.
if (!(FL_TEST(klass, FL_SINGLETON) && RCLASS_ATTACHED_OBJECT(klass) == obj)) {
if (!(RCLASS_SINGLETON_P(klass) && RCLASS_ATTACHED_OBJECT(klass) == obj)) {
// nothing to clone
return klass;
}
@ -701,7 +701,7 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
void
rb_singleton_class_attached(VALUE klass, VALUE obj)
{
if (FL_TEST(klass, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(klass)) {
RCLASS_SET_ATTACHED_OBJECT(klass, obj);
}
}
@ -1607,7 +1607,7 @@ class_descendants_recursive(VALUE klass, VALUE v)
{
struct subclass_traverse_data *data = (struct subclass_traverse_data *) v;
if (BUILTIN_TYPE(klass) == T_CLASS && !FL_TEST(klass, FL_SINGLETON)) {
if (BUILTIN_TYPE(klass) == T_CLASS && !RCLASS_SINGLETON_P(klass)) {
if (data->buffer && data->count < data->maxcount && !rb_objspace_garbage_object_p(klass)) {
// assumes that this does not cause GC as long as the length does not exceed the capacity
rb_ary_push(data->buffer, klass);
@ -1712,7 +1712,7 @@ rb_class_subclasses(VALUE klass)
VALUE
rb_class_attached_object(VALUE klass)
{
if (!FL_TEST(klass, FL_SINGLETON)) {
if (!RCLASS_SINGLETON_P(klass)) {
rb_raise(rb_eTypeError, "'%"PRIsVALUE"' is not a singleton class", klass);
}
@ -1815,7 +1815,7 @@ static bool
particular_class_p(VALUE mod)
{
if (!mod) return false;
if (FL_TEST(mod, FL_SINGLETON)) return true;
if (RCLASS_SINGLETON_P(mod)) return true;
if (BUILTIN_TYPE(mod) == T_ICLASS) return true;
return false;
}
@ -2092,19 +2092,19 @@ rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
int recur = TRUE;
if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]);
if (RB_TYPE_P(obj, T_CLASS) && FL_TEST(obj, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(obj)) {
rb_singleton_class(obj);
}
klass = CLASS_OF(obj);
origin = RCLASS_ORIGIN(klass);
me_arg.list = st_init_numtable();
me_arg.recur = recur;
if (klass && FL_TEST(klass, FL_SINGLETON)) {
if (klass && RCLASS_SINGLETON_P(klass)) {
if ((mtbl = RCLASS_M_TBL(origin)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
klass = RCLASS_SUPER(klass);
}
if (recur) {
while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) {
while (klass && (RCLASS_SINGLETON_P(klass) || RB_TYPE_P(klass, T_ICLASS))) {
if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
klass = RCLASS_SUPER(klass);
}
@ -2244,7 +2244,7 @@ singleton_class_of(VALUE obj)
}
klass = METACLASS_OF(obj);
if (!(FL_TEST(klass, FL_SINGLETON) &&
if (!(RCLASS_SINGLETON_P(klass) &&
RCLASS_ATTACHED_OBJECT(klass) == obj)) {
klass = rb_make_metaclass(obj, klass);
}
@ -2258,7 +2258,7 @@ void
rb_freeze_singleton_class(VALUE x)
{
/* should not propagate to meta-meta-class, and so on */
if (!(RBASIC(x)->flags & FL_SINGLETON)) {
if (!RCLASS_SINGLETON_P(x)) {
VALUE klass = RBASIC_CLASS(x);
if (klass && // no class when hidden from ObjectSpace
FL_TEST(klass, (FL_SINGLETON|FL_FREEZE)) == FL_SINGLETON) {
@ -2283,7 +2283,7 @@ rb_singleton_class_get(VALUE obj)
return rb_special_singleton_class(obj);
}
klass = METACLASS_OF(obj);
if (!FL_TEST(klass, FL_SINGLETON)) return Qnil;
if (!RCLASS_SINGLETON_P(klass)) return Qnil;
if (RCLASS_ATTACHED_OBJECT(klass) != obj) return Qnil;
return klass;
}

View File

@ -6537,6 +6537,7 @@ error.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
error.$(OBJEXT): {$(VPATH)}builtin.h
error.$(OBJEXT): {$(VPATH)}config.h
error.$(OBJEXT): {$(VPATH)}constant.h
error.$(OBJEXT): {$(VPATH)}debug_counter.h
error.$(OBJEXT): {$(VPATH)}defines.h
error.$(OBJEXT): {$(VPATH)}encoding.h
error.$(OBJEXT): {$(VPATH)}error.c
@ -6709,7 +6710,9 @@ error.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
error.$(OBJEXT): {$(VPATH)}thread_native.h
error.$(OBJEXT): {$(VPATH)}util.h
error.$(OBJEXT): {$(VPATH)}vm_core.h
error.$(OBJEXT): {$(VPATH)}vm_debug.h
error.$(OBJEXT): {$(VPATH)}vm_opts.h
error.$(OBJEXT): {$(VPATH)}vm_sync.h
error.$(OBJEXT): {$(VPATH)}warning.rbinc
error.$(OBJEXT): {$(VPATH)}yjit.h
eval.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
@ -8353,6 +8356,7 @@ io.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
io.$(OBJEXT): {$(VPATH)}builtin.h
io.$(OBJEXT): {$(VPATH)}config.h
io.$(OBJEXT): {$(VPATH)}constant.h
io.$(OBJEXT): {$(VPATH)}debug_counter.h
io.$(OBJEXT): {$(VPATH)}defines.h
io.$(OBJEXT): {$(VPATH)}dln.h
io.$(OBJEXT): {$(VPATH)}encindex.h
@ -8531,7 +8535,9 @@ io.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
io.$(OBJEXT): {$(VPATH)}thread_native.h
io.$(OBJEXT): {$(VPATH)}util.h
io.$(OBJEXT): {$(VPATH)}vm_core.h
io.$(OBJEXT): {$(VPATH)}vm_debug.h
io.$(OBJEXT): {$(VPATH)}vm_opts.h
io.$(OBJEXT): {$(VPATH)}vm_sync.h
io_buffer.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
io_buffer.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
io_buffer.$(OBJEXT): $(CCAN_DIR)/list/list.h
@ -10790,6 +10796,7 @@ node_dump.$(OBJEXT): $(top_srcdir)/internal/array.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/bignum.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/bits.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/class.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/complex.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
@ -10818,6 +10825,7 @@ node_dump.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
node_dump.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
node_dump.$(OBJEXT): {$(VPATH)}config.h
node_dump.$(OBJEXT): {$(VPATH)}constant.h
node_dump.$(OBJEXT): {$(VPATH)}debug_counter.h
node_dump.$(OBJEXT): {$(VPATH)}defines.h
node_dump.$(OBJEXT): {$(VPATH)}encoding.h
node_dump.$(OBJEXT): {$(VPATH)}id.h
@ -10987,7 +10995,9 @@ node_dump.$(OBJEXT): {$(VPATH)}subst.h
node_dump.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
node_dump.$(OBJEXT): {$(VPATH)}thread_native.h
node_dump.$(OBJEXT): {$(VPATH)}vm_core.h
node_dump.$(OBJEXT): {$(VPATH)}vm_debug.h
node_dump.$(OBJEXT): {$(VPATH)}vm_opts.h
node_dump.$(OBJEXT): {$(VPATH)}vm_sync.h
numeric.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
numeric.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
numeric.$(OBJEXT): $(CCAN_DIR)/list/list.h

View File

@ -32,6 +32,7 @@
#endif
#include "internal.h"
#include "internal/class.h"
#include "internal/error.h"
#include "internal/eval.h"
#include "internal/hash.h"
@ -2388,7 +2389,7 @@ name_err_mesg_to_str(VALUE obj)
VALUE klass;
object:
klass = CLASS_OF(obj);
if (RB_TYPE_P(klass, T_CLASS) && FL_TEST(klass, FL_SINGLETON)) {
if (RB_TYPE_P(klass, T_CLASS) && RCLASS_SINGLETON_P(klass)) {
s = FAKE_CSTR(&s_str, "");
if (obj == rb_vm_top_self()) {
c = FAKE_CSTR(&c_str, "main");

2
eval.c
View File

@ -428,7 +428,7 @@ rb_class_modify_check(VALUE klass)
if (OBJ_FROZEN(klass)) {
const char *desc;
if (FL_TEST(klass, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(klass)) {
desc = "object";
klass = RCLASS_ATTACHED_OBJECT(klass);
if (!SPECIAL_CONST_P(klass)) {

View File

@ -560,7 +560,7 @@ dump_object(VALUE obj, struct dump_config *dc)
}
}
if (FL_TEST(obj, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(obj)) {
dump_append(dc, ", \"singleton\":true");
}
}

2
gc.c
View File

@ -3763,7 +3763,7 @@ internal_object_p(VALUE obj)
break;
case T_CLASS:
if (!p->as.basic.klass) break;
if (FL_TEST(obj, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(obj)) {
return rb_singleton_class_internal_p(obj);
}
return 0;

View File

@ -395,7 +395,7 @@ ruby_fl_type {
* 3rd parties. It must be an implementation detail that they should never
* know. Might better be hidden.
*/
RUBY_FL_SINGLETON = RUBY_FL_USER0,
RUBY_FL_SINGLETON = RUBY_FL_USER1,
};
enum {

View File

@ -195,10 +195,16 @@ 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)
{
if (FL_TEST_RAW(klass, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(klass)) {
return 0;
}
return RCLASS_EXT(klass)->as.class.allocator;
@ -207,7 +213,7 @@ RCLASS_ALLOCATOR(VALUE klass)
static inline void
RCLASS_SET_ALLOCATOR(VALUE klass, rb_alloc_func_t allocator)
{
assert(!FL_TEST(klass, FL_SINGLETON));
assert(!RCLASS_SINGLETON_P(klass));
RCLASS_EXT(klass)->as.class.allocator = allocator;
}
@ -267,8 +273,7 @@ RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent)
static inline VALUE
RCLASS_SET_ATTACHED_OBJECT(VALUE klass, VALUE attached_object)
{
assert(BUILTIN_TYPE(klass) == T_CLASS);
assert(FL_TEST_RAW(klass, FL_SINGLETON));
assert(RCLASS_SINGLETON_P(klass));
RB_OBJ_WRITE(klass, &RCLASS_EXT(klass)->as.singleton_class.attached_object, attached_object);
return attached_object;

3
io.c
View File

@ -112,6 +112,7 @@
#include "encindex.h"
#include "id.h"
#include "internal.h"
#include "internal/class.h"
#include "internal/encoding.h"
#include "internal/error.h"
#include "internal/inits.h"
@ -2276,7 +2277,7 @@ rb_io_writev(VALUE io, int argc, const VALUE *argv)
if (argc > 1 && rb_obj_method_arity(io, id_write) == 1) {
if (io != rb_ractor_stderr() && RTEST(ruby_verbose)) {
VALUE klass = CLASS_OF(io);
char sep = FL_TEST(klass, FL_SINGLETON) ? (klass = io, '.') : '#';
char sep = RCLASS_SINGLETON_P(klass) ? (klass = io, '.') : '#';
rb_category_warning(
RB_WARN_CATEGORY_DEPRECATED, "%+"PRIsVALUE"%c""write is outdated interface"
" which accepts just one argument",

View File

@ -3736,7 +3736,7 @@ module RubyVM::RJIT
ctx.upgrade_opnd_type(insn_opnd, Type::Flonum)
end
elsif C.FL_TEST(known_klass, C::RUBY_FL_SINGLETON) && comptime_obj == C.rb_class_attached_object(known_klass)
elsif C.RCLASS_SINGLETON_P(known_klass) && comptime_obj == C.rb_class_attached_object(known_klass)
# Singleton classes are attached to one specific object, so we can
# avoid one memory access (and potentially the is_heap check) by
# looking for the expected object directly.

View File

@ -533,7 +533,7 @@ hash_each(VALUE key, VALUE value, VALUE v)
static void
w_extended(VALUE klass, struct dump_arg *arg, int check)
{
if (check && FL_TEST(klass, FL_SINGLETON)) {
if (check && RCLASS_SINGLETON_P(klass)) {
VALUE origin = RCLASS_ORIGIN(klass);
if (SINGLETON_DUMP_UNABLE_P(klass) ||
(origin != klass && SINGLETON_DUMP_UNABLE_P(origin))) {

View File

@ -10,6 +10,7 @@
**********************************************************************/
#include "internal.h"
#include "internal/class.h"
#include "internal/hash.h"
#include "internal/ruby_parser.h"
#include "internal/variable.h"
@ -89,7 +90,7 @@ rb_dump_literal(VALUE lit)
switch (RB_BUILTIN_TYPE(lit)) {
case T_CLASS: case T_MODULE: case T_ICLASS:
str = rb_class_path(lit);
if (FL_TEST(lit, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(lit)) {
str = rb_sprintf("<%"PRIsVALUE">", str);
}
return str;

View File

@ -288,7 +288,7 @@ VALUE
rb_class_real(VALUE cl)
{
while (cl &&
((RBASIC(cl)->flags & FL_SINGLETON) || BUILTIN_TYPE(cl) == T_ICLASS)) {
(RCLASS_SINGLETON_P(cl) || BUILTIN_TYPE(cl) == T_ICLASS)) {
cl = RCLASS_SUPER(cl);
}
return cl;
@ -493,7 +493,7 @@ rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze)
VALUE singleton = rb_singleton_class_clone_and_attach(obj, clone);
RBASIC_SET_CLASS(clone, singleton);
if (FL_TEST(singleton, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(singleton)) {
rb_singleton_class_attached(singleton, clone);
}
@ -1745,7 +1745,7 @@ rb_mod_to_s(VALUE klass)
ID id_defined_at;
VALUE refined_class, defined_at;
if (FL_TEST(klass, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(klass)) {
VALUE s = rb_usascii_str_new2("#<Class:");
VALUE v = RCLASS_ATTACHED_OBJECT(klass);
@ -2121,7 +2121,7 @@ class_get_alloc_func(VALUE klass)
if (RCLASS_SUPER(klass) == 0 && klass != rb_cBasicObject) {
rb_raise(rb_eTypeError, "can't instantiate uninitialized class");
}
if (FL_TEST(klass, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(klass)) {
rb_raise(rb_eTypeError, "can't create instance of singleton class");
}
allocator = rb_get_alloc_func(klass);
@ -3082,7 +3082,7 @@ rb_mod_cvar_defined(VALUE obj, VALUE iv)
static VALUE
rb_mod_singleton_p(VALUE klass)
{
return RBOOL(RB_TYPE_P(klass, T_CLASS) && FL_TEST(klass, FL_SINGLETON));
return RBOOL(RCLASS_SINGLETON_P(klass));
}
/*! \private */

10
proc.c
View File

@ -1945,7 +1945,7 @@ rb_method_name_error(VALUE klass, VALUE str)
VALUE c = klass;
VALUE s = Qundef;
if (FL_TEST(c, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(c)) {
VALUE obj = RCLASS_ATTACHED_OBJECT(klass);
switch (BUILTIN_TYPE(obj)) {
@ -2194,7 +2194,7 @@ rb_mod_define_method_with_visibility(int argc, VALUE *argv, VALUE mod, const str
struct METHOD *method = (struct METHOD *)RTYPEDDATA_GET_DATA(body);
if (method->me->owner != mod && !RB_TYPE_P(method->me->owner, T_MODULE) &&
!RTEST(rb_class_inherited_p(mod, method->me->owner))) {
if (FL_TEST(method->me->owner, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(method->me->owner)) {
rb_raise(rb_eTypeError,
"can't bind singleton method to a different class");
}
@ -2561,7 +2561,7 @@ convert_umethod_to_method_components(const struct METHOD *data, VALUE recv, VALU
if (!NIL_P(refined_class)) methclass = refined_class;
}
if (!RB_TYPE_P(methclass, T_MODULE) && !RTEST(rb_obj_is_kind_of(recv, methclass))) {
if (FL_TEST(methclass, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(methclass)) {
rb_raise(rb_eTypeError,
"singleton method called for a different object");
}
@ -3132,7 +3132,7 @@ method_inspect(VALUE method)
// UnboundMethod
rb_str_buf_append(str, rb_inspect(defined_class));
}
else if (FL_TEST(mklass, FL_SINGLETON)) {
else if (RCLASS_SINGLETON_P(mklass)) {
VALUE v = RCLASS_ATTACHED_OBJECT(mklass);
if (UNDEF_P(data->recv)) {
@ -3152,7 +3152,7 @@ method_inspect(VALUE method)
}
else {
mklass = data->klass;
if (FL_TEST(mklass, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(mklass)) {
VALUE v = RCLASS_ATTACHED_OBJECT(mklass);
if (!(RB_TYPE_P(v, T_CLASS) || RB_TYPE_P(v, T_MODULE))) {
do {

View File

@ -326,6 +326,10 @@ module RubyVM::RJIT # :nodoc: all
def RCLASS_ORIGIN(klass)
Primitive.cexpr! 'RCLASS_ORIGIN(klass)'
end
def RCLASS_SINGLETON_P(klass)
Primitive.cexpr! 'RCLASS_SINGLETON_P(klass)'
end
end
#
@ -392,7 +396,6 @@ module RubyVM::RJIT # :nodoc: all
C::RUBY_FLONUM_FLAG = Primitive.cexpr! %q{ SIZET2NUM(RUBY_FLONUM_FLAG) }
C::RUBY_FLONUM_MASK = Primitive.cexpr! %q{ SIZET2NUM(RUBY_FLONUM_MASK) }
C::RUBY_FL_FREEZE = Primitive.cexpr! %q{ SIZET2NUM(RUBY_FL_FREEZE) }
C::RUBY_FL_SINGLETON = Primitive.cexpr! %q{ SIZET2NUM(RUBY_FL_SINGLETON) }
C::RUBY_IMMEDIATE_MASK = Primitive.cexpr! %q{ SIZET2NUM(RUBY_IMMEDIATE_MASK) }
C::RUBY_SPECIAL_SHIFT = Primitive.cexpr! %q{ SIZET2NUM(RUBY_SPECIAL_SHIFT) }
C::RUBY_SYMBOL_FLAG = Primitive.cexpr! %q{ SIZET2NUM(RUBY_SYMBOL_FLAG) }

View File

@ -423,7 +423,6 @@ generator = BindingGenerator.new(
RUBY_FIXNUM_FLAG
RUBY_FLONUM_FLAG
RUBY_FLONUM_MASK
RUBY_FL_SINGLETON
RUBY_IMMEDIATE_MASK
RUBY_SPECIAL_SHIFT
RUBY_SYMBOL_FLAG

View File

@ -1826,7 +1826,7 @@ void rb_obj_freeze_inline(VALUE x)
}
rb_shape_set_shape(x, next_shape);
if (RBASIC_CLASS(x) && !(RBASIC(x)->flags & RUBY_FL_SINGLETON)) {
if (RBASIC_CLASS(x)) {
rb_freeze_singleton_class(x);
}
}
@ -3855,7 +3855,7 @@ cvar_lookup_at(VALUE klass, ID id, st_data_t *v)
static VALUE
cvar_front_klass(VALUE klass)
{
if (FL_TEST(klass, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(klass)) {
VALUE obj = RCLASS_ATTACHED_OBJECT(klass);
if (rb_namespace_p(obj)) {
return obj;
@ -4064,7 +4064,7 @@ static void*
mod_cvar_of(VALUE mod, void *data)
{
VALUE tmp = mod;
if (FL_TEST(mod, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(mod)) {
if (rb_namespace_p(RCLASS_ATTACHED_OBJECT(mod))) {
data = mod_cvar_at(tmp, data);
tmp = cvar_front_klass(tmp);

2
vm.c
View File

@ -619,7 +619,7 @@ rb_dtrace_setup(rb_execution_context_t *ec, VALUE klass, ID id,
if (RB_TYPE_P(klass, T_ICLASS)) {
klass = RBASIC(klass)->klass;
}
else if (FL_TEST(klass, FL_SINGLETON)) {
else if (RCLASS_SINGLETON_P(klass)) {
klass = RCLASS_ATTACHED_OBJECT(klass);
if (NIL_P(klass)) return FALSE;
}

View File

@ -198,7 +198,7 @@ gen_method_name(VALUE owner, VALUE name)
{
bool permanent;
if (RB_TYPE_P(owner, T_CLASS) || RB_TYPE_P(owner, T_MODULE)) {
if (RBASIC(owner)->flags & FL_SINGLETON) {
if (RCLASS_SINGLETON_P(owner)) {
VALUE v = RCLASS_ATTACHED_OBJECT(owner);
if (RB_TYPE_P(v, T_CLASS) || RB_TYPE_P(v, T_MODULE)) {
v = rb_mod_name0(v, &permanent);
@ -1784,7 +1784,7 @@ rb_profile_frame_classpath(VALUE frame)
if (RB_TYPE_P(klass, T_ICLASS)) {
klass = RBASIC(klass)->klass;
}
else if (FL_TEST(klass, FL_SINGLETON)) {
else if (RCLASS_SINGLETON_P(klass)) {
klass = RCLASS_ATTACHED_OBJECT(klass);
if (!RB_TYPE_P(klass, T_CLASS) && !RB_TYPE_P(klass, T_MODULE))
return rb_sprintf("#<%s:%p>", rb_class2name(rb_obj_class(klass)), (void*)klass);
@ -1801,7 +1801,7 @@ rb_profile_frame_singleton_method_p(VALUE frame)
{
VALUE klass = frame2klass(frame);
return RBOOL(klass && !NIL_P(klass) && FL_TEST(klass, FL_SINGLETON));
return RBOOL(klass && !NIL_P(klass) && RCLASS_SINGLETON_P(klass));
}
VALUE

View File

@ -957,7 +957,7 @@ vm_get_const_key_cref(const VALUE *ep)
const rb_cref_t *key_cref = cref;
while (cref) {
if (FL_TEST(CREF_CLASS(cref), FL_SINGLETON) ||
if (RCLASS_SINGLETON_P(CREF_CLASS(cref)) ||
RCLASS_EXT(CREF_CLASS(cref))->cloned) {
return key_cref;
}
@ -1171,7 +1171,7 @@ vm_get_cvar_base(const rb_cref_t *cref, const rb_control_frame_t *cfp, int top_l
}
while (CREF_NEXT(cref) &&
(NIL_P(CREF_CLASS(cref)) || FL_TEST(CREF_CLASS(cref), FL_SINGLETON) ||
(NIL_P(CREF_CLASS(cref)) || RCLASS_SINGLETON_P(CREF_CLASS(cref)) ||
CREF_PUSHED_BY_EVAL(cref) || CREF_SINGLETON(cref))) {
cref = CREF_NEXT(cref);
}

View File

@ -962,7 +962,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil
}
orig_klass = klass;
if (!FL_TEST(klass, FL_SINGLETON) &&
if (!RCLASS_SINGLETON_P(klass) &&
type != VM_METHOD_TYPE_NOTIMPLEMENTED &&
type != VM_METHOD_TYPE_ZSUPER) {
switch (mid) {
@ -1199,7 +1199,7 @@ rb_check_overloaded_cme(const rb_callable_method_entry_t *cme, const struct rb_c
const VALUE arg = ID2SYM(mid); \
VALUE recv_class = (klass); \
ID hook_id = (hook); \
if (FL_TEST((klass), FL_SINGLETON)) { \
if (RCLASS_SINGLETON_P((klass))) { \
recv_class = RCLASS_ATTACHED_OBJECT((klass)); \
hook_id = singleton_##hook; \
} \
@ -1264,7 +1264,7 @@ void
rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE))
{
Check_Type(klass, T_CLASS);
if (FL_TEST_RAW(klass, FL_SINGLETON)) {
if (RCLASS_SINGLETON_P(klass)) {
rb_raise(rb_eTypeError, "can't define an allocator for a singleton class");
}
RCLASS_SET_ALLOCATOR(klass, func);
@ -2898,8 +2898,8 @@ vm_respond_to(rb_execution_context_t *ec, VALUE klass, VALUE obj, ID id, int pri
rb_category_warn(RB_WARN_CATEGORY_DEPRECATED,
"%"PRIsVALUE"%c""respond_to?(:%"PRIsVALUE") uses"
" the deprecated method signature, which takes one parameter",
(FL_TEST(klass, FL_SINGLETON) ? obj : klass),
(FL_TEST(klass, FL_SINGLETON) ? '.' : '#'),
(RCLASS_SINGLETON_P(klass) ? obj : klass),
(RCLASS_SINGLETON_P(klass) ? '.' : '#'),
QUOTE_ID(id));
if (!NIL_P(location)) {
VALUE path = RARRAY_AREF(location, 0);

View File

@ -734,7 +734,7 @@ call_trace_func(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klas
if (RB_TYPE_P(klass, T_ICLASS)) {
klass = RBASIC(klass)->klass;
}
else if (FL_TEST(klass, FL_SINGLETON)) {
else if (RCLASS_SINGLETON_P(klass)) {
klass = RCLASS_ATTACHED_OBJECT(klass);
}
}

View File

@ -252,7 +252,7 @@ pub const RUBY_FL_USER17: ruby_fl_type = 536870912;
pub const RUBY_FL_USER18: ruby_fl_type = 1073741824;
pub const RUBY_FL_USER19: ruby_fl_type = -2147483648;
pub const RUBY_ELTS_SHARED: ruby_fl_type = 16384;
pub const RUBY_FL_SINGLETON: ruby_fl_type = 4096;
pub const RUBY_FL_SINGLETON: ruby_fl_type = 8192;
pub type ruby_fl_type = i32;
pub const RSTRING_NOEMBED: ruby_rstring_flags = 8192;
pub const RSTRING_FSTR: ruby_rstring_flags = 536870912;