[前][次][番号順一覧][スレッド一覧]

ruby-changes:2036

From: ko1@a...
Date: 27 Sep 2007 04:12:19 +0900
Subject: [ruby-changes:2036] nobu - Ruby:r13527 (trunk): * marshal.c (struct dump_arg, struct load_arg): added wrappers to mark

nobu	2007-09-27 04:12:04 +0900 (Thu, 27 Sep 2007)

  New Revision: 13527

  Modified files:
    trunk/ChangeLog
    trunk/marshal.c

  Log:
    * marshal.c (struct dump_arg, struct load_arg): added wrappers to mark
      compat_tbl entries.  [ruby-dev:31870]


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13527&r2=13526
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/marshal.c?r1=13527&r2=13526

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 13526)
+++ ChangeLog	(revision 13527)
@@ -1,3 +1,8 @@
+Thu Sep 27 04:12:01 2007  Nobuyoshi Nakada  <nobu@r...>
+
+	* 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@r...>
 
 	* process.c (rb_waitpid): no needs to poll.  [ruby-dev:31871]
Index: marshal.c
===================================================================
--- marshal.c	(revision 13526)
+++ marshal.c	(revision 13527)
@@ -89,8 +89,27 @@
     VALUE (*loader)(VALUE, VALUE);
 } 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 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
 rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE))
 {
@@ -104,8 +123,6 @@
     compat = ALLOC(marshal_compat_t);
     compat->newclass = Qnil;
     compat->oldclass = Qnil;
-    rb_gc_register_address(&compat->newclass);
-    rb_gc_register_address(&compat->oldclass);
     compat->newclass = newclass;
     compat->oldclass = oldclass;
     compat->dumper = dumper;
@@ -121,6 +138,7 @@
     st_table *data;
     int taint;
     st_table *compat_tbl;
+    VALUE compat_tbl_wrapper;
 };
 
 struct dump_call_arg {
@@ -346,6 +364,9 @@
     }
     else {
 	sym = rb_id2name(id);
+	if (!sym) {
+	    rb_raise(rb_eTypeError, "can't dump anonymous ID %ld", id);
+	}
 	w_byte(TYPE_SYMBOL, arg);
 	w_bytes(sym, strlen(sym), arg);
 	st_add_direct(arg->symbols, id, arg->symbols->num_entries);
@@ -396,11 +417,11 @@
 {
     volatile VALUE p;
     char *path;
-    VALUE real_obj;
+    st_data_t real_obj;
     VALUE klass;
 
-    if (st_lookup(arg->compat_tbl, (st_data_t)obj, (st_data_t*)&real_obj)) {
-        obj = real_obj;
+    if (st_lookup(arg->compat_tbl, (st_data_t)obj, &real_obj)) {
+        obj = (VALUE)real_obj;
     }
     klass = CLASS_OF(obj);
     w_extended(klass, arg, check);
@@ -464,7 +485,7 @@
 	return;
     }
 
-    if (ivtbl = rb_generic_ivar_table(obj)) {
+    if ((ivtbl = rb_generic_ivar_table(obj)) != 0) {
 	w_byte(TYPE_IVAR, arg);
     }
     if (obj == Qnil) {
@@ -499,11 +520,12 @@
 	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);
             if (st_lookup(compat_allocator_tbl,
                           (st_data_t)allocator,
-                          (st_data_t*)(void*)&compat)) {
+                          &compat_data)) {
+                marshal_compat_t *compat = (marshal_compat_t*)compat_data;
                 VALUE real_obj = obj;
                 obj = compat->dumper(real_obj);
                 st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
@@ -699,6 +721,9 @@
 {
     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;
     if (arg->taint) {
 	OBJ_TAINT(arg->str);
     }
@@ -772,6 +797,7 @@
     arg.data    = st_init_numtable();
     arg.taint   = Qfalse;
     arg.compat_tbl = st_init_numtable();
+    arg.compat_tbl_wrapper = make_compat_tbl_wrapper(arg.compat_tbl);
     c_arg.obj   = obj;
     c_arg.arg   = &arg;
     c_arg.limit = limit;
@@ -792,6 +818,7 @@
     VALUE proc;
     int taint;
     st_table *compat_tbl;
+    VALUE compat_tbl_wrapper;
 };
 
 static VALUE r_entry(VALUE v, struct load_arg *arg);
@@ -952,17 +979,17 @@
 static VALUE
 r_entry(VALUE v, struct load_arg *arg)
 {
-    VALUE real_obj = Qundef;
-    if (st_lookup(arg->compat_tbl, v, (st_data_t*)&real_obj)) {
-        rb_hash_aset(arg->data, INT2FIX(RHASH_SIZE(arg->data)), real_obj);
+    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);
     }
     else {
         rb_hash_aset(arg->data, INT2FIX(RHASH_SIZE(arg->data)), v);
     }
     if (arg->taint) {
         OBJ_TAINT(v);
-        if (real_obj != Qundef)
-            OBJ_TAINT(real_obj);
+        if ((VALUE)real_obj != Qundef)
+            OBJ_TAINT((VALUE)real_obj);
     }
     if (arg->proc) {
 	v = rb_funcall(arg->proc, rb_intern("call"), 1, v);
@@ -973,12 +1000,13 @@
 static VALUE
 r_leave(VALUE v, struct load_arg *arg)
 {
-    VALUE real_obj;
-    marshal_compat_t *compat;
-    if (st_lookup(arg->compat_tbl, v, &real_obj)) {
+    st_data_t data;
+    if (st_lookup(arg->compat_tbl, v, &data)) {
+        VALUE real_obj = (VALUE)data;
         rb_alloc_func_t allocator = rb_get_alloc_func(CLASS_OF(real_obj));
         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);
         }
         st_delete(arg->compat_tbl, &key, 0);
@@ -1028,13 +1056,14 @@
 obj_alloc_by_path(const char *path, struct load_arg *arg)
 {
     VALUE klass;
-    marshal_compat_t *compat;
+    st_data_t data;
     rb_alloc_func_t allocator;
 
     klass = path2class(path);
 
     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 obj = rb_obj_alloc(compat->oldclass);
         st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
@@ -1428,6 +1457,9 @@
 load_ensure(struct load_arg *arg)
 {
     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;
 }
 
@@ -1467,6 +1499,7 @@
     arg.src = port;
     arg.offset = 0;
     arg.compat_tbl = st_init_numtable();
+    arg.compat_tbl_wrapper = make_compat_tbl_wrapper(arg.compat_tbl);
 
     major = r_byte(&arg);
     minor = r_byte(&arg);
@@ -1548,6 +1581,9 @@
     rb_define_const(rb_mMarshal, "MINOR_VERSION", INT2FIX(MARSHAL_MINOR));
 
     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

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧]