aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author卜部昌平 <shyouhei@ruby-lang.org>2019-09-25 17:00:25 +0900
committer卜部昌平 <shyouhei@ruby-lang.org>2019-09-30 10:26:38 +0900
commit6c6a25feca8752205d81c5247f85d8ae8fb880d8 (patch)
tree449e41fc35b50b0d498f646303c49935d05b457b
parent167e6b48f1b321d671998728adf5a0db06d24445 (diff)
downloadruby-6c6a25feca8752205d81c5247f85d8ae8fb880d8.tar.gz
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.
-rw-r--r--class.c17
-rw-r--r--method.h5
-rw-r--r--proc.c9
-rw-r--r--vm_insnhelper.c12
-rw-r--r--vm_method.c92
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);