зеркало из https://github.com/github/ruby.git
* 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:
Родитель
9375ff5b06
Коммит
9e73d45e0f
14
ChangeLog
14
ChangeLog
|
@ -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
|
||||
|
|
6
class.c
6
class.c
|
@ -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
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:
|
||||
|
|
9
method.h
9
method.h
|
@ -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;
|
||||
}
|
||||
|
|
20
vm_method.c
20
vm_method.c
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче