Refactor rewrite_cref

This commit is contained in:
John Hawthorn 2025-06-07 20:59:04 -07:00
parent 7c3bbfcddb
commit 443ed45a4e
3 changed files with 23 additions and 11 deletions

View file

@ -877,8 +877,7 @@ static void
clone_method(VALUE old_klass, VALUE new_klass, ID mid, const rb_method_entry_t *me)
{
if (me->def->type == VM_METHOD_TYPE_ISEQ) {
rb_cref_t *new_cref;
rb_vm_rewrite_cref(me->def->body.iseq.cref, old_klass, new_klass, &new_cref);
rb_cref_t *new_cref = rb_vm_rewrite_cref(me->def->body.iseq.cref, old_klass, new_klass);
rb_add_method_iseq(new_klass, mid, me->def->body.iseq.iseqptr, new_cref, METHOD_ENTRY_VISI(me));
}
else {

View file

@ -1922,7 +1922,7 @@ void rb_vm_register_special_exception_str(enum ruby_special_exceptions sp, VALUE
void rb_gc_mark_machine_context(const rb_execution_context_t *ec);
void rb_vm_rewrite_cref(rb_cref_t *node, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr);
rb_cref_t *rb_vm_rewrite_cref(rb_cref_t *node, VALUE old_klass, VALUE new_klass);
const rb_callable_method_entry_t *rb_vm_frame_method_entry(const rb_control_frame_t *cfp);

View file

@ -967,23 +967,36 @@ vm_get_const_key_cref(const VALUE *ep)
return NULL;
}
void
rb_vm_rewrite_cref(rb_cref_t *cref, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr)
rb_cref_t *
rb_vm_rewrite_cref(rb_cref_t *cref, VALUE old_klass, VALUE new_klass)
{
rb_cref_t *new_cref;
rb_cref_t *new_cref_head = NULL;
rb_cref_t *new_cref_tail = NULL;
#define ADD_NEW_CREF(new_cref) \
if (new_cref_tail) { \
new_cref_tail->next = new_cref; \
} else { \
new_cref_head = new_cref; \
} \
new_cref_tail = new_cref;
while (cref) {
rb_cref_t *new_cref;
if (CREF_CLASS(cref) == old_klass) {
new_cref = vm_cref_new_use_prev(new_klass, METHOD_VISI_UNDEF, FALSE, cref, FALSE);
*new_cref_ptr = new_cref;
return;
ADD_NEW_CREF(new_cref);
return new_cref_head;
}
new_cref = vm_cref_new_use_prev(CREF_CLASS(cref), METHOD_VISI_UNDEF, FALSE, cref, FALSE);
cref = CREF_NEXT(cref);
*new_cref_ptr = new_cref;
new_cref_ptr = &new_cref->next;
ADD_NEW_CREF(new_cref);
}
*new_cref_ptr = NULL;
#undef ADD_NEW_CREF
// Could we just reuse the original cref?
return new_cref_head;
}
static rb_cref_t *