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

ruby-changes:24487

From: nobu <ko1@a...>
Date: Wed, 25 Jul 2012 17:41:22 +0900 (JST)
Subject: [ruby-changes:24487] nobu:r36538 (trunk): complex.c, rational.c: compatible marshal loader

nobu	2012-07-25 17:41:07 +0900 (Wed, 25 Jul 2012)

  New Revision: 36538

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

  Log:
    complex.c, rational.c: compatible marshal loader
    
    * complex.c, rational.c: compatible marshal loader for compatibilities
      with 1.8.  [ruby-core:45775] [Bug #6625]

  Modified files:
    trunk/ChangeLog
    trunk/complex.c
    trunk/rational.c
    trunk/test/ruby/test_complex.rb
    trunk/test/ruby/test_rational.rb

Index: complex.c
===================================================================
--- complex.c	(revision 36537)
+++ complex.c	(revision 36538)
@@ -21,7 +21,8 @@
 static ID id_abs, id_abs2, id_arg, id_cmp, id_conj, id_convert,
     id_denominator, id_divmod, id_eqeq_p, id_expt, id_fdiv,  id_floor,
     id_idiv, id_imag, id_inspect, id_negate, id_numerator, id_quo,
-    id_real, id_real_p, id_to_f, id_to_i, id_to_r, id_to_s;
+    id_real, id_real_p, id_to_f, id_to_i, id_to_r, id_to_s,
+    id_i_real, id_i_imag;
 
 #define f_boolcast(x) ((x) ? Qtrue : Qfalse)
 
@@ -1244,13 +1245,31 @@
 
 /* :nodoc: */
 static VALUE
+nucomp_dumper(VALUE self)
+{
+    return self;
+}
+
+/* :nodoc: */
+static VALUE
+nucomp_loader(VALUE self, VALUE a)
+{
+    get_dat1(self);
+
+    dat->real = rb_ivar_get(a, id_i_real);
+    dat->imag = rb_ivar_get(a, id_i_imag);
+
+    return self;
+}
+
+/* :nodoc: */
+static VALUE
 nucomp_marshal_dump(VALUE self)
 {
     VALUE a;
     get_dat1(self);
 
     a = rb_assoc_new(dat->real, dat->imag);
-    rb_copy_generic_ivar(a, self);
     return a;
 }
 
@@ -1258,17 +1277,11 @@
 static VALUE
 nucomp_marshal_load(VALUE self, VALUE a)
 {
-    get_dat1(self);
-
-    rb_check_frozen(self);
-    rb_check_trusted(self);
-
     Check_Type(a, T_ARRAY);
     if (RARRAY_LEN(a) != 2)
 	rb_raise(rb_eArgError, "marshaled complex must have an array whose length is 2 but %ld", RARRAY_LEN(a));
-    dat->real = RARRAY_PTR(a)[0];
-    dat->imag = RARRAY_PTR(a)[1];
-    rb_copy_generic_ivar(self, a);
+    rb_ivar_set(self, id_i_real, RARRAY_PTR(a)[0]);
+    rb_ivar_set(self, id_i_imag, RARRAY_PTR(a)[1]);
     return self;
 }
 
@@ -1833,6 +1846,7 @@
 void
 Init_Complex(void)
 {
+    VALUE compat;
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
@@ -1862,6 +1876,8 @@
     id_to_i = rb_intern("to_i");
     id_to_r = rb_intern("to_r");
     id_to_s = rb_intern("to_s");
+    id_i_real = rb_intern("@real");
+    id_i_imag = rb_intern("@image");
 
     rb_cComplex = rb_define_class("Complex", rb_cNumeric);
 
@@ -1951,7 +1967,9 @@
     rb_define_method(rb_cComplex, "inspect", nucomp_inspect, 0);
 
     rb_define_method(rb_cComplex, "marshal_dump", nucomp_marshal_dump, 0);
-    rb_define_method(rb_cComplex, "marshal_load", nucomp_marshal_load, 1);
+    compat = rb_define_class_under(rb_cComplex, "compatible", rb_cObject);
+    rb_define_method(compat, "marshal_load", nucomp_marshal_load, 1);
+    rb_marshal_define_compat(rb_cComplex, compat, nucomp_dumper, nucomp_loader);
 
     /* --- */
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 36537)
+++ ChangeLog	(revision 36538)
@@ -1,3 +1,8 @@
+Wed Jul 25 17:41:05 2012  Nobuyoshi Nakada  <nobu@r...>
+
+	* complex.c, rational.c: compatible marshal loader for compatibilities
+	  with 1.8.  [ruby-core:45775] [Bug #6625]
+
 Wed Jul 25 17:17:05 2012  Nobuyoshi Nakada  <nobu@r...>
 
 	* atomic.h: prefer GCC atomic builtins than Windows APIs, if possible,
Index: test/ruby/test_complex.rb
===================================================================
--- test/ruby/test_complex.rb	(revision 36537)
+++ test/ruby/test_complex.rb	(revision 36538)
@@ -658,14 +658,15 @@
     end
 
     bug3656 = '[ruby-core:31622]'
-    assert_raise(TypeError, bug3656) {
-      Complex(1,2).marshal_load(0)
-    }
+    assert_not_respond_to(Complex(1,2), :marshal_load, bug3656)
+  end
 
-    c = Complex(1,2)
-    c.freeze
-    assert(c.frozen?)
-    assert_raise(RuntimeError){c.marshal_load([2,3])}
+  def test_marshal_compatibility
+    bug6625 = '[ruby-core:45775]'
+    dump = "\x04\x08o:\x0cComplex\x07:\x0a@reali\x06:\x0b@imagei\x07"
+    assert_nothing_raised(bug6625) do
+      assert_equal(Complex(1, 2), Marshal.load(dump), bug6625)
+    end
   end
 
   def test_parse
Index: test/ruby/test_rational.rb
===================================================================
--- test/ruby/test_rational.rb	(revision 36537)
+++ test/ruby/test_rational.rb	(revision 36538)
@@ -828,14 +828,15 @@
     }
 
     bug3656 = '[ruby-core:31622]'
-    assert_raise(TypeError, bug3656) {
-      Rational(1,2).marshal_load(0)
-    }
+    assert_not_respond_to(Rational(1,2), :marshal_load, bug3656)
+  end
 
-    c = Rational(1,2)
-    c.freeze
-    assert(c.frozen?)
-    assert_raise(RuntimeError){c.marshal_load([2,3])}
+  def test_marshal_compatibility
+    bug6625 = '[ruby-core:45775]'
+    dump = "\x04\x08o:\x0dRational\x07:\x11@denominatori\x07:\x0f@numeratori\x06"
+    assert_nothing_raised(bug6625) do
+      assert_equal(Rational(1, 2), Marshal.load(dump), bug6625)
+    end
   end
 
   def test_parse
Index: rational.c
===================================================================
--- rational.c	(revision 36537)
+++ rational.c	(revision 36538)
@@ -25,7 +25,7 @@
 
 static ID id_abs, id_cmp, id_convert, id_eqeq_p, id_expt, id_fdiv,
     id_floor, id_idiv, id_inspect, id_integer_p, id_negate, id_to_f,
-    id_to_i, id_to_s, id_truncate;
+    id_to_i, id_to_s, id_truncate, id_i_num, id_i_den;
 
 #define f_boolcast(x) ((x) ? Qtrue : Qfalse)
 
@@ -1590,13 +1590,31 @@
 
 /* :nodoc: */
 static VALUE
+nurat_dumper(VALUE self)
+{
+    return self;
+}
+
+/* :nodoc: */
+static VALUE
+nurat_loader(VALUE self, VALUE a)
+{
+    get_dat1(self);
+
+    dat->num = rb_ivar_get(a, id_i_num);
+    dat->den = rb_ivar_get(a, id_i_den);
+
+    return self;
+}
+
+/* :nodoc: */
+static VALUE
 nurat_marshal_dump(VALUE self)
 {
     VALUE a;
     get_dat1(self);
 
     a = rb_assoc_new(dat->num, dat->den);
-    rb_copy_generic_ivar(a, self);
     return a;
 }
 
@@ -1604,21 +1622,18 @@
 static VALUE
 nurat_marshal_load(VALUE self, VALUE a)
 {
-    get_dat1(self);
-
     rb_check_frozen(self);
     rb_check_trusted(self);
 
     Check_Type(a, T_ARRAY);
     if (RARRAY_LEN(a) != 2)
 	rb_raise(rb_eArgError, "marshaled rational must have an array whose length is 2 but %ld", RARRAY_LEN(a));
-    dat->num = RARRAY_PTR(a)[0];
-    dat->den = RARRAY_PTR(a)[1];
-    rb_copy_generic_ivar(self, a);
-
-    if (f_zero_p(dat->den))
+    if (f_zero_p(RARRAY_PTR(a)[1]))
 	rb_raise_zerodiv();
 
+    rb_ivar_set(self, id_i_num, RARRAY_PTR(a)[0]);
+    rb_ivar_set(self, id_i_den, RARRAY_PTR(a)[1]);
+
     return self;
 }
 
@@ -2295,6 +2310,7 @@
 void
 Init_Rational(void)
 {
+    VALUE compat;
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)
 
@@ -2315,6 +2331,8 @@
     id_to_i = rb_intern("to_i");
     id_to_s = rb_intern("to_s");
     id_truncate = rb_intern("truncate");
+    id_i_num = rb_intern("@numerator");
+    id_i_den = rb_intern("@denominator");
 
     rb_cRational = rb_define_class("Rational", rb_cNumeric);
 
@@ -2375,7 +2393,9 @@
     rb_define_method(rb_cRational, "inspect", nurat_inspect, 0);
 
     rb_define_method(rb_cRational, "marshal_dump", nurat_marshal_dump, 0);
-    rb_define_method(rb_cRational, "marshal_load", nurat_marshal_load, 1);
+    compat = rb_define_class_under(rb_cRational, "compatible", rb_cObject);
+    rb_define_method(compat, "marshal_load", nurat_marshal_load, 1);
+    rb_marshal_define_compat(rb_cRational, compat, nurat_dumper, nurat_loader);
 
     /* --- */
 

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

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