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:
parent
b88973165a
commit
b4a69351ec
30
class.c
30
class.c
@ -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;
|
||||
}
|
||||
|
10
common.mk
10
common.mk
@ -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
|
||||
|
3
error.c
3
error.c
@ -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
2
eval.c
@ -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)) {
|
||||
|
@ -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
2
gc.c
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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
3
io.c
@ -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",
|
||||
|
@ -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.
|
||||
|
@ -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))) {
|
||||
|
@ -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;
|
||||
|
10
object.c
10
object.c
@ -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
10
proc.c
@ -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 {
|
||||
|
@ -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) }
|
||||
|
@ -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
|
||||
|
@ -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
2
vm.c
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
10
vm_method.c
10
vm_method.c
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user