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

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/

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