Skip to content

Commit 2e8459e

Browse files
committed
Singleton classes of unshareable objects are not shareable
Currently, all RClasses are created as shareable in `class_alloc0`, which causes singleton classes of unshareable objects to be shareable which allows passing unshareable objects by passing their singleton class and getting their attached object. This changes `singleton_class_of` to mark the singleton class as shareable when the object is shareable, and inversely, to mark the singleton class as unshareable if the object is unshareable. We also need to not forcibly mark the class as shareable in `shareable_p_enter`. Additionally, if the object is not yet marked as shareable, but is frozen (and `allow_frozen_shareable_p`), it becomes marked as shareable through `rb_ractor_shareable_p`, and we need to also mark its singleton class as shareable at that point.
1 parent 8c7e6f2 commit 2e8459e

File tree

3 files changed

+20
-3
lines changed

3 files changed

+20
-3
lines changed

class.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "internal/string.h"
3030
#include "internal/variable.h"
3131
#include "ruby/st.h"
32+
#include "ruby/ractor.h"
3233
#include "vm_core.h"
3334
#include "ruby/ractor.h"
3435
#include "yjit.h"
@@ -2864,6 +2865,12 @@ singleton_class_of(VALUE obj, bool ensure_eigenclass)
28642865
klass = rb_make_metaclass(obj, klass);
28652866
}
28662867
RB_FL_SET_RAW(klass, RB_OBJ_FROZEN_RAW(obj));
2868+
if (!RB_OBJ_SHAREABLE_P(obj) && RB_OBJ_SHAREABLE_P(klass)) {
2869+
RB_FL_UNSET_RAW(klass, RUBY_FL_SHAREABLE);
2870+
}
2871+
else if (RB_OBJ_SHAREABLE_P(obj) && !RB_OBJ_SHAREABLE_P(klass)) {
2872+
RB_FL_SET_RAW(klass, RUBY_FL_SHAREABLE);
2873+
}
28672874
if (ensure_eigenclass && RB_TYPE_P(obj, T_CLASS)) {
28682875
/* ensures an exposed class belongs to its own eigenclass */
28692876
(void)ENSURE_EIGENCLASS(klass);

depend

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12523,6 +12523,7 @@ ractor.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
1252312523
ractor.$(OBJEXT): $(top_srcdir)/internal/bignum.h
1252412524
ractor.$(OBJEXT): $(top_srcdir)/internal/bits.h
1252512525
ractor.$(OBJEXT): $(top_srcdir)/internal/box.h
12526+
ractor.$(OBJEXT): $(top_srcdir)/internal/class.h
1252612527
ractor.$(OBJEXT): $(top_srcdir)/internal/compilers.h
1252712528
ractor.$(OBJEXT): $(top_srcdir)/internal/complex.h
1252812529
ractor.$(OBJEXT): $(top_srcdir)/internal/error.h

ractor.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "vm_core.h"
99
#include "vm_sync.h"
1010
#include "ractor_core.h"
11+
#include "internal/class.h"
1112
#include "internal/complex.h"
1213
#include "internal/error.h"
1314
#include "internal/gc.h"
@@ -1540,6 +1541,9 @@ mark_shareable(VALUE obj)
15401541
}
15411542

15421543
rb_obj_set_shareable_no_assert(obj);
1544+
if (RCLASS_SINGLETON_P(RBASIC(obj)->klass)) {
1545+
rb_obj_set_shareable_no_assert(RBASIC(obj)->klass);
1546+
}
15431547
return traverse_cont;
15441548
}
15451549

@@ -1587,9 +1591,14 @@ shareable_p_enter(VALUE obj)
15871591
else if (RB_TYPE_P(obj, T_CLASS) ||
15881592
RB_TYPE_P(obj, T_MODULE) ||
15891593
RB_TYPE_P(obj, T_ICLASS)) {
1590-
// TODO: remove it
1591-
mark_shareable(obj);
1592-
return traverse_skip;
1594+
if (RCLASS_SINGLETON_P(obj) && !RB_OBJ_SHAREABLE_P(RCLASS_ATTACHED_OBJECT(obj))) {
1595+
return traverse_stop;
1596+
}
1597+
else {
1598+
// TODO: remove it
1599+
mark_shareable(obj);
1600+
return traverse_skip;
1601+
}
15931602
}
15941603
else if (RB_OBJ_FROZEN_RAW(obj) &&
15951604
allow_frozen_shareable_p(obj)) {

0 commit comments

Comments
 (0)