summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--complex.c40
-rw-r--r--rational.c40
-rw-r--r--test/ruby/test_complex.rb15
-rw-r--r--test/ruby/test_rational.rb15
5 files changed, 80 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 0af07ad884..ed6f8f06ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Jul 25 17:41:05 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * 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@ruby-lang.org>
* atomic.h: prefer GCC atomic builtins than Windows APIs, if possible,
diff --git a/complex.c b/complex.c
index 1aae3b6ca8..b3279f3e0a 100644
--- a/complex.c
+++ b/complex.c
@@ -21,7 +21,8 @@ VALUE rb_cComplex;
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 @@ nucomp_inspect(VALUE self)
/* :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 @@ nucomp_marshal_dump(VALUE self)
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 @@ float_arg(VALUE self)
void
Init_Complex(void)
{
+ VALUE compat;
#undef rb_intern
#define rb_intern(str) rb_intern_const(str)
@@ -1862,6 +1876,8 @@ Init_Complex(void)
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 @@ Init_Complex(void)
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);
/* --- */
diff --git a/rational.c b/rational.c
index c4469c8092..e7a296a0d1 100644
--- a/rational.c
+++ b/rational.c
@@ -25,7 +25,7 @@ VALUE rb_cRational;
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 @@ nurat_inspect(VALUE self)
/* :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 @@ nurat_marshal_dump(VALUE self)
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 @@ nurat_s_convert(int argc, VALUE *argv, VALUE klass)
void
Init_Rational(void)
{
+ VALUE compat;
#undef rb_intern
#define rb_intern(str) rb_intern_const(str)
@@ -2315,6 +2331,8 @@ Init_Rational(void)
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 @@ Init_Rational(void)
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);
/* --- */
diff --git a/test/ruby/test_complex.rb b/test/ruby/test_complex.rb
index aa6d6a77fe..adf4a01b2d 100644
--- a/test/ruby/test_complex.rb
+++ b/test/ruby/test_complex.rb
@@ -658,14 +658,15 @@ class Complex_Test < Test::Unit::TestCase
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
diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb
index e1aafb5a0a..cc5ca9a750 100644
--- a/test/ruby/test_rational.rb
+++ b/test/ruby/test_rational.rb
@@ -828,14 +828,15 @@ class Rational_Test < Test::Unit::TestCase
}
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