ruby-changes:20947
From: mrkn <ko1@a...>
Date: Wed, 17 Aug 2011 15:35:33 +0900 (JST)
Subject: [ruby-changes:20947] mrkn:r32996 (trunk): Merge branch '5172_bigdecimal_gc_issue' into trunk
mrkn 2011-08-17 15:35:21 +0900 (Wed, 17 Aug 2011) New Revision: 32996 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=32996 Log: Merge branch '5172_bigdecimal_gc_issue' into trunk Modified files: trunk/ChangeLog trunk/ext/bigdecimal/bigdecimal.c trunk/test/bigdecimal/test_bigdecimal.rb trunk/test/bigdecimal/testbase.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 32995) +++ ChangeLog (revision 32996) @@ -1,3 +1,21 @@ +Wed Aug 17 15:27:00 2011 Kenta Murata <mrkn@m...> + + * ext/bigdecimal/bigdecimal.c (cannot_be_coerced_into_BigDecimal): + add a new function for raising error when an object cannot coerce + into BigDecimal. [Bug #5172] + + * ext/bigdecimal/bigdecimal.c (BigDecimalValueWithPrec): use + cannot_be_coerced_into_BigDecimal function. + + * ext/bigdecimal/bigdecimal.c (BigMath_s_exp): ditto. + + * ext/bigdecimal/bigdecimal.c (BigMath_s_log): ditto. + + * test/bigdecimal/test_bigdecimal.rb: test for the avobe changes. + + * test/bigdecimal/testbase.rb (under_gc_stress): add a new utility + method to run tests under the condition of GC.stress = true. + Wed Aug 17 10:16:00 2011 Kenta Murata <mrkn@m...> * rational.c (nurat_coerce): Rational#coerce should converts itself Index: ext/bigdecimal/bigdecimal.c =================================================================== --- ext/bigdecimal/bigdecimal.c (revision 32995) +++ ext/bigdecimal/bigdecimal.c (revision 32996) @@ -174,6 +174,25 @@ return p->obj; } +NORETURN(static void cannot_be_coerced_into_BigDecimal(VALUE, VALUE)); + +static void +cannot_be_coerced_into_BigDecimal(VALUE exc_class, VALUE v) +{ + VALUE str; + + if (rb_special_const_p(v)) { + str = rb_str_cat2(rb_str_dup(rb_inspect(v)), + " can't be coerced into BigDecimal"); + } + else { + str = rb_str_cat2(rb_str_dup(rb_class_name(rb_obj_class(v))), + " can't be coerced into BigDecimal"); + } + + rb_exc_raise(rb_exc_new3(exc_class, str)); +} + static VALUE BigDecimal_div2(int, VALUE*, VALUE); static Real* @@ -240,8 +259,7 @@ SomeOneMayDoIt: if (must) { - rb_raise(rb_eTypeError, "%s can't be coerced into BigDecimal", - rb_special_const_p(v) ? RSTRING_PTR(rb_inspect(v)) : rb_obj_classname(v)); + cannot_be_coerced_into_BigDecimal(rb_eTypeError, v); } return NULL; /* NULL means to coerce */ @@ -2463,8 +2481,7 @@ return ToValue(vy); } else if (vx == NULL) { - rb_raise(rb_eArgError, "%s can't be coerced into BigDecimal", - rb_special_const_p(x) ? RSTRING_PTR(rb_inspect(x)) : rb_obj_classname(x)); + cannot_be_coerced_into_BigDecimal(rb_eArgError, x); } RB_GC_GUARD(vx->obj); @@ -2619,8 +2636,7 @@ "Zero or negative argument for log"); } else if (vx == NULL) { - rb_raise(rb_eArgError, "%s can't be coerced into BigDecimal", - rb_special_const_p(x) ? RSTRING_PTR(rb_inspect(x)) : rb_obj_classname(x)); + cannot_be_coerced_into_BigDecimal(rb_eArgError, x); } x = ToValue(vx); Index: test/bigdecimal/test_bigdecimal.rb =================================================================== --- test/bigdecimal/test_bigdecimal.rb (revision 32995) +++ test/bigdecimal/test_bigdecimal.rb (revision 32996) @@ -1086,7 +1086,7 @@ assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal.new("-1E-1" + "0" * 10000).sign) end - def test_gc + def test_split_under_gc_stress bug3258 = '[ruby-dev:41213]' stress, GC.stress = GC.stress, true 10.upto(20) do |i| @@ -1097,6 +1097,21 @@ GC.stress = stress end + def test_coerce_under_gc_stress + expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal" + under_gc_stress do + b = BigDecimal.new("1") + 10.times do + begin + b.coerce(:too_long_to_embed_as_string) + rescue => e + assert_instance_of TypeError, e + assert_equal expect, e.message + end + end + end + end + def test_INFINITY assert(BigDecimal::INFINITY.infinite?, "BigDecimal::INFINITY is not a infinity") end @@ -1157,6 +1172,20 @@ assert_in_epsilon(Math.exp(-40), BigMath.exp(BigDecimal("-40"), n)) end + def test_BigMath_exp_under_gc_stress + expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal" + under_gc_stress do + 10.times do + begin + BigMath.exp(:too_long_to_embed_as_string, 6) + rescue => e + assert_instance_of ArgumentError, e + assert_equal expect, e.message + end + end + end + end + def test_BigMath_log_with_nil assert_raise(ArgumentError) do BigMath.log(nil, 20) @@ -1241,4 +1270,18 @@ assert_in_delta(Math.log(1e-42), BigMath.log(1e-42, 20)) assert_in_delta(Math.log(1e-42), BigMath.log(BigDecimal("1e-42"), 20)) end + + def test_BigMath_log_under_gc_stress + expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal" + under_gc_stress do + 10.times do + begin + BigMath.log(:too_long_to_embed_as_string, 6) + rescue => e + assert_instance_of ArgumentError, e + assert_equal expect, e.message + end + end + end + end end Index: test/bigdecimal/testbase.rb =================================================================== --- test/bigdecimal/testbase.rb (revision 32995) +++ test/bigdecimal/testbase.rb (revision 32996) @@ -17,4 +17,11 @@ BigDecimal.mode(mode, !(@mode & mode).zero?) end end + + def under_gc_stress + stress, GC.stress = GC.stress, true + yield + ensure + GC.stress = stress + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/