* marshal.c (struct dump_arg, struct load_arg): added wrappers to mark
compat_tbl entries. [ruby-dev:31870] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13527 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4d1450fc96
commit
71341b814a
@ -1,3 +1,8 @@
|
|||||||
|
Thu Sep 27 04:12:01 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* marshal.c (struct dump_arg, struct load_arg): added wrappers to mark
|
||||||
|
compat_tbl entries. [ruby-dev:31870]
|
||||||
|
|
||||||
Thu Sep 27 03:17:41 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Thu Sep 27 03:17:41 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* process.c (rb_waitpid): no needs to poll. [ruby-dev:31871]
|
* process.c (rb_waitpid): no needs to poll. [ruby-dev:31871]
|
||||||
|
74
marshal.c
74
marshal.c
@ -89,7 +89,26 @@ typedef struct {
|
|||||||
VALUE (*loader)(VALUE, VALUE);
|
VALUE (*loader)(VALUE, VALUE);
|
||||||
} marshal_compat_t;
|
} marshal_compat_t;
|
||||||
|
|
||||||
|
#define make_compat_tbl_wrapper(tbl) Data_Wrap_Struct(rb_cData, rb_mark_tbl, 0, tbl)
|
||||||
|
|
||||||
static st_table *compat_allocator_tbl;
|
static st_table *compat_allocator_tbl;
|
||||||
|
static VALUE compat_allocator_tbl_wrapper;
|
||||||
|
|
||||||
|
static int
|
||||||
|
mark_marshal_compat_i(st_data_t key, st_data_t value)
|
||||||
|
{
|
||||||
|
marshal_compat_t *p = (marshal_compat_t *)value;
|
||||||
|
rb_gc_mark(p->newclass);
|
||||||
|
rb_gc_mark(p->oldclass);
|
||||||
|
return ST_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mark_marshal_compat_t(void *tbl)
|
||||||
|
{
|
||||||
|
if (!tbl) return;
|
||||||
|
st_foreach(tbl, mark_marshal_compat_i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE))
|
rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE))
|
||||||
@ -104,8 +123,6 @@ rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE),
|
|||||||
compat = ALLOC(marshal_compat_t);
|
compat = ALLOC(marshal_compat_t);
|
||||||
compat->newclass = Qnil;
|
compat->newclass = Qnil;
|
||||||
compat->oldclass = Qnil;
|
compat->oldclass = Qnil;
|
||||||
rb_gc_register_address(&compat->newclass);
|
|
||||||
rb_gc_register_address(&compat->oldclass);
|
|
||||||
compat->newclass = newclass;
|
compat->newclass = newclass;
|
||||||
compat->oldclass = oldclass;
|
compat->oldclass = oldclass;
|
||||||
compat->dumper = dumper;
|
compat->dumper = dumper;
|
||||||
@ -121,6 +138,7 @@ struct dump_arg {
|
|||||||
st_table *data;
|
st_table *data;
|
||||||
int taint;
|
int taint;
|
||||||
st_table *compat_tbl;
|
st_table *compat_tbl;
|
||||||
|
VALUE compat_tbl_wrapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dump_call_arg {
|
struct dump_call_arg {
|
||||||
@ -346,6 +364,9 @@ w_symbol(ID id, struct dump_arg *arg)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sym = rb_id2name(id);
|
sym = rb_id2name(id);
|
||||||
|
if (!sym) {
|
||||||
|
rb_raise(rb_eTypeError, "can't dump anonymous ID %ld", id);
|
||||||
|
}
|
||||||
w_byte(TYPE_SYMBOL, arg);
|
w_byte(TYPE_SYMBOL, arg);
|
||||||
w_bytes(sym, strlen(sym), arg);
|
w_bytes(sym, strlen(sym), arg);
|
||||||
st_add_direct(arg->symbols, id, arg->symbols->num_entries);
|
st_add_direct(arg->symbols, id, arg->symbols->num_entries);
|
||||||
@ -396,11 +417,11 @@ w_class(char type, VALUE obj, struct dump_arg *arg, int check)
|
|||||||
{
|
{
|
||||||
volatile VALUE p;
|
volatile VALUE p;
|
||||||
char *path;
|
char *path;
|
||||||
VALUE real_obj;
|
st_data_t real_obj;
|
||||||
VALUE klass;
|
VALUE klass;
|
||||||
|
|
||||||
if (st_lookup(arg->compat_tbl, (st_data_t)obj, (st_data_t*)&real_obj)) {
|
if (st_lookup(arg->compat_tbl, (st_data_t)obj, &real_obj)) {
|
||||||
obj = real_obj;
|
obj = (VALUE)real_obj;
|
||||||
}
|
}
|
||||||
klass = CLASS_OF(obj);
|
klass = CLASS_OF(obj);
|
||||||
w_extended(klass, arg, check);
|
w_extended(klass, arg, check);
|
||||||
@ -464,7 +485,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ivtbl = rb_generic_ivar_table(obj)) {
|
if ((ivtbl = rb_generic_ivar_table(obj)) != 0) {
|
||||||
w_byte(TYPE_IVAR, arg);
|
w_byte(TYPE_IVAR, arg);
|
||||||
}
|
}
|
||||||
if (obj == Qnil) {
|
if (obj == Qnil) {
|
||||||
@ -499,11 +520,12 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
|
|||||||
st_add_direct(arg->data, obj, arg->data->num_entries);
|
st_add_direct(arg->data, obj, arg->data->num_entries);
|
||||||
|
|
||||||
{
|
{
|
||||||
marshal_compat_t *compat;
|
st_data_t compat_data;
|
||||||
rb_alloc_func_t allocator = rb_get_alloc_func(RBASIC(obj)->klass);
|
rb_alloc_func_t allocator = rb_get_alloc_func(RBASIC(obj)->klass);
|
||||||
if (st_lookup(compat_allocator_tbl,
|
if (st_lookup(compat_allocator_tbl,
|
||||||
(st_data_t)allocator,
|
(st_data_t)allocator,
|
||||||
(st_data_t*)(void*)&compat)) {
|
&compat_data)) {
|
||||||
|
marshal_compat_t *compat = (marshal_compat_t*)compat_data;
|
||||||
VALUE real_obj = obj;
|
VALUE real_obj = obj;
|
||||||
obj = compat->dumper(real_obj);
|
obj = compat->dumper(real_obj);
|
||||||
st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
|
st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
|
||||||
@ -699,6 +721,9 @@ dump_ensure(struct dump_arg *arg)
|
|||||||
{
|
{
|
||||||
st_free_table(arg->symbols);
|
st_free_table(arg->symbols);
|
||||||
st_free_table(arg->data);
|
st_free_table(arg->data);
|
||||||
|
st_free_table(arg->compat_tbl);
|
||||||
|
DATA_PTR(arg->compat_tbl_wrapper) = 0;
|
||||||
|
arg->compat_tbl_wrapper = 0;
|
||||||
if (arg->taint) {
|
if (arg->taint) {
|
||||||
OBJ_TAINT(arg->str);
|
OBJ_TAINT(arg->str);
|
||||||
}
|
}
|
||||||
@ -772,6 +797,7 @@ marshal_dump(int argc, VALUE *argv)
|
|||||||
arg.data = st_init_numtable();
|
arg.data = st_init_numtable();
|
||||||
arg.taint = Qfalse;
|
arg.taint = Qfalse;
|
||||||
arg.compat_tbl = st_init_numtable();
|
arg.compat_tbl = st_init_numtable();
|
||||||
|
arg.compat_tbl_wrapper = make_compat_tbl_wrapper(arg.compat_tbl);
|
||||||
c_arg.obj = obj;
|
c_arg.obj = obj;
|
||||||
c_arg.arg = &arg;
|
c_arg.arg = &arg;
|
||||||
c_arg.limit = limit;
|
c_arg.limit = limit;
|
||||||
@ -792,6 +818,7 @@ struct load_arg {
|
|||||||
VALUE proc;
|
VALUE proc;
|
||||||
int taint;
|
int taint;
|
||||||
st_table *compat_tbl;
|
st_table *compat_tbl;
|
||||||
|
VALUE compat_tbl_wrapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
static VALUE r_entry(VALUE v, struct load_arg *arg);
|
static VALUE r_entry(VALUE v, struct load_arg *arg);
|
||||||
@ -952,17 +979,17 @@ r_string(struct load_arg *arg)
|
|||||||
static VALUE
|
static VALUE
|
||||||
r_entry(VALUE v, struct load_arg *arg)
|
r_entry(VALUE v, struct load_arg *arg)
|
||||||
{
|
{
|
||||||
VALUE real_obj = Qundef;
|
st_data_t real_obj = (VALUE)Qundef;
|
||||||
if (st_lookup(arg->compat_tbl, v, (st_data_t*)&real_obj)) {
|
if (st_lookup(arg->compat_tbl, v, &real_obj)) {
|
||||||
rb_hash_aset(arg->data, INT2FIX(RHASH_SIZE(arg->data)), real_obj);
|
rb_hash_aset(arg->data, INT2FIX(RHASH_SIZE(arg->data)), (VALUE)real_obj);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rb_hash_aset(arg->data, INT2FIX(RHASH_SIZE(arg->data)), v);
|
rb_hash_aset(arg->data, INT2FIX(RHASH_SIZE(arg->data)), v);
|
||||||
}
|
}
|
||||||
if (arg->taint) {
|
if (arg->taint) {
|
||||||
OBJ_TAINT(v);
|
OBJ_TAINT(v);
|
||||||
if (real_obj != Qundef)
|
if ((VALUE)real_obj != Qundef)
|
||||||
OBJ_TAINT(real_obj);
|
OBJ_TAINT((VALUE)real_obj);
|
||||||
}
|
}
|
||||||
if (arg->proc) {
|
if (arg->proc) {
|
||||||
v = rb_funcall(arg->proc, rb_intern("call"), 1, v);
|
v = rb_funcall(arg->proc, rb_intern("call"), 1, v);
|
||||||
@ -973,12 +1000,13 @@ r_entry(VALUE v, struct load_arg *arg)
|
|||||||
static VALUE
|
static VALUE
|
||||||
r_leave(VALUE v, struct load_arg *arg)
|
r_leave(VALUE v, struct load_arg *arg)
|
||||||
{
|
{
|
||||||
VALUE real_obj;
|
st_data_t data;
|
||||||
marshal_compat_t *compat;
|
if (st_lookup(arg->compat_tbl, v, &data)) {
|
||||||
if (st_lookup(arg->compat_tbl, v, &real_obj)) {
|
VALUE real_obj = (VALUE)data;
|
||||||
rb_alloc_func_t allocator = rb_get_alloc_func(CLASS_OF(real_obj));
|
rb_alloc_func_t allocator = rb_get_alloc_func(CLASS_OF(real_obj));
|
||||||
st_data_t key = v;
|
st_data_t key = v;
|
||||||
if (st_lookup(compat_allocator_tbl, (st_data_t)allocator, (st_data_t*)(void*)&compat)) {
|
if (st_lookup(compat_allocator_tbl, (st_data_t)allocator, &data)) {
|
||||||
|
marshal_compat_t *compat = (marshal_compat_t*)data;
|
||||||
compat->loader(real_obj, v);
|
compat->loader(real_obj, v);
|
||||||
}
|
}
|
||||||
st_delete(arg->compat_tbl, &key, 0);
|
st_delete(arg->compat_tbl, &key, 0);
|
||||||
@ -1028,13 +1056,14 @@ static VALUE
|
|||||||
obj_alloc_by_path(const char *path, struct load_arg *arg)
|
obj_alloc_by_path(const char *path, struct load_arg *arg)
|
||||||
{
|
{
|
||||||
VALUE klass;
|
VALUE klass;
|
||||||
marshal_compat_t *compat;
|
st_data_t data;
|
||||||
rb_alloc_func_t allocator;
|
rb_alloc_func_t allocator;
|
||||||
|
|
||||||
klass = path2class(path);
|
klass = path2class(path);
|
||||||
|
|
||||||
allocator = rb_get_alloc_func(klass);
|
allocator = rb_get_alloc_func(klass);
|
||||||
if (st_lookup(compat_allocator_tbl, (st_data_t)allocator, (st_data_t*)(void*)&compat)) {
|
if (st_lookup(compat_allocator_tbl, (st_data_t)allocator, &data)) {
|
||||||
|
marshal_compat_t *compat = (marshal_compat_t*)data;
|
||||||
VALUE real_obj = rb_obj_alloc(klass);
|
VALUE real_obj = rb_obj_alloc(klass);
|
||||||
VALUE obj = rb_obj_alloc(compat->oldclass);
|
VALUE obj = rb_obj_alloc(compat->oldclass);
|
||||||
st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
|
st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
|
||||||
@ -1428,6 +1457,9 @@ static VALUE
|
|||||||
load_ensure(struct load_arg *arg)
|
load_ensure(struct load_arg *arg)
|
||||||
{
|
{
|
||||||
st_free_table(arg->symbols);
|
st_free_table(arg->symbols);
|
||||||
|
st_free_table(arg->compat_tbl);
|
||||||
|
DATA_PTR(arg->compat_tbl_wrapper) = 0;
|
||||||
|
arg->compat_tbl_wrapper = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1467,6 +1499,7 @@ marshal_load(int argc, VALUE *argv)
|
|||||||
arg.src = port;
|
arg.src = port;
|
||||||
arg.offset = 0;
|
arg.offset = 0;
|
||||||
arg.compat_tbl = st_init_numtable();
|
arg.compat_tbl = st_init_numtable();
|
||||||
|
arg.compat_tbl_wrapper = make_compat_tbl_wrapper(arg.compat_tbl);
|
||||||
|
|
||||||
major = r_byte(&arg);
|
major = r_byte(&arg);
|
||||||
minor = r_byte(&arg);
|
minor = r_byte(&arg);
|
||||||
@ -1548,6 +1581,9 @@ Init_marshal(void)
|
|||||||
rb_define_const(rb_mMarshal, "MINOR_VERSION", INT2FIX(MARSHAL_MINOR));
|
rb_define_const(rb_mMarshal, "MINOR_VERSION", INT2FIX(MARSHAL_MINOR));
|
||||||
|
|
||||||
compat_allocator_tbl = st_init_numtable();
|
compat_allocator_tbl = st_init_numtable();
|
||||||
|
rb_gc_register_address(&compat_allocator_tbl_wrapper);
|
||||||
|
compat_allocator_tbl_wrapper =
|
||||||
|
Data_Wrap_Struct(rb_cData, mark_marshal_compat_t, 0, compat_allocator_tbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user