File tree Expand file tree Collapse file tree 4 files changed +21
-0
lines changed Expand file tree Collapse file tree 4 files changed +21
-0
lines changed Original file line number Diff line number Diff line change @@ -446,6 +446,7 @@ fn main() {
446
446
. allowlist_function ( "rb_obj_is_proc" )
447
447
. allowlist_function ( "rb_vm_base_ptr" )
448
448
. allowlist_function ( "rb_ec_stack_check" )
449
+ . allowlist_function ( "rb_vm_top_self" )
449
450
450
451
// We define VALUE manually, don't import it
451
452
. blocklist_type ( "VALUE" )
Original file line number Diff line number Diff line change @@ -7321,6 +7321,17 @@ fn gen_send_general(
7321
7321
assert_eq ! ( RUBY_T_CLASS , comptime_recv_klass. builtin_type( ) ,
7322
7322
"objects visible to ruby code should have a T_CLASS in their klass field" ) ;
7323
7323
7324
+
7325
+ // Don't compile calls through singleton classes to avoid retaining the recevier.
7326
+ // Make a special exception for top_self to help tests.
7327
+ if VALUE ( 0 ) != unsafe { FL_TEST ( comptime_recv_klass, VALUE ( RUBY_FL_SINGLETON as usize ) ) }
7328
+ && comptime_recv != unsafe { rb_vm_top_self ( ) }
7329
+ && !unsafe { RB_TYPE_P ( comptime_recv, RUBY_T_CLASS ) }
7330
+ && !unsafe { RB_TYPE_P ( comptime_recv, RUBY_T_MODULE ) } {
7331
+ gen_counter_incr ( asm, Counter :: send_singleton_class) ;
7332
+ return None ;
7333
+ }
7334
+
7324
7335
// Points to the receiver operand on the stack
7325
7336
let recv = asm. stack_opnd ( recv_idx) ;
7326
7337
let recv_opnd: YARVOpnd = recv. into ( ) ;
@@ -8094,6 +8105,12 @@ fn gen_invokesuper_specialized(
8094
8105
return None ;
8095
8106
}
8096
8107
8108
+ // Don't compile `super` on objects with singleton class to avoid retaining the receiver.
8109
+ if VALUE ( 0 ) != unsafe { FL_TEST ( comptime_recv. class_of ( ) , VALUE ( RUBY_FL_SINGLETON as usize ) ) } {
8110
+ gen_counter_incr ( asm, Counter :: invokesuper_singleton_class) ;
8111
+ return None ;
8112
+ }
8113
+
8097
8114
// Do method lookup
8098
8115
let cme = unsafe { rb_callable_method_entry ( comptime_superclass, mid) } ;
8099
8116
if cme. is_null ( ) {
Original file line number Diff line number Diff line change @@ -974,6 +974,7 @@ extern "C" {
974
974
n : :: std:: os:: raw:: c_long ,
975
975
elts : * const VALUE ,
976
976
) -> VALUE ;
977
+ pub fn rb_vm_top_self ( ) -> VALUE ;
977
978
pub static mut rb_vm_insns_count: u64 ;
978
979
pub fn rb_method_entry_at ( obj : VALUE , id : ID ) -> * const rb_method_entry_t ;
979
980
pub fn rb_callable_method_entry ( klass : VALUE , id : ID ) -> * const rb_callable_method_entry_t ;
Original file line number Diff line number Diff line change @@ -300,6 +300,7 @@ make_counters! {
300
300
// Method calls that fallback to dynamic dispatch
301
301
send_keywords,
302
302
send_kw_splat,
303
+ send_singleton_class,
303
304
send_args_splat_super,
304
305
send_iseq_zsuper,
305
306
send_block_arg,
@@ -388,6 +389,7 @@ make_counters! {
388
389
invokesuper_no_me,
389
390
invokesuper_not_iseq_or_cfunc,
390
391
invokesuper_refinement,
392
+ invokesuper_singleton_class,
391
393
392
394
invokeblock_megamorphic,
393
395
invokeblock_none,
You can’t perform that action at this time.
0 commit comments