aboutsummaryrefslogtreecommitdiffstats
path: root/vm_method.c
diff options
context:
space:
mode:
author卜部昌平 <shyouhei@ruby-lang.org>2019-09-24 15:41:52 +0900
committer卜部昌平 <shyouhei@ruby-lang.org>2019-09-30 10:26:38 +0900
commit3207979278bea11c50cb84f4044047b9c503230b (patch)
tree3aacc896e9801b42f0aa79931c78f335004eee89 /vm_method.c
parent595b3c4fddc5cde58add2fa2637acb2664694194 (diff)
downloadruby-3207979278bea11c50cb84f4044047b9c503230b.tar.gz
refactor delete rb_method_definition_set
Instead of destructively write fields of method entries, create a new entry and let it overwrite its owner.
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/vm_method.c b/vm_method.c
index bde8c1bd26..7bb675ebcc 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -443,10 +443,13 @@ rb_method_definition_new(rb_method_type_t type, ID mid, const void *opts)
}
MJIT_FUNC_EXPORTED void
-rb_method_definition_set(const rb_method_entry_t *me, const rb_method_definition_t *def)
+rb_method_entry_spoof(const rb_method_entry_t *me)
{
- memcpy((void *)&me->def, &def, sizeof def);
- method_definition_reset(me);
+ VALUE v = (VALUE)me;
+ VALUE o = me->owner;
+ rb_id_table_insert(RCLASS_M_TBL(o), me->called_id, v);
+ RB_OBJ_WRITTEN(o, Qundef, v);
+ rb_clear_method_cache_by_class(o);
}
MJIT_FUNC_EXPORTED const rb_method_definition_t *
@@ -495,7 +498,7 @@ filter_defined_class(VALUE klass)
rb_bug("filter_defined_class: %s", rb_obj_info(klass));
}
-rb_method_entry_t *
+MJIT_FUNC_EXPORTED rb_method_entry_t *
rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def)
{
rb_method_entry_t *me = rb_method_entry_alloc(called_id, klass, filter_defined_class(klass), def);
@@ -554,11 +557,11 @@ rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src)
METHOD_ENTRY_FLAGS_COPY(dst, src);
}
-static void
+static rb_method_entry_t*
make_method_entry_refined(VALUE owner, rb_method_entry_t *me)
{
if (me->def->type == VM_METHOD_TYPE_REFINED) {
- return;
+ return me;
}
else {
rb_vm_check_redefinition_opt_method(me, me->owner);
@@ -577,8 +580,15 @@ make_method_entry_refined(VALUE owner, rb_method_entry_t *me)
.owner = owner,
}
);
- rb_method_definition_set(me, def);
- METHOD_ENTRY_VISI_SET(me, METHOD_VISI_PUBLIC);
+ rb_method_entry_t *new_me =
+ rb_method_entry_create(
+ me->called_id,
+ me->owner,
+ me->defined_class,
+ def);
+ METHOD_ENTRY_FLAGS_COPY(new_me, me);
+ METHOD_ENTRY_VISI_SET(new_me, METHOD_VISI_PUBLIC);
+ return new_me;
}
}
@@ -588,7 +598,8 @@ rb_add_refined_method_entry(VALUE refined_class, ID mid)
rb_method_entry_t *me = lookup_method_table(refined_class, mid);
if (me) {
- make_method_entry_refined(refined_class, me);
+ me = make_method_entry_refined(refined_class, me);
+ rb_method_entry_spoof(me);
rb_clear_method_cache_by_class(refined_class);
}
else {
@@ -723,7 +734,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil
}
if (make_refined) {
- make_method_entry_refined(klass, me);
+ me = make_method_entry_refined(klass, me);
}
rb_id_table_insert(mtbl, mid, (VALUE)me);