From 6c6a25feca8752205d81c5247f85d8ae8fb880d8 Mon Sep 17 00:00:00 2001 From: 卜部昌平 Date: Wed, 25 Sep 2019 17:00:25 +0900 Subject: refactor add rb_method_entry_from_template Tired of rb_method_entry_create(..., rb_method_definition_create( ..., &(rb_method_foo_t) {...})) maneuver. Provide a function that does the thing to reduce copy&paste. --- class.c | 17 ++++------- method.h | 5 ++-- proc.c | 9 +----- vm_insnhelper.c | 12 ++------ vm_method.c | 92 ++++++++++++++++++++++++++++++++++++--------------------- 5 files changed, 68 insertions(+), 67 deletions(-) diff --git a/class.c b/class.c index 308033d2cb..3160444239 100644 --- a/class.c +++ b/class.c @@ -967,18 +967,11 @@ inject_refined_method(ID *key, VALUE *value, void *data, int _) const tuple *ptr = data; const rb_method_entry_t *me = *(rb_method_entry_t **) value; const rb_method_entry_t *orig_me = me->def->body.refined.orig_me; - rb_method_entry_t *new_me = - rb_method_entry_create( - me->called_id, - me->owner, - me->defined_class, - rb_method_definition_create( - me->def->type, - me->def->original_id, - &(rb_method_refined_t) { - .orig_me = NULL, - .owner = me->def->body.refined.owner, })); - METHOD_ENTRY_FLAGS_COPY(new_me, me); + const rb_method_entry_t *new_me = + rb_method_entry_from_template( + me, &(rb_method_refined_t) { + .orig_me = NULL, + .owner = me->def->body.refined.owner, }); rb_id_table_insert(RCLASS_M_TBL(ptr->klass), *key, (VALUE)new_me); RB_OBJ_WRITTEN(ptr->klass, Qundef, new_me); *value = (VALUE)rb_method_entry_clone(orig_me); diff --git a/method.h b/method.h index b46336b51e..105e4b6a40 100644 --- a/method.h +++ b/method.h @@ -185,15 +185,14 @@ STATIC_ASSERT(sizeof_method_def, offsetof(rb_method_definition_t, body)==8); ((def)->type == VM_METHOD_TYPE_REFINED && \ UNDEFINED_METHOD_ENTRY_P((def)->body.refined.orig_me)) -const rb_method_definition_t *rb_method_definition_create(rb_method_type_t which, ID what, const void *how); - void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_visibility_t visi); void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi); void rb_add_refined_method_entry(VALUE refined_class, ID mid); void rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi); rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_visibility_t noex); -rb_method_entry_t *rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def); +const rb_method_entry_t *rb_method_entry_from_template(const rb_method_entry_t *template, const void *opts); +const rb_method_entry_t *rb_method_entry_for_missing(ID mid, VALUE klass); const rb_method_entry_t *rb_method_entry_at(VALUE obj, ID id); diff --git a/proc.c b/proc.c index 67e29643bb..09b310356c 100644 --- a/proc.c +++ b/proc.c @@ -1474,16 +1474,9 @@ mnew_missing(VALUE klass, VALUE obj, ID id, VALUE mclass) { struct METHOD *data; VALUE method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data); - rb_method_entry_t *me; - const rb_method_definition_t *def; - RB_OBJ_WRITE(method, &data->recv, obj); RB_OBJ_WRITE(method, &data->klass, klass); - - def = rb_method_definition_create(VM_METHOD_TYPE_MISSING, id, NULL); - me = rb_method_entry_create(id, klass, METHOD_VISI_UNDEF, def); - - RB_OBJ_WRITE(method, &data->me, me); + RB_OBJ_WRITE(method, &data->me, rb_method_entry_for_missing(id, klass)); OBJ_INFECT(method, klass); diff --git a/vm_insnhelper.c b/vm_insnhelper.c index f144d1157c..adad1df6dd 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2587,16 +2587,8 @@ aliased_callable_method_entry0(const rb_method_entry_t *me) 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); - 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); + const rb_method_entry_t *ret = + rb_method_entry_from_template((const rb_method_entry_t*)me, cme); rb_method_entry_spoof(ret); return ret; } diff --git a/vm_method.c b/vm_method.c index 3249cb7720..ce703f3d34 100644 --- a/vm_method.c +++ b/vm_method.c @@ -452,7 +452,7 @@ rb_method_entry_spoof(const rb_method_entry_t *me) rb_clear_method_cache_by_class(o); } -MJIT_FUNC_EXPORTED const rb_method_definition_t * +static const rb_method_definition_t * rb_method_definition_create(rb_method_type_t type, ID mid, const void *opts) { rb_method_definition_t template = rb_method_definition_new(type, mid, opts); @@ -483,6 +483,9 @@ rb_method_entry_alloc(VALUE flags, ID called_id, VALUE owner, VALUE defined_clas rb_method_entry_t tmp = { flags, }; rb_method_entry_t *me = (rb_method_entry_t *)rb_imemo_new(imemo_ment, (VALUE)def, (VALUE)called_id, owner, defined_class); METHOD_ENTRY_FLAGS_COPY(me, &tmp); + if (def) { + method_definition_reset(me); + } return me; } @@ -500,20 +503,42 @@ filter_defined_class(VALUE klass) rb_bug("filter_defined_class: %s", rb_obj_info(klass)); } -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) +static inline VALUE +method_entry_flags(rb_method_visibility_t visi) { rb_method_entry_t tmp = { 0, }; METHOD_ENTRY_FLAGS_SET(&tmp, visi, !ruby_running); - rb_method_entry_t *me = - rb_method_entry_alloc( - tmp.flags, - called_id, - klass, - filter_defined_class(klass), - def); - if (def != NULL) method_definition_reset(me); - return me; + return tmp.flags; +} + +MJIT_FUNC_EXPORTED const rb_method_entry_t * +rb_method_entry_from_template( + const rb_method_entry_t *me, + const void *body) +{ + return rb_method_entry_alloc( + me->flags, + me->called_id, + me->owner, + me->defined_class, + rb_method_definition_create( + me->def->type, + me->def->original_id, + body)); +} + +const rb_method_entry_t * +rb_method_entry_for_missing(ID mid, VALUE klass) +{ + return rb_method_entry_alloc( + method_entry_flags(METHOD_VISI_UNDEF), + mid, + klass, + filter_defined_class(klass), + rb_method_definition_create( + VM_METHOD_TYPE_MISSING, + mid, + NULL)); } const rb_method_entry_t * @@ -569,32 +594,26 @@ make_method_entry_refined(VALUE owner, rb_method_entry_t *me) } else { rb_vm_check_redefinition_opt_method(me, me->owner); - rb_method_entry_t *orig_me = - rb_method_entry_alloc( - me->flags, - me->called_id, - me->owner, - me->defined_class ? - me->defined_class : owner, - method_definition_addref(me->def)); - const rb_method_definition_t *def = + /* :FIXME: can rb_method_entry_from_template be tweaked to also be + * applicable here? */ + return rb_method_entry_alloc( + method_entry_flags(METHOD_VISI_PUBLIC), + me->called_id, + me->owner, + me->defined_class, rb_method_definition_create( VM_METHOD_TYPE_REFINED, me->called_id, &(rb_method_refined_t) { - .orig_me = orig_me, .owner = owner, - } - ); - rb_method_entry_t *new_me = - rb_method_entry_alloc( - me->flags, - me->called_id, - me->owner, - me->defined_class, - def); - METHOD_ENTRY_VISI_SET(new_me, METHOD_VISI_PUBLIC); - return new_me; + .orig_me = + rb_method_entry_alloc( + me->flags, + me->called_id, + me->owner, + me->defined_class ? + me->defined_class : owner, + method_definition_addref(me->def))})); } } @@ -718,7 +737,12 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil if (!def) { def = rb_method_definition_create(type, original_id, opts); } - me = rb_method_entry_create(mid, defined_class, visi, def); + me = rb_method_entry_alloc( + method_entry_flags(visi), + mid, + defined_class, + filter_defined_class(defined_class), + def); rb_clear_method_cache_by_class(klass); -- cgit v1.2.3