@@ -3663,6 +3663,70 @@ vm_weak_table_gen_ivar_foreach_too_complex_replace_i(st_data_t *_key, st_data_t
36633663
36643664struct st_table * rb_generic_ivtbl_get (void );
36653665
3666+ static int
3667+ vm_weak_table_id_to_obj_foreach (st_data_t key , st_data_t value , st_data_t data )
3668+ {
3669+ struct global_vm_table_foreach_data * iter_data = (struct global_vm_table_foreach_data * )data ;
3670+
3671+ int ret = iter_data -> callback ((VALUE )value , iter_data -> data );
3672+
3673+ switch (ret ) {
3674+ case ST_CONTINUE :
3675+ return ret ;
3676+
3677+ case ST_DELETE :
3678+ GC_ASSERT (FL_TEST_RAW ((VALUE )value , FL_SEEN_OBJ_ID ));
3679+ FL_UNSET ((VALUE )value , FL_SEEN_OBJ_ID );
3680+ return ST_DELETE ;
3681+
3682+ case ST_REPLACE : {
3683+ VALUE new_value = (VALUE )value ;
3684+ ret = iter_data -> update_callback (& new_value , iter_data -> data );
3685+ if (value != new_value ) {
3686+ st_insert (id_to_obj_tbl , key , (st_data_t )new_value );
3687+ }
3688+ return ST_CONTINUE ;
3689+ }
3690+ }
3691+
3692+ return ret ;
3693+ }
3694+
3695+ static int
3696+ vm_weak_table_id_to_obj_keys_foreach (st_data_t key , st_data_t value , st_data_t data )
3697+ {
3698+ struct global_vm_table_foreach_data * iter_data = (struct global_vm_table_foreach_data * )data ;
3699+
3700+ if (LIKELY (FIXNUM_P ((VALUE )key ))) {
3701+ return ST_CONTINUE ;
3702+ }
3703+
3704+ int ret = iter_data -> callback ((VALUE )key , iter_data -> data );
3705+
3706+ switch (ret ) {
3707+ case ST_CONTINUE :
3708+ return ret ;
3709+
3710+ case ST_DELETE :
3711+ return ST_DELETE ;
3712+
3713+ case ST_REPLACE : {
3714+ VALUE new_key = (VALUE )key ;
3715+ ret = iter_data -> update_callback (& new_key , iter_data -> data );
3716+ if (key != new_key ) ret = ST_DELETE ;
3717+ DURING_GC_COULD_MALLOC_REGION_START ();
3718+ {
3719+ st_insert (id_to_obj_tbl , (st_data_t )new_key , value );
3720+ }
3721+ DURING_GC_COULD_MALLOC_REGION_END ();
3722+ key = (st_data_t )new_key ;
3723+ break ;
3724+ }
3725+ }
3726+
3727+ return ret ;
3728+ }
3729+
36663730static int
36673731vm_weak_table_gen_ivar_foreach (st_data_t key , st_data_t value , st_data_t data )
36683732{
@@ -3790,6 +3854,26 @@ rb_gc_vm_weak_table_foreach(vm_table_foreach_callback_func callback,
37903854 }
37913855 break ;
37923856 }
3857+ case RB_GC_VM_ID_TO_OBJ_TABLE : {
3858+ if (id_to_obj_tbl ) {
3859+ st_foreach (
3860+ id_to_obj_tbl ,
3861+ vm_weak_table_id_to_obj_foreach ,
3862+ (st_data_t )& foreach_data
3863+ );
3864+ }
3865+ break ;
3866+ }
3867+ case RB_GC_VM_ID_TO_OBJ_TABLE_KEYS : {
3868+ if (id_to_obj_tbl && !RB_POSFIXABLE (next_object_id )) {
3869+ st_foreach (
3870+ id_to_obj_tbl ,
3871+ vm_weak_table_id_to_obj_keys_foreach ,
3872+ (st_data_t )& foreach_data
3873+ );
3874+ }
3875+ break ;
3876+ }
37933877 case RB_GC_VM_GENERIC_IV_TABLE : {
37943878 st_table * generic_iv_tbl = rb_generic_ivtbl_get ();
37953879 if (generic_iv_tbl ) {
@@ -3809,8 +3893,8 @@ rb_gc_vm_weak_table_foreach(vm_table_foreach_callback_func callback,
38093893 );
38103894 break ;
38113895 }
3812- default :
3813- rb_bug ("rb_gc_vm_weak_table_foreach: unknown table %d" , table );
3896+ case RB_GC_VM_WEAK_TABLE_COUNT :
3897+ rb_bug ("Unreacheable" );
38143898 }
38153899}
38163900
0 commit comments