From 433999fd5c82a8925baf312155351252320a44ce Mon Sep 17 00:00:00 2001 From: nobu Date: Sun, 20 Jan 2013 14:55:42 +0000 Subject: [PATCH] marshal.c: get back to the old behavior * marshal.c (w_object, r_object0): separate respond_to checks and calling, and get back to the old behavior for 2.0. [Bug #7564] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38888 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 ++++ marshal.c | 90 ++++++++++++++----------------------------------------- 2 files changed, 28 insertions(+), 67 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9ae42f3c64..beec695847 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sun Jan 20 23:55:37 2013 Nobuyoshi Nakada + + * marshal.c (w_object, r_object0): separate respond_to checks and + calling, and get back to the old behavior for 2.0. [Bug #7564] + Sun Jan 20 22:24:28 2013 Nobuyoshi Nakada * tool/vpath.rb (VPath#def_options): hack for msys make, which diff --git a/marshal.c b/marshal.c index c9bdfd3346..786a28bb8e 100644 --- a/marshal.c +++ b/marshal.c @@ -586,15 +586,6 @@ w_objivar(VALUE obj, struct dump_call_arg *arg) } } -static void -push_dump_object(int found, VALUE recv, ID mid, int argc, VALUE *argv, VALUE data) -{ - if (found) { - struct dump_arg *arg = (struct dump_arg *)data; - st_add_direct(arg->data, recv, arg->data->num_entries); - } -} - static void w_object(VALUE obj, struct dump_arg *arg, int limit) { @@ -655,8 +646,10 @@ w_object(VALUE obj, struct dump_arg *arg, int limit) arg->infection |= (int)FL_TEST(obj, MARSHAL_INFECTION); - v = rb_check_funcall_with_hook(obj, s_mdump, 0, 0, push_dump_object, (VALUE)arg); - if (v != Qundef) { + if (rb_obj_respond_to(obj, s_mdump, TRUE)) { + st_add_direct(arg->data, obj, arg->data->num_entries); + + v = rb_funcall2(obj, s_mdump, 0, 0); check_dump_arg(arg, s_mdump); hasiv = has_ivars(obj, ivtbl); if (hasiv) w_byte(TYPE_IVAR, arg); @@ -665,12 +658,12 @@ w_object(VALUE obj, struct dump_arg *arg, int limit) if (hasiv) w_ivar(obj, ivtbl, &c_arg); return; } - v = INT2NUM(limit); - v = rb_check_funcall(obj, s_dump, 1, &v); - if (v != Qundef) { + if (rb_obj_respond_to(obj, s_dump, TRUE)) { st_table *ivtbl2 = 0; int hasiv2; + v = INT2NUM(limit); + v = rb_funcall2(obj, s_dump, 1, &v); check_dump_arg(arg, s_dump); if (!RB_TYPE_P(v, T_STRING)) { rb_raise(rb_eTypeError, "_dump() must return string"); @@ -840,12 +833,12 @@ w_object(VALUE obj, struct dump_arg *arg, int limit) { VALUE v; - v = rb_check_funcall(obj, s_dump_data, 0, 0); - if (v == Qundef) { + if (!rb_obj_respond_to(obj, s_dump_data, TRUE)) { rb_raise(rb_eTypeError, "no _dump_data is defined for class %s", rb_obj_classname(obj)); } + v = rb_funcall2(obj, s_dump_data, 0, 0); check_dump_arg(arg, s_dump_data); w_class(TYPE_DATA, obj, arg, TRUE); w_object(v, arg, limit); @@ -1033,7 +1026,6 @@ static VALUE r_entry0(VALUE v, st_index_t num, struct load_arg *arg); static VALUE r_object(struct load_arg *arg); static ID r_symbol(struct load_arg *arg); static VALUE path2class(VALUE path); -static VALUE r_object0(struct load_arg *arg, int *ivp, VALUE extmod); NORETURN(static void too_short(void)); static void @@ -1442,42 +1434,6 @@ append_extmod(VALUE obj, VALUE extmod) return obj; } -static void -load_data_hook(int found, VALUE recv, ID mid, int argc, VALUE *argv, VALUE data) -{ - if (found) { - struct load_arg *arg = (struct load_arg *)((VALUE *)data)[0]; - VALUE extmod = ((VALUE *)data)[1]; - *argv = r_object0(arg, 0, extmod); - } -} - -static void -load_userdef_hook(int found, VALUE recv, ID mid, int argc, VALUE *argv, VALUE data) -{ - if (found) { - struct load_arg *arg = (struct load_arg *)((VALUE *)data)[0]; - int *ivp = (int *)((VALUE *)data)[1]; - VALUE r = r_string(arg); - if (ivp) { - r_ivar(r, NULL, arg); - *ivp = FALSE; - } - *argv = r; - } -} - -static void -mload_hook(int found, VALUE recv, ID mid, int argc, VALUE *argv, VALUE data) -{ - if (found) { - struct load_arg *arg = (struct load_arg *)((VALUE *)data)[0]; - VALUE v = ((VALUE *)data)[1]; - r_entry(v, arg); - *argv = r_object(arg); - } -} - static VALUE r_object0(struct load_arg *arg, int *ivp, VALUE extmod) { @@ -1485,7 +1441,6 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) int type = r_byte(arg); long id; st_data_t link; - VALUE args[2]; switch (type) { case TYPE_LINK: @@ -1763,14 +1718,16 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) VALUE klass = path2class(r_unique(arg)); VALUE data; - args[0] = (VALUE)arg; - args[1] = (VALUE)ivp; - v = rb_check_funcall_with_hook(klass, s_load, 1, &data, - load_userdef_hook, (VALUE)args); - if (v == Qundef) { + if (!rb_obj_respond_to(klass, s_load, TRUE)) { rb_raise(rb_eTypeError, "class %s needs to have method `_load'", rb_class2name(klass)); } + data = r_string(arg); + if (ivp) { + r_ivar(data, NULL, arg); + *ivp = FALSE; + } + v = rb_funcall2(klass, s_load, 1, &data); check_load_arg(arg, s_load); v = r_entry(v, arg); v = r_leave(v, arg); @@ -1788,13 +1745,13 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) /* for the case marshal_load is overridden */ append_extmod(v, extmod); } - args[0] = (VALUE)arg; - args[1] = v; - data = rb_check_funcall_with_hook(v, s_mload, 1, &data, mload_hook, (VALUE)args); - if (data == Qundef) { + if (!rb_obj_respond_to(v, s_mload, TRUE)) { rb_raise(rb_eTypeError, "instance of %s needs to have method `marshal_load'", rb_class2name(klass)); } + v = r_entry(v, arg); + data = r_object(arg); + rb_funcall2(v, s_mload, 1, &data); check_load_arg(arg, s_mload); v = r_leave(v, arg); if (!NIL_P(extmod)) { @@ -1828,14 +1785,13 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) rb_raise(rb_eArgError, "dump format error"); } v = r_entry(v, arg); - args[0] = (VALUE)arg; - args[1] = extmod; - r = rb_check_funcall_with_hook(v, s_load_data, 1, &r, load_data_hook, (VALUE)args); - if (r == Qundef) { + if (!rb_obj_respond_to(v, s_load_data, TRUE)) { rb_raise(rb_eTypeError, "class %s needs to have instance method `_load_data'", rb_class2name(klass)); } + r = r_object0(arg, 0, extmod); + rb_funcall2(v, s_load_data, 1, &r); check_load_arg(arg, s_load_data); v = r_leave(v, arg); }