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

ruby-changes:22040

From: nobu <ko1@a...>
Date: Wed, 21 Dec 2011 12:35:40 +0900 (JST)
Subject: [ruby-changes:22040] nobu:r34089 (trunk): * ext/bigdecimal/bigdecimal.c (BigDecimal_s_allocate): follow

nobu	2011-12-21 12:35:27 +0900 (Wed, 21 Dec 2011)

  New Revision: 34089

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=34089

  Log:
    * ext/bigdecimal/bigdecimal.c (BigDecimal_s_allocate): follow
      Allocation Framework.  [Bug #5775]

  Modified files:
    trunk/ChangeLog
    trunk/ext/bigdecimal/bigdecimal.c
    trunk/ext/bigdecimal/bigdecimal.h
    trunk/test/bigdecimal/test_bigdecimal.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 34088)
+++ ChangeLog	(revision 34089)
@@ -1,3 +1,8 @@
+Wed Dec 21 12:35:24 2011  Nobuyoshi Nakada  <nobu@r...>
+
+	* ext/bigdecimal/bigdecimal.c (BigDecimal_s_allocate): follow
+	  Allocation Framework.  [Bug #5775]
+
 Wed Dec 21 02:25:36 2011  Aaron Patterson <aaron@t...>
 
 	* ext/psych/emitter.c: fixing clang warnings. Thanks Joey!
Index: ext/bigdecimal/bigdecimal.c
===================================================================
--- ext/bigdecimal/bigdecimal.c	(revision 34088)
+++ ext/bigdecimal/bigdecimal.c	(revision 34089)
@@ -131,7 +131,7 @@
 static void  VpSetException(unsigned short f);
 static void  VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v);
 static int   VpLimitRound(Real *c, size_t ixDigit);
-static Real *VpDup(Real const* const x);
+static Real *VpCopy(Real *pv, Real const* const x);
 
 /*
  *  **** BigDecimal part ****
@@ -561,15 +561,14 @@
 }
 
 #define VpAllocReal(prec) (Real *)VpMemAlloc(offsetof(Real, frac) + (prec) * sizeof(BDIGIT))
+#define VpReallocReal(ptr, prec) (Real *)VpMemRealloc((ptr), offsetof(Real, frac) + (prec) * sizeof(BDIGIT))
 
 static Real *
-VpDup(Real const* const x)
+VpCopy(Real *pv, Real const* const x)
 {
-    Real *pv;
-
     assert(x != NULL);
 
-    pv = VpAllocReal(x->MaxPrec);
+    pv = VpReallocReal(pv, x->MaxPrec);
     pv->MaxPrec = x->MaxPrec;
     pv->Prec = x->Prec;
     pv->exponent = x->exponent;
@@ -577,9 +576,6 @@
     pv->flag = x->flag;
     MEMCPY(pv->frac, x->frac, BDIGIT, pv->MaxPrec);
 
-    pv->obj = TypedData_Wrap_Struct(
-	rb_obj_class(x->obj), &BigDecimal_data_type, pv);
-
     return pv;
 }
 
@@ -2254,6 +2250,14 @@
     return BigDecimal_power(1, &exp, self);
 }
 
+static VALUE
+BigDecimal_s_allocate(VALUE klass)
+{
+    return VpNewRbClass(0, NULL, klass)->obj;
+}
+
+static Real *BigDecimal_new(int argc, VALUE *argv);
+
 /* call-seq:
  *   new(initial, digits)
  *
@@ -2272,10 +2276,36 @@
  * larger than the specified number.
  */
 static VALUE
-BigDecimal_new(int argc, VALUE *argv, VALUE self)
+BigDecimal_initialize(int argc, VALUE *argv, VALUE self)
 {
-    ENTER(5);
-    Real *pv;
+    Real *pv = rb_check_typeddata(self, &BigDecimal_data_type);
+    Real *x = BigDecimal_new(argc, argv);
+
+    if (ToValue(x)) {
+	pv = VpCopy(pv, x);
+    }
+    else {
+	VpFree(pv);
+	pv = x;
+    }
+    DATA_PTR(self) = pv;
+    pv->obj = self;
+    return self;
+}
+
+static VALUE
+BigDecimal_initialize_copy(VALUE self, VALUE other)
+{
+    Real *pv = rb_check_typeddata(self, &BigDecimal_data_type);
+    Real *x = rb_check_typeddata(other, &BigDecimal_data_type);
+
+    DATA_PTR(self) = VpCopy(pv, x);
+    return self;
+}
+
+static Real *
+BigDecimal_new(int argc, VALUE *argv)
+{
     size_t mf;
     VALUE  nFig;
     VALUE  iniValue;
@@ -2290,15 +2320,14 @@
     switch (TYPE(iniValue)) {
       case T_DATA:
 	if (is_kind_of_BigDecimal(iniValue)) {
-	    pv = VpDup(DATA_PTR(iniValue));
-	    return ToValue(pv);
+	    return DATA_PTR(iniValue);
 	}
 	break;
 
       case T_FIXNUM:
 	/* fall through */
       case T_BIGNUM:
-	return ToValue(GetVpValue(iniValue, 1));
+	return GetVpValue(iniValue, 1);
 
       case T_FLOAT:
 	if (mf > DBL_DIG+1) {
@@ -2309,23 +2338,25 @@
 	if (NIL_P(nFig)) {
 	    rb_raise(rb_eArgError, "can't omit precision for a Rational.");
 	}
-	return ToValue(GetVpValueWithPrec(iniValue, mf, 1));
+	return GetVpValueWithPrec(iniValue, mf, 1);
 
       case T_STRING:
 	/* fall through */
       default:
 	break;
     }
-    SafeStringValue(iniValue);
-    GUARD_OBJ(pv, VpNewRbClass(mf, RSTRING_PTR(iniValue),self));
-
-    return ToValue(pv);
+    StringValueCStr(iniValue);
+    rb_check_safe_obj(iniValue);
+    return VpAlloc(mf, RSTRING_PTR(iniValue));
 }
 
 static VALUE
 BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
 {
-    return BigDecimal_new(argc, argv, rb_cBigDecimal);
+    Real *pv = BigDecimal_new(argc, argv);
+    if (ToValue(pv)) pv = VpCopy(NULL, pv);
+    pv->obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, pv);
+    return pv->obj;
 }
 
  /* call-seq:
@@ -2830,16 +2861,12 @@
 
     /* Class and method registration */
     rb_cBigDecimal = rb_define_class("BigDecimal",rb_cNumeric);
-    rb_undef_alloc_func(rb_cBigDecimal); /* TODO: define alloc func */
+    rb_define_alloc_func(rb_cBigDecimal, BigDecimal_s_allocate);
 
     /* Global function */
     rb_define_global_function("BigDecimal", BigDecimal_global_new, -1);
 
     /* Class methods */
-#if 1
-    /* TODO: follow allocation framework */
-    rb_define_singleton_method(rb_cBigDecimal, "new", BigDecimal_new, -1);
-#endif
     rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1);
     rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
     rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
@@ -2963,6 +2990,8 @@
 
 
     /* instance methods */
+    rb_define_method(rb_cBigDecimal, "initialize", BigDecimal_initialize, -1);
+    rb_define_method(rb_cBigDecimal, "initialize_copy", BigDecimal_initialize_copy, 1);
     rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
 
     rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2);
@@ -3093,6 +3122,16 @@
     return p;
 }
 
+VP_EXPORT void *
+VpMemRealloc(void *ptr, size_t mb)
+{
+    void *p = xrealloc(ptr, mb);
+    if (!p) {
+        VpException(VP_EXCEPTION_MEMORY, "failed to allocate memory", 1);
+    }
+    return p;
+}
+
 VP_EXPORT void
 VpFree(Real *pv)
 {
Index: ext/bigdecimal/bigdecimal.h
===================================================================
--- ext/bigdecimal/bigdecimal.h	(revision 34088)
+++ ext/bigdecimal/bigdecimal.h	(revision 34089)
@@ -21,7 +21,10 @@
 
 #if defined(__cplusplus)
 extern "C" {
+#if 0
+}
 #endif
+#endif
 
 #ifndef HAVE_LABS
 static inline long
@@ -197,6 +200,7 @@
 VP_EXPORT size_t VpNumOfChars(Real *vp,const char *pszFmt);
 VP_EXPORT size_t VpInit(BDIGIT BaseVal);
 VP_EXPORT void *VpMemAlloc(size_t mb);
+VP_EXPORT void *VpMemRealloc(void *ptr, size_t mb);
 VP_EXPORT void VpFree(Real *pv);
 VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal);
 VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw);
@@ -279,6 +283,9 @@
 #endif /* BIGDECIMAL_DEBUG */
 
 #if defined(__cplusplus)
+#if 0
+{
+#endif
 }  /* extern "C" { */
 #endif
 #endif /* RUBY_BIG_DECIMAL_H */
Index: test/bigdecimal/test_bigdecimal.rb
===================================================================
--- test/bigdecimal/test_bigdecimal.rb	(revision 34088)
+++ test/bigdecimal/test_bigdecimal.rb	(revision 34089)
@@ -19,10 +19,6 @@
     [ BigDecimal::ROUND_FLOOR,     :floor],
   ]
 
-  def assert_allocate
-    assert_raise(TypeError) {BigDecimal.allocate}
-  end
-
   def assert_nan(x)
     assert(x.nan?, "Expected #{x.inspect} to be NaN")
   end
@@ -47,6 +43,10 @@
                  "Expected #{x.inspect} to be negative zero")
   end
 
+  def test_not_equal
+    assert_not_equal BigDecimal("1"), BigDecimal.allocate
+  end
+
   def test_global_new
     assert_equal(1, BigDecimal("1"))
     assert_equal(1, BigDecimal("1", 1))
@@ -1288,4 +1288,19 @@
       end
     end
   end
+
+  def test_dup
+    [1, -1, 2**100, -2**100].each do |i|
+      x = BigDecimal(i)
+      assert_equal(x, x.dup)
+    end
+  end
+
+  def test_dup_subclass
+    c = Class.new(BigDecimal)
+    x = c.new(1)
+    y = x.dup
+    assert_equal(1, y)
+    assert_kind_of(c, y)
+  end
 end

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

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