summaryrefslogtreecommitdiff
path: root/math.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-29 01:42:12 (GMT)
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-29 01:42:12 (GMT)
commita1f8fbd18da34473ad27323b11f4ebe06dc43104 (patch)
treed7241f4628fa0cd63d6e73d8b080d5f94bf312b7 /math.c
parentd77ae2c2f4c6c2a4225bb1346067da478393f182 (diff)
math.c: deoptimize
* math.c (Get_Double): restrict direct casting only when Fixnum#to_f is not redefined, and convert with rb_to_float(). [Feature #10785] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49434 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'math.c')
-rw-r--r--math.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/math.c b/math.c
index c7dde81..3f0b11e 100644
--- a/math.c
+++ b/math.c
@@ -21,10 +21,18 @@
#define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
+static ID id_to_f;
+
VALUE rb_mMath;
VALUE rb_eMathDomainError;
-#define Get_Double(x) FIXNUM_P(x) ? (double)FIX2LONG(x) : NUM2DBL(x)
+#define fix_to_f_optimizable() rb_method_basic_definition_p(rb_cFixnum, id_to_f)
+#define Get_Float(x) \
+ ((RB_TYPE_P((x), T_FLOAT) ? (void)0 : ((x) = rb_to_float(x))), RFLOAT_VALUE(x))
+#define Get_Double(x) \
+ (FIXNUM_P(x) && fix_to_f_optimizable() ? \
+ (double)FIX2LONG(x) : \
+ Get_Float(x))
#define domain_error(msg) \
rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg)
@@ -929,7 +937,7 @@ exp1(sqrt)
void
-Init_Math(void)
+InitVM_Math(void)
{
rb_mMath = rb_define_module("Math");
rb_eMathDomainError = rb_define_class_under(rb_mMath, "DomainError", rb_eStandardError);
@@ -983,3 +991,10 @@ Init_Math(void)
rb_define_module_function(rb_mMath, "gamma", math_gamma, 1);
rb_define_module_function(rb_mMath, "lgamma", math_lgamma, 1);
}
+
+void
+Init_Math(void)
+{
+ id_to_f = rb_intern_const("to_f");
+ InitVM(Math);
+}