diff options
author | 卜部昌平 <shyouhei@ruby-lang.org> | 2019-09-24 15:41:52 +0900 |
---|---|---|
committer | 卜部昌平 <shyouhei@ruby-lang.org> | 2019-09-30 10:26:38 +0900 |
commit | 3207979278bea11c50cb84f4044047b9c503230b (patch) | |
tree | 3aacc896e9801b42f0aa79931c78f335004eee89 /vm_insnhelper.c | |
parent | 595b3c4fddc5cde58add2fa2637acb2664694194 (diff) |
refactor delete rb_method_definition_set
Instead of destructively write fields of method entries, create a
new entry and let it overwrite its owner.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/2486
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r-- | vm_insnhelper.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 0919f6ebe9..0a43f949af 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -20,7 +20,7 @@ #include "debug_counter.h" extern const rb_method_definition_t *rb_method_definition_create(rb_method_type_t type, ID mid, const void *opts); -extern void rb_method_definition_set(const rb_method_entry_t *me, const rb_method_definition_t *def); +extern void rb_method_entry_spoof(const rb_method_entry_t *me); extern int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2); extern VALUE rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj, int argc, const VALUE *argv, int priv); @@ -2574,32 +2574,39 @@ find_defined_class_by_owner(VALUE current_class, VALUE target_owner) return current_class; /* maybe module function */ } -static const rb_callable_method_entry_t * -aliased_callable_method_entry(const rb_callable_method_entry_t *me) +static const void* +aliased_callable_method_entry0(const rb_method_entry_t *me) { const rb_method_entry_t *orig_me = me->def->body.alias.original_me; const rb_callable_method_entry_t *cme; - if (orig_me->defined_class == 0) { + if (orig_me->defined_class != 0) { + VM_ASSERT(callable_method_entry_p(orig_me)); + return orig_me; + } + else { VALUE defined_class = find_defined_class_by_owner(me->defined_class, orig_me->owner); VM_ASSERT(RB_TYPE_P(orig_me->owner, T_MODULE)); cme = rb_method_entry_complement_defined_class(orig_me, me->called_id, defined_class); - - if (me->def->alias_count + me->def->complemented_count == 0) { - RB_OBJ_WRITE(me, &me->def->body.alias.original_me, cme); - } - else { - const rb_method_definition_t *def = - rb_method_definition_create(VM_METHOD_TYPE_ALIAS, me->def->original_id, cme); - rb_method_definition_set((rb_method_entry_t *)me, def); - } - } - else { - cme = (const rb_callable_method_entry_t *)orig_me; - } - - VM_ASSERT(callable_method_entry_p(cme)); - return cme; + rb_method_entry_t *ret = + rb_method_entry_create( + me->called_id, + me->owner, + me->defined_class, + rb_method_definition_create( + VM_METHOD_TYPE_ALIAS, + me->def->original_id, + cme)); + METHOD_ENTRY_FLAGS_COPY(ret, (const void*)me); + rb_method_entry_spoof(ret); + return ret; + } +} + +static const rb_callable_method_entry_t* +aliased_callable_method_entry(const rb_callable_method_entry_t *me) +{ + return aliased_callable_method_entry0((const void*)me); } static const rb_callable_method_entry_t * |