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

ruby-changes:64676

From: Kenta <ko1@a...>
Date: Thu, 31 Dec 2020 02:19:55 +0900 (JST)
Subject: [ruby-changes:64676] a8014dae47 (master): [ruby/bigdecimal] Refactor object allocation

https://git.ruby-lang.org/ruby.git/commit/?id=a8014dae47

From a8014dae47cc777ce5e509c9401b67cacb6631ae Mon Sep 17 00:00:00 2001
From: Kenta Murata <mrkn@m...>
Date: Thu, 31 Dec 2020 02:01:35 +0900
Subject: [ruby/bigdecimal] Refactor object allocation

https://github.com/ruby/bigdecimal/commit/271cebe567

diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index 13b2cdc..96fe253 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -266,7 +266,7 @@ again: https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L266
 	if (prec > (long)DBLE_FIG) goto SomeOneMayDoIt;
 	d = RFLOAT_VALUE(v);
 	if (!isfinite(d)) {
-	    pv = VpCreateRbObject(1, NULL);
+            pv = VpCreateRbObject(1, NULL, true);
 	    VpDtoV(pv, d);
 	    return pv;
 	}
@@ -275,9 +275,9 @@ again: https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L275
 	    goto again;
 	}
 	if (1/d < 0.0) {
-	    return VpCreateRbObject(prec, "-0");
+            return VpCreateRbObject(prec, "-0", true);
 	}
-	return VpCreateRbObject(prec, "0");
+        return VpCreateRbObject(prec, "0", true);
 
       case T_RATIONAL:
 	if (prec < 0) goto unable_to_coerce_without_prec;
@@ -306,20 +306,20 @@ again: https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L306
 
       case T_FIXNUM:
 	sprintf(szD, "%ld", FIX2LONG(v));
-	return VpCreateRbObject(VpBaseFig() * 2 + 1, szD);
+        return VpCreateRbObject(VpBaseFig() * 2 + 1, szD, true);
 
 #ifdef ENABLE_NUMERIC_STRING
       case T_STRING:
 	StringValueCStr(v);
-	return VpCreateRbObject(RSTRING_LEN(v) + VpBaseFig() + 1,
-				RSTRING_PTR(v));
+        return VpCreateRbObject(RSTRING_LEN(v) + VpBaseFig() + 1,
+                                RSTRING_PTR(v), true);
 #endif /* ENABLE_NUMERIC_STRING */
 
       case T_BIGNUM:
 	bg = rb_big2str(v, 10);
 	PUSH(bg);
-	return VpCreateRbObject(strlen(RSTRING_PTR(bg)) + VpBaseFig() + 1,
-				RSTRING_PTR(bg));
+        return VpCreateRbObject(strlen(RSTRING_PTR(bg)) + VpBaseFig() + 1,
+                                RSTRING_PTR(bg), true);
       default:
 	goto SomeOneMayDoIt;
     }
@@ -559,7 +559,7 @@ BigDecimal_load(VALUE self, VALUE str) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L559
         m = m*10 + (unsigned long)(ch-'0');
     }
     if (m > VpBaseFig()) m -= VpBaseFig();
-    GUARD_OBJ(pv, VpNewRbClass(m, (char *)pch, self));
+    GUARD_OBJ(pv, VpNewRbClass(m, (char *)pch, self, true, true));
     m /= VpBaseFig();
     if (m && pv->MaxPrec > m) {
 	pv->MaxPrec = m+1;
@@ -774,21 +774,39 @@ GetPrecisionInt(VALUE v) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L774
     return n;
 }
 
+static VALUE
+BigDecimal_wrap_struct(VALUE obj, Real *vp)
+{
+    assert(is_kind_of_BigDecimal(obj));
+    assert(vp != NULL);
+
+    if (vp->obj == obj && RTYPEDDATA_DATA(obj) == vp)
+        return obj;
+
+    assert(RTYPEDDATA_DATA(obj) == NULL);
+    assert(vp->obj == 0);
+
+    RTYPEDDATA_DATA(obj) = vp;
+    vp->obj = obj;
+    RB_OBJ_FREEZE(obj);
+    return obj;
+}
+
 VP_EXPORT Real *
-VpNewRbClass(size_t mx, const char *str, VALUE klass)
+VpNewRbClass(size_t mx, const char *str, VALUE klass, bool strict_p, bool raise_exception)
 {
     VALUE obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, 0);
-    Real *pv = VpAlloc(mx, str, 1, 1);
-    RTYPEDDATA_DATA(obj) = pv;
-    pv->obj = obj;
-    RB_OBJ_FREEZE(obj);
+    Real *pv = VpAlloc(mx, str, strict_p, raise_exception);
+    if (!pv)
+        return NULL;
+    BigDecimal_wrap_struct(obj, pv);
     return pv;
 }
 
 VP_EXPORT Real *
-VpCreateRbObject(size_t mx, const char *str)
+VpCreateRbObject(size_t mx, const char *str, bool raise_exception)
 {
-    return VpNewRbClass(mx, str, rb_cBigDecimal);
+    return VpNewRbClass(mx, str, rb_cBigDecimal, true, raise_exception);
 }
 
 #define VpAllocReal(prec) (Real *)VpMemAlloc(offsetof(Real, frac) + (prec) * sizeof(BDIGIT))
@@ -1076,11 +1094,11 @@ BigDecimal_add(VALUE self, VALUE r) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1094
 
     mx = GetAddSubPrec(a, b);
     if (mx == (size_t)-1L) {
-	GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0"));
+        GUARD_OBJ(c, VpCreateRbObject(VpBaseFig() + 1, "0", true));
 	VpAddSub(c, a, b, 1);
     }
     else {
-	GUARD_OBJ(c, VpCreateRbObject(mx * (VpBaseFig() + 1), "0"));
+        GUARD_OBJ(c, VpCreateRbObject(mx * (VpBaseFig() + 1), "0", true));
 	if(!mx) {
 	    VpSetInf(c, VpGetSign(a));
 	}
@@ -1134,11 +1152,11 @@ BigDecimal_sub(VALUE self, VALUE r) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1152
 
     mx = GetAddSubPrec(a,b);
     if (mx == (size_t)-1L) {
-	GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0"));
+        GUARD_OBJ(c, VpCreateRbObject(VpBaseFig() + 1, "0", true));
 	VpAddSub(c, a, b, -1);
     }
     else {
-	GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0"));
+        GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0", true));
 	if (!mx) {
 	    VpSetInf(c,VpGetSign(a));
 	}
@@ -1351,7 +1369,7 @@ BigDecimal_neg(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1369
     ENTER(5);
     Real *c, *a;
     GUARD_OBJ(a, GetVpValue(self, 1));
-    GUARD_OBJ(c, VpCreateRbObject(a->Prec *(VpBaseFig() + 1), "0"));
+    GUARD_OBJ(c, VpCreateRbObject(a->Prec *(VpBaseFig() + 1), "0", true));
     VpAsgn(c, a, -1);
     return VpCheckGetValue(c);
 }
@@ -1393,7 +1411,7 @@ BigDecimal_mult(VALUE self, VALUE r) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1411
     SAVE(b);
 
     mx = a->Prec + b->Prec;
-    GUARD_OBJ(c, VpCreateRbObject(mx *(VpBaseFig() + 1), "0"));
+    GUARD_OBJ(c, VpCreateRbObject(mx *(VpBaseFig() + 1), "0", true));
     VpMult(c, a, b);
     return VpCheckGetValue(c);
 }
@@ -1426,8 +1444,8 @@ BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1444
     mx++; /* NOTE: An additional digit is needed for the compatibility to
                    the version 1.2.1 and the former.  */
     mx = (mx + 1) * VpBaseFig();
-    GUARD_OBJ((*c), VpCreateRbObject(mx, "#0"));
-    GUARD_OBJ((*res), VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0"));
+    GUARD_OBJ((*c), VpCreateRbObject(mx, "#0", true));
+    GUARD_OBJ((*res), VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0", true));
     VpDivd(*c, *res, a, b);
     return Qnil;
 }
@@ -1492,22 +1510,22 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1510
 	rb_raise(rb_eZeroDivError, "divided by 0");
     }
     if (VpIsInf(a)) {
-	GUARD_OBJ(d, VpCreateRbObject(1, "0"));
+        GUARD_OBJ(d, VpCreateRbObject(1, "0", true));
 	VpSetInf(d, (SIGNED_VALUE)(VpGetSign(a) == VpGetSign(b) ? 1 : -1));
-	GUARD_OBJ(c, VpCreateRbObject(1, "NaN"));
+        GUARD_OBJ(c, VpCreateRbObject(1, "NaN", true));
 	*div = d;
 	*mod = c;
 	return Qtrue;
     }
     if (VpIsInf(b)) {
-	GUARD_OBJ(d, VpCreateRbObject(1, "0"));
+        GUARD_OBJ(d, VpCreateRbObject(1, "0", true));
 	*div = d;
 	*mod = a;
 	return Qtrue;
     }
     if (VpIsZero(a)) {
-	GUARD_OBJ(c, VpCreateRbObject(1, "0"));
-	GUARD_OBJ(d, VpCreateRbObject(1, "0"));
+        GUARD_OBJ(c, VpCreateRbObject(1, "0", true));
+        GUARD_OBJ(d, VpCreateRbObject(1, "0", true));
 	*div = d;
 	*mod = c;
 	return Qtrue;
@@ -1516,17 +1534,17 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1534
     mx = a->Prec + vabs(a->exponent);
     if (mx<b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent);
     mx = (mx + 1) * VpBaseFig();
-    GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
-    GUARD_OBJ(res, VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0"));
+    GUARD_OBJ(c, VpCreateRbObject(mx, "0", true));
+    GUARD_OBJ(res, VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0", true));
     VpDivd(c, res, a, b);
     mx = c->Prec * (VpBaseFig() + 1);
-    GUARD_OBJ(d, VpCreateRbObject(mx, "0"));
+    GUARD_OBJ(d, VpCreateRbObject(mx, "0", true));
     VpActiveRound(d, c, VP_ROUND_DOWN, 0);
     VpMult(res, d, b);
     VpAddSub(c, a, res, -1);
     if (!VpIsZero(c) && (VpGetSign(a) * VpGetSign(b) < 0)) {
 	VpAddSub(res, d, VpOne(), -1);
-	GUARD_OBJ(d, VpCreateRbObject(GetAddSubPrec(c, b)*(VpBaseFig() + 1), "0"));
+        GUARD_OBJ(d, VpCreateRbObject(GetAddSubPrec(c, b)*(VpBaseFig() + 1), "0", true));
 	VpAddSub(d, c, b, 1);
 	*div = res;
 	*mod = d;
@@ -1537,8 +1555,8 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1555
     return Qtrue;
 
 NaN:
-    GUARD_OBJ(c, VpCreateRbObject(1, "NaN"));
-    GUARD_OBJ(d, VpCreateRbObject(1, "NaN"));
+    GUARD_OBJ(c, VpCreateRbObject(1, "NaN", true));
+    GUARD_OBJ(d, VpCreateRbObject(1, "NaN", true));
     *div = d;
     *mod = c;
     return Qtrue;
@@ -1588,17 +1606,17 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1606
     SAVE(b);
 
     mx = (a->MaxPrec + b->MaxPrec) *VpBaseFig();
-    GUARD_OBJ(c,   VpCreateRbObject(mx, "0"));
-    GUARD_OBJ(res, VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0"));
-    GUARD_OBJ(rr,  VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0"));
-    GUARD_OBJ(ff,  VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0"));
+    GUARD_OBJ(c,   VpCreateRbObject(mx, "0", true));
+    GUARD_OBJ(res, VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0", true));
+    GUARD_OBJ(rr,  VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0", true));
+    GUARD_OBJ(ff,  VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0", true));
 
     VpDivd(c, res, a, b);
 
     mx = c->Prec *(VpBaseFig() + 1);
 
-    GUARD_OBJ(d, VpCreateRbObject(mx, "0"));
-    GUARD_OBJ(f, VpCreateRbObject(mx, "0"));
+    GUARD_OBJ(d, VpCreateRbObj (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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