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

ruby-changes:10188

From: shyouhei <ko1@a...>
Date: Thu, 22 Jan 2009 15:22:25 +0900 (JST)
Subject: [ruby-changes:10188] Ruby:r21731 (ruby_1_8_7): merge revision(s) 19078,20097:

shyouhei	2009-01-22 15:22:00 +0900 (Thu, 22 Jan 2009)

  New Revision: 21731

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=21731

  Log:
    merge revision(s) 19078,20097:
    * gc.c (rb_mark_set): new function to mark keys.
    * marshal.c (struct dump_arg, struct load_arg): added wrappers to mark
      data entries.  backport from trunk r13527,r13528,r13961,r16533.
      [ruby-dev:36082]
    * marshal.c (marshal_load): arg.data is no longer a VALUE but a
      st_table, and freed in load_ensure.  pointed out by pegacorn.
      [ruby-dev:37008]

  Modified files:
    branches/ruby_1_8_7/ChangeLog
    branches/ruby_1_8_7/gc.c
    branches/ruby_1_8_7/intern.h
    branches/ruby_1_8_7/marshal.c
    branches/ruby_1_8_7/test/ruby/marshaltestlib.rb
    branches/ruby_1_8_7/test/ruby/test_marshal.rb
    branches/ruby_1_8_7/version.h

Index: ruby_1_8_7/intern.h
===================================================================
--- ruby_1_8_7/intern.h	(revision 21730)
+++ ruby_1_8_7/intern.h	(revision 21731)
@@ -256,6 +256,7 @@
 char *rb_source_filename _((const char*));
 void rb_gc_mark_locations _((VALUE*, VALUE*));
 void rb_mark_tbl _((struct st_table*));
+void rb_mark_set _((struct st_table*));
 void rb_mark_hash _((struct st_table*));
 void rb_gc_mark_maybe _((VALUE));
 void rb_gc_mark _((VALUE));
Index: ruby_1_8_7/ChangeLog
===================================================================
--- ruby_1_8_7/ChangeLog	(revision 21730)
+++ ruby_1_8_7/ChangeLog	(revision 21731)
@@ -1,3 +1,17 @@
+Thu Jan 22 15:19:39 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* marshal.c (marshal_load): arg.data is no longer a VALUE but a
+	  st_table, and freed in load_ensure.  pointed out by pegacorn.
+	  [ruby-dev:37008]
+
+Thu Jan 22 15:19:39 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* gc.c (rb_mark_set): new function to mark keys.
+
+	* marshal.c (struct dump_arg, struct load_arg): added wrappers to mark
+	  data entries.  backport from trunk r13527,r13528,r13961,r16533.
+	  [ruby-dev:36082]
+
 Wed Jan 21 11:12:55 2009  NAKAMURA Usaku  <usa@r...>
 
 	* win32/win32.c (filetime_to_timeval): new function, split from
Index: ruby_1_8_7/version.h
===================================================================
--- ruby_1_8_7/version.h	(revision 21730)
+++ ruby_1_8_7/version.h	(revision 21731)
@@ -1,15 +1,15 @@
 #define RUBY_VERSION "1.8.7"
-#define RUBY_RELEASE_DATE "2009-01-21"
+#define RUBY_RELEASE_DATE "2009-01-22"
 #define RUBY_VERSION_CODE 187
-#define RUBY_RELEASE_CODE 20090121
-#define RUBY_PATCHLEVEL 91
+#define RUBY_RELEASE_CODE 20090122
+#define RUBY_PATCHLEVEL 92
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8
 #define RUBY_VERSION_TEENY 7
 #define RUBY_RELEASE_YEAR 2009
 #define RUBY_RELEASE_MONTH 1
-#define RUBY_RELEASE_DAY 21
+#define RUBY_RELEASE_DAY 22
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
Index: ruby_1_8_7/marshal.c
===================================================================
--- ruby_1_8_7/marshal.c	(revision 21730)
+++ ruby_1_8_7/marshal.c	(revision 21731)
@@ -84,22 +84,13 @@
 static ID s_dump_data, s_load_data, s_alloc, s_call;
 static ID s_getc, s_read, s_write, s_binmode;
 
-static void
-reentrant_check(obj, sym)
-    VALUE obj;
-    ID sym;
-{
-    if (obj && RBASIC(obj)->klass) {
-        rb_raise(rb_eRuntimeError, "%s reentered", rb_id2name(sym));
-    }
-}
-
 struct dump_arg {
     VALUE obj;
     VALUE str, dest;
     st_table *symbols;
     st_table *data;
     int taint;
+    VALUE wrapper;
 };
 
 struct dump_call_arg {
@@ -108,6 +99,27 @@
     int limit;
 };
 
+static void
+check_dump_arg(arg, sym)
+    struct dump_arg *arg;
+    ID sym;
+{
+    if (!DATA_PTR(arg->wrapper)) {
+        rb_raise(rb_eRuntimeError, "Marshal.dump reentered at %s",
+		 rb_id2name(sym));
+    }
+}
+
+static void
+mark_dump_arg(ptr)
+    void *ptr;
+{
+    struct dump_arg *p = ptr;
+    if (!ptr)
+        return;
+    rb_mark_set(p->data);
+}
+
 static VALUE
 class2path(klass)
     VALUE klass;
@@ -515,7 +527,7 @@
 	    volatile VALUE v;
 
 	    v = rb_funcall(obj, s_mdump, 0, 0);
-	    reentrant_check(arg->str, s_mdump);
+	    check_dump_arg(arg, s_mdump);
 	    w_class(TYPE_USRMARSHAL, obj, arg, Qfalse);
 	    w_object(v, arg, limit);
 	    if (ivtbl) w_ivar(0, &c_arg);
@@ -525,7 +537,7 @@
 	    VALUE v;
 
 	    v = rb_funcall(obj, s_dump, 1, INT2NUM(limit));
-	    reentrant_check(arg->str, s_dump);
+	    check_dump_arg(arg, s_dump);
 	    if (TYPE(v) != T_STRING) {
 		rb_raise(rb_eTypeError, "_dump() must return string");
 	    }
@@ -670,7 +682,7 @@
 			     rb_obj_classname(obj));
 		}
 		v = rb_funcall(obj, s_dump_data, 0);
-		reentrant_check(arg->str, s_dump_data);
+		check_dump_arg(arg, s_dump_data);
 		w_class(TYPE_DATA, obj, arg, Qtrue);
 		w_object(v, arg, limit);
 	    }
@@ -703,9 +715,11 @@
 dump_ensure(arg)
     struct dump_arg *arg;
 {
-    if (RBASIC(arg->str)->klass) return 0; /* ignore reentrant */
+    if (!DATA_PTR(arg->wrapper)) return 0;
     st_free_table(arg->symbols);
     st_free_table(arg->data);
+    DATA_PTR(arg->wrapper) = 0;
+    arg->wrapper = 0;
     if (arg->taint) {
 	OBJ_TAINT(arg->str);
     }
@@ -772,7 +786,7 @@
 	arg.dest = port;
 	if (rb_respond_to(port, s_binmode)) {
 	    rb_funcall2(port, s_binmode, 0, 0);
-	    reentrant_check(arg.str, s_dump_data);
+	    check_dump_arg(&arg, s_dump_data);
 	}
     }
     else {
@@ -782,6 +796,7 @@
     arg.symbols = st_init_numtable();
     arg.data    = st_init_numtable();
     arg.taint   = Qfalse;
+    arg.wrapper = Data_Wrap_Struct(rb_cData, mark_dump_arg, 0, &arg);
     c_arg.obj   = obj;
     c_arg.arg   = &arg;
     c_arg.limit = limit;
@@ -799,11 +814,33 @@
     VALUE src;
     long offset;
     st_table *symbols;
-    VALUE data;
+    st_table *data;
     VALUE proc;
     int taint;
+    VALUE wrapper;
 };
 
+static void
+check_load_arg(arg, sym)
+    struct load_arg *arg;
+    ID sym;
+{
+    if (!DATA_PTR(arg->wrapper)) {
+        rb_raise(rb_eRuntimeError, "Marshal.load reentered at %s",
+		 rb_id2name(sym));
+    }
+}
+
+static void
+mark_load_arg(ptr)
+    void *ptr;
+{
+    struct load_arg *p = ptr;
+    if (!ptr)
+        return;
+    rb_mark_tbl(p->data);
+}
+
 static VALUE r_object _((struct load_arg *arg));
 
 static int
@@ -823,7 +860,7 @@
     else {
 	VALUE src = arg->src;
 	VALUE v = rb_funcall2(src, s_getc, 0, 0);
-	reentrant_check(arg->data, s_getc);
+	check_load_arg(arg, s_getc);
 	if (NIL_P(v)) rb_eof_error();
 	c = (unsigned char)FIX2INT(v);
     }
@@ -904,7 +941,7 @@
 	VALUE src = arg->src;
 	VALUE n = LONG2NUM(len);
 	str = rb_funcall2(src, s_read, 1, &n);
-	reentrant_check(arg->data, s_read);
+	check_load_arg(arg, s_read);
 	if (NIL_P(str)) goto too_short;
 	StringValue(str);
 	if (RSTRING(str)->len != len) goto too_short;
@@ -967,7 +1004,7 @@
     VALUE v;
     struct load_arg *arg;
 {
-    rb_hash_aset(arg->data, INT2FIX(RHASH(arg->data)->tbl->num_entries), v);
+    st_insert(arg->data, arg->data->num_entries, (st_data_t)v);
     if (arg->taint) OBJ_TAINT(v);
     return v;
 }
@@ -1023,14 +1060,15 @@
     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));
-	if (NIL_P(v)) {
+ 	if (!st_lookup(arg->data, (st_data_t)id, &link)) {
 	    rb_raise(rb_eArgError, "dump format error (unlinked)");
 	}
+	v = (st_data_t)link;
 	return v;
 
       case TYPE_IVAR:
@@ -1255,7 +1293,7 @@
 		*ivp = Qfalse;
 	    }
 	    v = rb_funcall(klass, s_load, 1, data);
-	    reentrant_check(arg->data, s_load);
+	    check_load_arg(arg, s_load);
 	    r_entry(v, arg);
 	}
         break;
@@ -1279,7 +1317,7 @@
 	    r_entry(v, arg);
 	    data = r_object(arg);
 	    rb_funcall(v, s_mload, 1, data);
-	    reentrant_check(arg->data, s_mload);
+	    check_load_arg(arg, s_mload);
 	}
         break;
 
@@ -1306,7 +1344,7 @@
 		   warn = Qfalse;
 	       }
 	       v = rb_funcall(klass, s_alloc, 0);
-	       reentrant_check(arg->data, s_alloc);
+	       check_load_arg(arg, s_alloc);
            }
 	   else {
 	       v = rb_obj_alloc(klass);
@@ -1321,7 +1359,7 @@
                         rb_class2name(klass));
            }
            rb_funcall(v, s_load_data, 1, r_object0(arg, 0, 0, extmod));
-	   reentrant_check(arg->data, s_load_data);
+	   check_load_arg(arg, s_load_data);
        }
        break;
 
@@ -1365,7 +1403,7 @@
     }
     if (proc) {
 	rb_funcall(proc, s_call, 1, v);
-	reentrant_check(arg->data, s_call);
+	check_load_arg(arg, s_call);
     }
     return v;
 }
@@ -1388,8 +1426,11 @@
 load_ensure(arg)
     struct load_arg *arg;
 {
-    if (RBASIC(arg->data)->klass) return 0; /* ignore reentrant */
+    if (!DATA_PTR(arg->wrapper)) return 0;
     st_free_table(arg->symbols);
+    st_free_table(arg->data);
+    DATA_PTR(arg->wrapper) = 0;
+    arg->wrapper = 0;
     return 0;
 }
 
@@ -1431,7 +1472,10 @@
     }
     arg.src = port;
     arg.offset = 0;
-    arg.data = 0;
+    arg.symbols = st_init_numtable();
+    arg.data    = st_init_numtable();
+    arg.proc = 0;
+    arg.wrapper = Data_Wrap_Struct(rb_cData, mark_load_arg, 0, &arg);
 
     major = r_byte(&arg);
     minor = r_byte(&arg);
@@ -1446,13 +1490,8 @@
 		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);
-    RBASIC(arg.data)->klass = rb_cHash;
 
     return v;
 }
Index: ruby_1_8_7/test/ruby/test_marshal.rb
===================================================================
--- ruby_1_8_7/test/ruby/test_marshal.rb	(revision 21730)
+++ ruby_1_8_7/test/ruby/test_marshal.rb	(revision 21731)
@@ -12,11 +12,17 @@
   include MarshalTestLib
 
   def encode(o)
+    stress, GC.stress = GC.stress, true
     Marshal.dump(o)
+  ensure
+    GC.stress = stress
   end
 
   def decode(s)
+    stress, GC.stress = GC.stress, true
     Marshal.load(s)
+  ensure
+    GC.stress = stress
   end
 
   def fact(n)
Index: ruby_1_8_7/test/ruby/marshaltestlib.rb
===================================================================
--- ruby_1_8_7/test/ruby/marshaltestlib.rb	(revision 21730)
+++ ruby_1_8_7/test/ruby/marshaltestlib.rb	(revision 21731)
@@ -193,6 +193,12 @@
     1.instance_eval { remove_instance_variable("@iv") }
   end
 
+  def test_fixnum_64bit
+    obj = [1220278665, 1220278662, 1220278661, 1220278661, 1220278656]
+
+    marshal_equal(obj)
+  end
+
   def test_float
     marshal_equal(-1.0)
     marshal_equal(0.0)
Index: ruby_1_8_7/gc.c
===================================================================
--- ruby_1_8_7/gc.c	(revision 21730)
+++ ruby_1_8_7/gc.c	(revision 21731)
@@ -724,6 +724,31 @@
 }
 
 static int
+mark_key(key, value, lev)
+    VALUE key, value;
+    int lev;
+{
+    gc_mark(key, lev);
+    return ST_CONTINUE;
+}
+
+static void
+mark_set(tbl, lev)
+    st_table *tbl;
+    int lev;
+{
+    if (!tbl) return;
+    st_foreach(tbl, mark_key, lev);
+}
+
+void
+rb_mark_set(tbl)
+    st_table *tbl;
+{
+    mark_set(tbl, 0);
+}
+
+static int
 mark_keyvalue(key, value, lev)
     VALUE key;
     VALUE value;

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

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