summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-09-02 02:47:38 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-09-02 02:47:38 +0000
commit14cf8d09ca7f4c7514bc50f6f7ee6faddb9f89cb (patch)
tree2df828b346944740835dd1146602ec32d17e9680
parent3977007d18fcaf8471ad01c8b2c71e82b1c41814 (diff)
* 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
-rw-r--r--ChangeLog10
-rw-r--r--marshal.c44
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 <nobu@ruby-lang.org>
+
+ * 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 <usa@ruby-lang.org>
* 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;