From 14cf8d09ca7f4c7514bc50f6f7ee6faddb9f89cb Mon Sep 17 00:00:00 2001 From: nobu Date: Tue, 2 Sep 2008 02:47:38 +0000 Subject: * marshal.c (struct load_arg): data is now st_table. * marshal.c (mark_load_arg): marks data and compat_tbl. * marshal.c (r_object0): no need to check if reentered. * marshal.c (marshal_load): make the wrapper with mark_load_arg. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19056 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 10 ++++++++++ marshal.c | 44 +++++++++++++++++++++++++++----------------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2a8925e657..8fea8ab240 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Tue Sep 2 11:47:36 2008 Nobuyoshi Nakada + + * marshal.c (struct load_arg): data is now st_table. + + * marshal.c (mark_load_arg): marks data and compat_tbl. + + * marshal.c (r_object0): no need to check if reentered. + + * marshal.c (marshal_load): make the wrapper with mark_load_arg. + Tue Sep 2 10:49:18 2008 NAKAMURA Usaku * win32/win32.c (gettimeofday): easier calculation. use the definition diff --git a/marshal.c b/marshal.c index 0909addc83..97d4fa1679 100644 --- a/marshal.c +++ b/marshal.c @@ -904,22 +904,32 @@ struct load_arg { VALUE src; long offset; st_table *symbols; - VALUE data; + st_table *data; VALUE proc; int taint; int untrust; st_table *compat_tbl; - VALUE compat_tbl_wrapper; + VALUE wrapper; }; static void check_load_arg(struct load_arg *arg) { - if (!DATA_PTR(arg->compat_tbl_wrapper)) { + if (!DATA_PTR(arg->wrapper)) { rb_raise(rb_eRuntimeError, "Marshal.load reentered"); } } +static void +mark_load_arg(void *ptr) +{ + struct load_arg *p = ptr; + if (!ptr) + return; + rb_mark_tbl(p->data); + rb_mark_hash(p->compat_tbl); +} + static VALUE r_entry(VALUE v, struct load_arg *arg); static VALUE r_object(struct load_arg *arg); static VALUE path2class(const char *path); @@ -1083,10 +1093,10 @@ r_entry(VALUE v, struct load_arg *arg) { st_data_t real_obj = (VALUE)Qundef; if (st_lookup(arg->compat_tbl, v, &real_obj)) { - rb_hash_aset(arg->data, INT2FIX(RHASH_SIZE(arg->data)), (VALUE)real_obj); + st_insert(arg->data, arg->data->num_entries, (st_data_t)real_obj); } else { - rb_hash_aset(arg->data, INT2FIX(RHASH_SIZE(arg->data)), v); + st_insert(arg->data, arg->data->num_entries, (st_data_t)v); } if (arg->taint) { OBJ_TAINT(v); @@ -1193,15 +1203,15 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) VALUE v = Qnil; int type = r_byte(arg); long id; + st_data_t link; switch (type) { case TYPE_LINK: id = r_long(arg); - v = rb_hash_aref(arg->data, LONG2FIX(id)); - check_load_arg(arg); - if (NIL_P(v)) { + if (!st_lookup(arg->data, (st_data_t)id, &link)) { rb_raise(rb_eArgError, "dump format error (unlinked)"); } + v = (VALUE)link; if (arg->proc) { v = rb_funcall(arg->proc, rb_intern("call"), 1, v); check_load_arg(arg); @@ -1581,11 +1591,12 @@ load(struct load_arg *arg) static VALUE load_ensure(struct load_arg *arg) { - if (!DATA_PTR(arg->compat_tbl_wrapper)) return 0; + if (!DATA_PTR(arg->wrapper)) return 0; st_free_table(arg->symbols); + st_free_table(arg->data); st_free_table(arg->compat_tbl); - DATA_PTR(arg->compat_tbl_wrapper) = 0; - arg->compat_tbl_wrapper = 0; + DATA_PTR(arg->wrapper) = 0; + arg->wrapper = 0; return 0; } @@ -1626,8 +1637,11 @@ marshal_load(int argc, VALUE *argv) arg.untrust = OBJ_UNTRUSTED(port); arg.src = port; arg.offset = 0; + arg.symbols = st_init_numtable(); + arg.data = st_init_numtable(); arg.compat_tbl = st_init_numtable(); - arg.compat_tbl_wrapper = Data_Wrap_Struct(rb_cData, rb_mark_tbl, 0, arg.compat_tbl); + arg.proc = 0; + arg.wrapper = Data_Wrap_Struct(rb_cData, mark_load_arg, 0, &arg); major = r_byte(&arg); minor = r_byte(&arg); @@ -1642,11 +1656,7 @@ marshal_load(int argc, VALUE *argv) MARSHAL_MAJOR, MARSHAL_MINOR, major, minor); } - arg.symbols = st_init_numtable(); - arg.data = rb_hash_new(); - RBASIC(arg.data)->klass = 0; - if (NIL_P(proc)) arg.proc = 0; - else arg.proc = proc; + if (!NIL_P(proc)) arg.proc = proc; v = rb_ensure(load, (VALUE)&arg, load_ensure, (VALUE)&arg); return v; -- cgit v1.2.3