зеркало из https://github.com/github/ruby.git
Merge branch '5172_bigdecimal_gc_issue' into trunk
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32996 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
b30d203fed
Коммит
4e8d6c105c
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
|||
Wed Aug 17 15:27:00 2011 Kenta Murata <mrkn@mrkn.jp>
|
||||
|
||||
* 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@mrkn.jp>
|
||||
|
||||
* rational.c (nurat_coerce): Rational#coerce should converts itself
|
||||
|
|
|
@ -174,6 +174,25 @@ ToValue(Real *p)
|
|||
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 @@ again:
|
|||
|
||||
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 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
|
|||
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 @@ get_vp_value:
|
|||
"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);
|
||||
|
||||
|
|
|
@ -1086,7 +1086,7 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
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 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
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 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
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 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
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
|
||||
|
|
|
@ -17,4 +17,11 @@ module TestBigDecimalBase
|
|||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче