* method.h: introduce rb_method_refined_t for refined method entry.

* class.c (move_refined_method): catch up this fix.
* gc.c (mark_method_entry): ditto.
* vm_eval.c (vm_call0_body): ditto.
* vm_insnhelper.c (vm_call_method): ditto.
* vm_method.c: ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50761 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2015-06-03 22:27:51 +00:00
Родитель 9375ff5b06
Коммит 9e73d45e0f
7 изменённых файлов: 39 добавлений и 20 удалений

Просмотреть файл

@ -1,3 +1,17 @@
Thu Jun 4 07:22:45 2015 Koichi Sasada <ko1@atdot.net>
* method.h: introduce rb_method_refined_t for refined method entry.
* class.c (move_refined_method): catch up this fix.
* gc.c (mark_method_entry): ditto.
* vm_eval.c (vm_call0_body): ditto.
* vm_insnhelper.c (vm_call_method): ditto.
* vm_method.c: ditto.
Thu Jun 4 07:12:20 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* dir.c (dirent_match): match short names only when FNM_SHORTNAME

Просмотреть файл

@ -913,9 +913,9 @@ move_refined_method(st_data_t key, st_data_t value, st_data_t data)
st_table *tbl = (st_table *) data;
if (me->def->type == VM_METHOD_TYPE_REFINED) {
if (me->def->body.orig_me) {
rb_method_entry_t *orig_me = me->def->body.orig_me, *new_me;
me->def->body.orig_me = NULL;
if (me->def->body.refined.orig_me) {
rb_method_entry_t *orig_me = me->def->body.refined.orig_me, *new_me;
me->def->body.refined.orig_me = NULL;
new_me = rb_method_entry_clone(me);
st_add_direct(tbl, key, (st_data_t) new_me);
rb_method_entry_copy(me, orig_me);

2
gc.c
Просмотреть файл

@ -3946,7 +3946,7 @@ mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me)
gc_mark(objspace, (VALUE)def->body.alias.original_me);
return;
case VM_METHOD_TYPE_REFINED:
gc_mark(objspace, (VALUE)def->body.orig_me);
gc_mark(objspace, (VALUE)def->body.refined.orig_me);
break;
case VM_METHOD_TYPE_CFUNC:
case VM_METHOD_TYPE_ZSUPER:

Просмотреть файл

@ -77,6 +77,10 @@ typedef struct rb_method_alias_struct {
const struct rb_method_entry_struct *original_me; /* original_me->klass is original owner */
} rb_method_alias_t;
typedef struct rb_method_refined_struct {
struct rb_method_entry_struct *orig_me;
} rb_method_refined_t;
typedef struct rb_method_definition_struct {
struct {
rb_method_visibility_t visi: 3;
@ -90,6 +94,8 @@ typedef struct rb_method_definition_struct {
rb_method_cfunc_t cfunc;
rb_method_attr_t attr;
rb_method_alias_t alias;
rb_method_refined_t refined;
const VALUE proc; /* should be marked */
enum method_optimized_type {
OPTIMIZED_METHOD_TYPE_SEND,
@ -97,7 +103,6 @@ typedef struct rb_method_definition_struct {
OPTIMIZED_METHOD_TYPE__MAX
} optimize_type;
struct rb_method_entry_struct *orig_me;
} body;
int *alias_count_ptr;
@ -107,7 +112,7 @@ typedef struct rb_method_definition_struct {
#define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF)
#define UNDEFINED_REFINED_METHOD_P(def) \
((def)->type == VM_METHOD_TYPE_REFINED && \
UNDEFINED_METHOD_ENTRY_P((def)->body.orig_me))
UNDEFINED_METHOD_ENTRY_P((def)->body.refined.orig_me))
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, VALUE iseqval, rb_cref_t *cref, rb_method_visibility_t visi);

Просмотреть файл

@ -198,8 +198,8 @@ vm_call0_body(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv)
case VM_METHOD_TYPE_REFINED:
{
const rb_method_type_t type = ci->me->def->type;
if (type == VM_METHOD_TYPE_REFINED && ci->me->def->body.orig_me) {
ci->me = ci->me->def->body.orig_me;
if (type == VM_METHOD_TYPE_REFINED && ci->me->def->body.refined.orig_me) {
ci->me = ci->me->def->body.refined.orig_me;
goto again;
}

Просмотреть файл

@ -2019,8 +2019,8 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
}
no_refinement_dispatch:
if (ci->me->def->body.orig_me) {
ci->me = ci->me->def->body.orig_me;
if (ci->me->def->body.refined.orig_me) {
ci->me = ci->me->def->body.refined.orig_me;
if (UNDEFINED_METHOD_ENTRY_P(ci->me)) {
ci->me = 0;
}

Просмотреть файл

@ -278,7 +278,7 @@ rb_method_definition_set(rb_method_definition_t *def, void *opts)
def->body.optimize_type = (enum method_optimized_type)opts;
return;
case VM_METHOD_TYPE_REFINED:
DEF_OBJ_WRITE(&def->body.orig_me, (rb_method_entry_t *)opts);
DEF_OBJ_WRITE(&def->body.refined.orig_me, (rb_method_entry_t *)opts);
return;
case VM_METHOD_TYPE_ALIAS:
DEF_OBJ_WRITE(&def->body.alias.original_me, (rb_method_entry_t *)opts);
@ -321,7 +321,7 @@ rb_method_definition_reset(rb_method_entry_t *me, rb_method_definition_t *def)
RB_OBJ_WRITTEN(me, Qundef, def->body.proc);
break;
case VM_METHOD_TYPE_REFINED:
RB_OBJ_WRITTEN(me, Qundef, def->body.orig_me);
RB_OBJ_WRITTEN(me, Qundef, def->body.refined.orig_me);
break;
case VM_METHOD_TYPE_ALIAS:
RB_OBJ_WRITTEN(me, Qundef, def->body.alias.original_me);
@ -548,8 +548,8 @@ rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_
rb_method_definition_t *def = rb_method_definition_create(visi, type, mid, opts);
rb_method_entry_t *me = rb_method_entry_make(klass, mid, type, def, visi, klass);
if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.orig_me) { /* TODO: really needed? */
rb_method_definition_reset(me->def->body.orig_me, def);
if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) { /* TODO: really needed? */
rb_method_definition_reset(me->def->body.refined.orig_me, def);
}
if (type != VM_METHOD_TYPE_UNDEF && type != VM_METHOD_TYPE_REFINED) {
@ -716,8 +716,8 @@ get_original_method_entry(VALUE refinements,
{
VALUE super;
if (me->def->body.orig_me) {
return me->def->body.orig_me;
if (me->def->body.refined.orig_me) {
return me->def->body.refined.orig_me;
}
else if (!(super = RCLASS_SUPER(me->klass))) {
return 0;
@ -893,8 +893,8 @@ rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi)
if (klass == defined_class || RCLASS_ORIGIN(klass) == defined_class) {
me->def->flags.visi = visi;
if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.orig_me) {
me->def->body.orig_me->def->flags.visi = visi;
if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) {
me->def->body.refined.orig_me->def->flags.visi = visi;
}
rb_clear_method_cache_by_class(klass);
}
@ -1274,8 +1274,8 @@ original_method_definition(const rb_method_definition_t *def)
if (def) {
switch (def->type) {
case VM_METHOD_TYPE_REFINED:
if (def->body.orig_me) {
def = def->body.orig_me->def;
if (def->body.refined.orig_me) {
def = def->body.refined.orig_me->def;
goto again;
}
break;