Merge mpnumber malloc's into python mpw object malloc.
authorjbj <devnull@localhost>
Fri, 9 May 2003 22:01:59 +0000 (22:01 +0000)
committerjbj <devnull@localhost>
Fri, 9 May 2003 22:01:59 +0000 (22:01 +0000)
CVS patchset: 6828
CVS date: 2003/05/09 22:01:59

python/rpmdebug-py.c
python/rpmmpw-py.c
python/rpmmpw-py.h
python/rpmrng-py.c

index 8d1d9c2..b08148c 100644 (file)
@@ -33,11 +33,14 @@ static const char * lbl(void * s)
 
     if (o->ob_type == &PyType_Type)    return o->ob_type->tp_name;
 
+    if (o->ob_type == &PyBaseObject_Type)      return "BaseObj";
     if (o->ob_type == &PyBuffer_Type)  return "Buffer";
     if (o->ob_type == &PyCFunction_Type)       return "CFunction";
     if (o->ob_type == &PyCObject_Type) return "CObject";
     if (o->ob_type == &PyCell_Type)    return "Cell";
     if (o->ob_type == &PyClass_Type)   return "Class";
+    if (o->ob_type == &PyClassMethod_Type)     return "ClassMethod";
+    if (o->ob_type == &PyStaticMethod_Type)    return "StaticMethod";
     if (o->ob_type == &PyCode_Type)    return "Code";
     if (o->ob_type == &PyComplex_Type) return "Complex";
     if (o->ob_type == &PyDict_Type)    return "Dict";
@@ -51,11 +54,15 @@ static const char * lbl(void * s)
     if (o->ob_type == &PyList_Type)    return "List";
     if (o->ob_type == &PyLong_Type)    return "Long";
     if (o->ob_type == &PyMethod_Type)  return "Method";
+    if (o->ob_type == &PyWrapperDescr_Type)    return "WrapperDescr";
+    if (o->ob_type == &PyProperty_Type)        return "Property";
     if (o->ob_type == &PyModule_Type)  return "Module";
     if (o->ob_type == &PyRange_Type)   return "Range";
     if (o->ob_type == &PySeqIter_Type) return "SeqIter";
+    if (o->ob_type == &PyCallIter_Type)        return "CallIter";
     if (o->ob_type == &PySlice_Type)   return "Slice";
     if (o->ob_type == &PyString_Type)  return "String";
+    if (o->ob_type == &PySuper_Type)   return "Super";
     if (o->ob_type == &PyTuple_Type)   return "Tuple";
     if (o->ob_type == &PyType_Type)    return "Type";
     if (o->ob_type == &PyUnicode_Type) return "Unicode";
index c6dd86b..b323f74 100644 (file)
 #define        BITS_TO_DIGITS(_b)      (((_b) + SHIFT - 1)/SHIFT)
 #define        DIGITS_TO_BITS(_d)      ((_d) * SHIFT)
 
-#define        MP_ROUND_B2W(_b)        MP_BITS_TO_WORDS((_b) + MP_WBITS - 1)
-
-#define        MPW_SIZE(_a)    (_a)->n.size
-#define        MPW_DATA(_a)    (_a)->n.data
-
 /*@unchecked@*/
 static int _ie = 0x44332211;
 /*@unchecked@*/
@@ -450,7 +445,7 @@ mpw_format(mpwObject * z, size_t base, int addL)
     char * tcp = prefix;
     int sign;
 
-    if (z == NULL || !is_mpw(z)) {
+    if (z == NULL || !mpw_Check(z)) {
        PyErr_BadInternalCall();
        return NULL;
     }
@@ -824,14 +819,153 @@ fprintf(stderr, "*** pbits %d xbits %d nsize %d size %d\n", pbits, xbits, nsize,
 
 /* ---------- */
 
+mpwObject *
+mpw_New(int ob_size)
+       /*@*/
+{
+    size_t size = ABS(ob_size);
+    mpwObject * z = PyObject_NEW_VAR(mpwObject, &mpw_Type, size);
+
+    if (z == NULL)
+       return NULL;
+
+    z->ob_size = ob_size;
+
+    if (size > 0)
+       memset(&z->data, 0, size * sizeof(*z->data));
+
+    return z;
+}
+
+static mpwObject *
+mpw_FromLong(long ival)
+       /*@*/
+{
+    mpwObject * z = mpw_New(1);
+
+    if (z == NULL)
+       return NULL;
+
+    if (ival >= 0) {
+       z->data[0] = (mpw) ival;
+    } else {
+       z->ob_size = -z->ob_size;
+       z->data[0] = (mpw) -ival;
+    }
+
+    return z;
+}
+
+static mpwObject *
+mpw_FromUnsignedLong(unsigned long ival)
+       /*@*/
+{
+    mpwObject * z = mpw_New(1);
+
+    if (z == NULL)
+       return NULL;
+
+    z->data[0] = (mpw) ival;
+
+    return z;
+}
+
+static mpwObject *
+mpw_FromDouble(double dval)
+{
+    mpwObject * z = mpw_New(1);
+
+    if (z == NULL)
+       return NULL;
+
+    z->data[0] = (mpw) dval;
+
+    return z;
+}
+
+static mpwObject *
+mpw_FromHEX(const char * hex)
+       /*@*/
+{
+    size_t len = strlen(hex);
+    size_t size = MP_NIBBLES_TO_WORDS(len + MP_WNIBBLES - 1);
+    mpwObject * z = mpw_New(size);
+
+    if (z != NULL && size > 0)
+       hs2ip(MPW_DATA(z), size, hex, len);
+
+    return z;
+}
+
+mpwObject *
+mpw_FromMPW(size_t size, mpw* data)
+{
+    mpwObject * z = mpw_New(size);
+
+    if (z == NULL)
+       return NULL;
+
+    if (size > 0)
+       memcpy(&z->data, data, size * sizeof(*z->data));
+
+    return z;
+}
+
+static mpwObject *
+mpw_FromLongObject(PyLongObject *lo)
+       /*@*/
+{
+    mpwObject * z;
+    int lsize = ABS(lo->ob_size);
+    int lbits = DIGITS_TO_BITS(lsize);
+    size_t zsize = MP_BITS_TO_WORDS(lbits) + 1;
+    mpw* zdata;
+    unsigned char * zb;
+    size_t nzb;
+    int is_littleendian = 0;
+    int is_signed = 1;
+
+    z = mpw_New(zsize);
+    if (z == NULL)
+       return NULL;
+
+    zdata = MPW_DATA(z);
+    zb = (unsigned char *) zdata;
+    nzb = MP_WORDS_TO_BYTES(zsize);
+
+    /* Grab long as big-endian signed octets. */
+    if (_PyLong_AsByteArray(lo, zb, nzb, is_littleendian, is_signed)) {
+       Py_DECREF(z);
+       return NULL;
+    }
+
+    /* Endian swap zdata's mpw elements. */
+    if (IS_LITTLE_ENDIAN()) {
+       mpw w = 0;
+       int zx = 0;
+       while (nzb) {
+           w <<= 8;
+           w |= *zb++;
+           nzb--;
+           if ((nzb % MP_WBYTES) == 0) {
+               zdata[zx++] = w;
+               w = 0;
+           }
+       }
+    }
+
+    return z;
+}
+
+/* ---------- */
+
 static void
 mpw_dealloc(mpwObject * s)
        /*@modifies s @*/
 {
 if (_mpw_debug < -1)
-fprintf(stderr, "*** mpw_dealloc(%p)\n", s);
+fprintf(stderr, "*** mpw_dealloc(%p[%s])\n", s, lbl(s));
 
-    mpnfree(&s->n);
     PyObject_Del(s);
 }
 
@@ -879,6 +1013,7 @@ fprintf(stderr, "*** mpw_str(%p): \"%s\"\n", a, PyString_AS_STRING(so));
     return so;
 }
 
+#ifdef DYING
 /** \ingroup py_c
  */
 static int mpw_init(mpwObject * z, PyObject *args, PyObject *kwds)
@@ -933,7 +1068,7 @@ static int mpw_init(mpwObject * z, PyObject *args, PyObject *kwds)
        const unsigned char * hex = PyString_AsString(o);
        /* XXX TODO: check for hex. */
        mpnsethex(&z->n, hex);
-    } else if (is_mpw(o)) {
+    } else if (mpw_Check(o)) {
        mpwObject *a = (mpwObject *)o;
        mpncopy(&z->n, &a->n);
     } else {
@@ -946,6 +1081,7 @@ fprintf(stderr, "*** mpw_init(%p[%s],%p[%s],%p[%s]):\t", z, lbl(z), args, lbl(ar
 
     return 0;
 }
+#endif
 
 /** \ingroup py_c
  */
@@ -954,72 +1090,81 @@ static void mpw_free(/*@only@*/ mpwObject * s)
 {
 if (_mpw_debug)
 fprintf(stderr, "*** mpw_free(%p[%s])\n", s, lbl(s));
-    mpnfree(&s->n);
     PyObject_Del(s);
 }
 
 /** \ingroup py_c
- */
-static PyObject * mpw_alloc(PyTypeObject * subtype, int nitems)
-       /*@*/
-{
-    PyObject * ns = PyType_GenericAlloc(subtype, nitems);
-
-if (_mpw_debug)
-fprintf(stderr, "*** mpw_alloc(%p[%s},%d) ret %p[%s]\n", subtype, lbl(subtype), nitems, ns, lbl(ns));
-    return (PyObject *) ns;
-}
-
-static PyObject *
-mpw_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
-       /*@*/
-{
-    PyObject * ns = (PyObject *) PyObject_New(mpwObject, &mpw_Type);
-
-    if (ns != NULL)
-       mpnzero(&((mpwObject *)ns)->n);
-
-if (_mpw_debug < -1)
-fprintf(stderr, "*** mpw_new(%p[%s],%p[%s],%p[%s]) ret %p[%s]\n", subtype, lbl(subtype), args, lbl(args), kwds, lbl(kwds), ns, lbl(ns));
-
-    return ns;
-}
-
-mpwObject * mpw_New(void)
-       /*@*/
-{
-    mpwObject * ns = PyObject_New(mpwObject, &mpw_Type);
-
-    mpnzero(&ns->n);
-    return ns;
-}
-
-/** \ingroup py_c
  * Convert integer to mpw.
  */
 static mpwObject *
 mpw_i2mpw(PyObject * o)
        /*@modifies o @*/
 {
-    if (is_mpw(o)) {
+    if (mpw_Check(o)) {
        Py_INCREF(o);
        return (mpwObject *)o;
     }
-    if (PyInt_Check(o) || PyLong_Check(o)) {
-       mpwObject * ns = PyObject_New(mpwObject, &mpw_Type);
-       PyObject * args = PyTuple_New(1);
-
-       mpnzero(&((mpwObject *)ns)->n);
-       (void) PyTuple_SetItem(args, 0, o);
-       mpw_init(ns, args, NULL);
-       Py_DECREF(args);
-       return ns;
-    }
+    if (PyInt_Check(o))
+       return mpw_FromLong(PyInt_AsLong(o));
+    else if (PyLong_Check(o))
+       return mpw_FromLongObject((PyLongObject *)o);
+    else if (PyFloat_Check(o))
+       return mpw_FromDouble(PyFloat_AsDouble(o));
+    else if (PyString_Check(o))
+       return mpw_FromHEX(PyString_AS_STRING(o));
 
     PyErr_SetString(PyExc_TypeError, "number coercion (to mpwObject) failed");
     return NULL;
 }
 
+static PyObject *
+mpw_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+       /*@*/
+{
+    mpwObject *z;
+
+    if (type != &mpw_Type) {
+       mpwObject *tz;
+       size_t size;
+
+       assert(PyType_IsSubtype(type, &mpw_Type));
+       tz = (mpwObject *)mpw_new(&mpw_Type, args, kwds);
+       if (tz == NULL)
+           return NULL;
+
+       size = ABS(tz->ob_size);
+       z = (mpwObject *) type->tp_alloc(type, size);
+       if (z == NULL)
+           return NULL;
+
+       z->ob_size = tz->ob_size;
+       if (size > 0)
+           memcpy(&z->data, &tz->data, size * sizeof(*z->data));
+       Py_DECREF(tz);
+    } else {
+       PyObject * x = NULL;
+       int base = -909;
+       static char *kwlist[] = {"x", "base", 0};
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:mpw", kwlist, &x, &base))
+           return NULL;
+
+       if (x != NULL) {
+           if (mpw_Check(x)) {
+               z = (mpwObject *)x;
+               z = mpw_FromMPW(MPW_SIZE(z), MPW_DATA(z));
+           } else
+               z = mpw_i2mpw(x);
+       } else
+           z = mpw_FromLong(0);
+    }
+
+if (_mpw_debug < -1)
+fprintf(stderr, "*** mpw_new(%p[%s],%p[%s],%p[%s])\t", type, lbl(type), args, lbl(args), kwds, lbl(kwds)), mpfprintln(stderr, MPW_SIZE(z), MPW_DATA(z));
+
+    return (PyObject *)z;
+}
+
 /** \ingroup py_c
  * Compute 1 argument operations.
  */
@@ -1027,30 +1172,29 @@ static PyObject *
 mpw_ops1(const char *fname, char op, mpwObject *x)
         /*@*/
 {
-    size_t xsize = MPW_SIZE(x);
-    mpw* xdata = MPW_DATA(x);
-    mpwObject * z = mpw_New();
-    mpbarrett b;
+    mpwObject * z = NULL;
+    size_t xsize;
+    mpw* xdata;
 
-    mpbzero(&b);
-    if (x == NULL || z == NULL)
+    if (x == NULL)
        goto exit;
 
+    xsize = MPW_SIZE(x);
+    xdata = MPW_DATA(x);
+
 if (_mpw_debug < 0)
 prtmpw("a", x);
 
     switch (op) {
     default:
-       Py_DECREF(z);
-       z = NULL;
        goto exit;
        /*@notreached@*/ break;
     case '~':
-       mpninit(&z->n, xsize, xdata);
+       z = mpw_FromMPW(xsize, xdata);
        mpnot(MPW_SIZE(z), MPW_DATA(z));
        break;
     case '-':
-       mpninit(&z->n, xsize, xdata);
+       z = mpw_FromMPW(xsize, xdata);
        mpneg(MPW_SIZE(z), MPW_DATA(z));
        break;
     }
@@ -1059,7 +1203,6 @@ if (_mpw_debug < 0)
 fprintf(stderr, "*** mpw_%s %p[%d]\t", fname, MPW_DATA(z), MPW_SIZE(z)), mpfprintln(stderr, MPW_SIZE(z), MPW_DATA(z));
 
 exit:
-    mpbfree(&b);
     Py_XDECREF(x);
     return (PyObject *)z;
 }
@@ -1071,19 +1214,24 @@ static PyObject *
 mpw_ops2(const char *fname, char op, mpwObject *x, mpwObject *m)
         /*@*/
 {
-    size_t xsize = MPW_SIZE(x);
-    mpw* xdata = MPW_DATA(x);
-    size_t msize = MPW_SIZE(m);
-    mpw* mdata = MPW_DATA(m);
-    mpwObject * z = mpw_New();
+    mpwObject * z = NULL;
+    size_t xsize;
+    mpw* xdata;
+    size_t msize;
+    mpw* mdata;
     mpbarrett b;
     mpw* wksp;
     int carry;
 
     mpbzero(&b);
-    if (x == NULL || m == NULL || z == NULL)
+    if (x == NULL || m == NULL)
        goto exit;
 
+    xsize = MPW_SIZE(x);
+    xdata = MPW_DATA(x);
+    msize = MPW_SIZE(m);
+    mdata = MPW_DATA(m);
+
 if (_mpw_debug < 0) {
 prtmpw("a", x);
 prtmpw("b", m);
@@ -1091,16 +1239,14 @@ prtmpw("b", m);
 
     switch (op) {
     default:
-       Py_DECREF(z);
-       z = NULL;
        goto exit;
        /*@notreached@*/ break;
     case '+':
-       mpninit(&z->n, xsize, xdata);
+       z = mpw_FromMPW(xsize, xdata);
        carry = mpaddx(MPW_SIZE(z), MPW_DATA(z), msize, mdata);
        break;
     case '-':
-       mpninit(&z->n, xsize, xdata);
+       z = mpw_FromMPW(xsize, xdata);
        carry = mpsubx(MPW_SIZE(z), MPW_DATA(z), msize, mdata);
        break;
     case '*':
@@ -1112,7 +1258,7 @@ prtmpw("b", m);
        znorm = zsize - MP_ROUND_B2W(mpbitcnt(zsize, zdata));
        zsize -= znorm;
        zdata += znorm;
-       mpnset(&z->n, zsize, zdata);
+       z = mpw_FromMPW(zsize, zdata);
     }  break;
     case '/':
     {  size_t asize = xsize;
@@ -1147,7 +1293,7 @@ prtmpw("b", m);
            zdata += znorm;
        }
 
-       mpnset(&z->n, zsize, zdata);
+       z = mpw_FromMPW(zsize, zdata);
     }  break;
     case '%':
     {  size_t bsize = msize;
@@ -1163,7 +1309,7 @@ prtmpw("b", m);
        wksp = alloca((bsize+1) * sizeof(*wksp));
 
        mpnmod(zdata, xsize, xdata, bsize, bdata, wksp);
-       mpnset(&z->n, zsize, zdata);
+       z = mpw_FromMPW(zsize, zdata);
     }  break;
     case '<':
     {  size_t bnorm = msize - MP_ROUND_B2W(mpbitcnt(msize, mdata));
@@ -1173,7 +1319,7 @@ prtmpw("b", m);
 
        if (bsize == 1)
            count = bdata[0];
-       mpninit(&z->n, xsize, xdata);
+       z = mpw_FromMPW(xsize, xdata);
        mplshift(MPW_SIZE(z), MPW_DATA(z), count);
     }  break;
     case '>':
@@ -1184,33 +1330,33 @@ prtmpw("b", m);
 
        if (bsize == 1)
            count = bdata[0];
-       mpninit(&z->n, xsize, xdata);
+       z = mpw_FromMPW(xsize, xdata);
        mprshift(MPW_SIZE(z), MPW_DATA(z), count);
     }  break;
     case '&':
        if (xsize <= msize) {
-           mpninit(&z->n, xsize, xdata);
+           z = mpw_FromMPW(xsize, xdata);
            mpand(MPW_SIZE(z), MPW_DATA(z), mdata + (msize - xsize));
        } else {
-           mpninit(&z->n, msize, mdata);
+           z = mpw_FromMPW(msize, mdata);
            mpand(MPW_SIZE(z), MPW_DATA(z), xdata + (xsize - msize));
        }
        break;
     case '|':
        if (xsize <= msize) {
-           mpninit(&z->n, xsize, xdata);
+           z = mpw_FromMPW(xsize, xdata);
            mpor(MPW_SIZE(z), MPW_DATA(z), mdata + (msize - xsize));
        } else {
-           mpninit(&z->n, msize, mdata);
+           z = mpw_FromMPW(msize, mdata);
            mpor(MPW_SIZE(z), MPW_DATA(z), xdata + (xsize - msize));
        }
        break;
     case '^':
        if (xsize <= msize) {
-           mpninit(&z->n, xsize, xdata);
+           z = mpw_FromMPW(xsize, xdata);
            mpxor(MPW_SIZE(z), MPW_DATA(z), mdata + (msize - xsize));
        } else {
-           mpninit(&z->n, msize, mdata);
+           z = mpw_FromMPW(msize, mdata);
            mpxor(MPW_SIZE(z), MPW_DATA(z), xdata + (xsize - msize));
        }
        break;
@@ -1218,30 +1364,35 @@ prtmpw("b", m);
     {  size_t bnorm = msize - MP_ROUND_B2W(mpbitcnt(msize, mdata));
        size_t bsize = msize - bnorm;
        mpw* bdata = mdata + bnorm;
-       mpnpow_w(&z->n, xsize, xdata, bsize, bdata);
+       mpnumber zn;
+
+       mpnzero(&zn);
+       mpnpow_w(&zn, xsize, xdata, bsize, bdata);
+       z = mpw_FromMPW(zn.size, zn.data);
+       mpnfree(&zn);
     }  break;
     case 'G':
        wksp = alloca((xsize) * sizeof(*wksp));
-       mpnsize(&z->n, msize);
+       z = mpw_New(msize);
        mpgcd_w(xsize, xdata, mdata, MPW_DATA(z), wksp);
        break;
     case 'I':
        wksp = alloca(6*(msize+1)*sizeof(*wksp));
        mpbset(&b, msize, mdata);
-       mpnsize(&z->n, msize);
+       z = mpw_New(msize);
        mpbinv_w(&b, xsize, xdata, MPW_DATA(z), wksp);
        break;
     case 'R':
     {  rngObject * r = ((rngObject *)x);
        wksp = alloca(msize*sizeof(*wksp));
        mpbset(&b, msize, mdata);
-       mpnsize(&z->n, msize);
+       z = mpw_New(msize);
        mpbrnd_w(&b, &r->rngc, MPW_DATA(z), wksp);
     }  break;
     case 'S':
        wksp = alloca((4*msize+2)*sizeof(*wksp));
        mpbset(&b, msize, mdata);
-       mpnsize(&z->n, msize);
+       z = mpw_New(msize);
        mpbsqrmod_w(&b, xsize, xdata, MPW_DATA(z), wksp);
        break;
     }
@@ -1264,20 +1415,20 @@ mpw_ops3(const char *fname, char op,
                mpwObject *x, mpwObject *y, mpwObject *m)
         /*@*/
 {
-    size_t xsize = MPW_SIZE(x);
-    mpw* xdata = MPW_DATA(x);
-    size_t ysize = MPW_SIZE(y);
-    mpw* ydata = MPW_DATA(y);
-    size_t msize = MPW_SIZE(m);
-    mpw* mdata = MPW_DATA(m);
-    mpwObject * z = mpw_New();
-    mpbarrett b;
+    mpwObject * z = NULL;
+    size_t xsize;
+    mpw* xdata;
+    size_t ysize;
+    mpw* ydata;
+    size_t msize;
+    mpw* mdata;
     size_t zsize;
     mpw* zdata;
+    mpbarrett b;
     mpw* wksp;
 
     mpbzero(&b);
-    if (x == NULL || y == NULL || m == NULL || z == NULL)
+    if (x == NULL || y == NULL || m == NULL)
        goto exit;
 
 if (_mpw_debug < 0) {
@@ -1286,6 +1437,13 @@ prtmpw("b", y);
 prtmpw("c", m);
 }
 
+    xsize = MPW_SIZE(x);
+    xdata = MPW_DATA(x);
+    ysize = MPW_SIZE(y);
+    ydata = MPW_DATA(y);
+    msize = MPW_SIZE(m);
+    mdata = MPW_DATA(m);
+
     mpbset(&b, msize, mdata);
 
     zsize = b.size;
@@ -1296,8 +1454,6 @@ prtmpw("c", m);
     case '/':
     case '%':
     default:
-       Py_DECREF(z);
-       z = NULL;
        goto exit;
        /*@notreached@*/ break;
     case '+':
@@ -1318,7 +1474,7 @@ prtmpw("c", m);
        break;
     }
 
-    mpnset(&z->n, zsize, zdata);
+    z = mpw_FromMPW(zsize, zdata);
 
 if (_mpw_debug < 0)
 fprintf(stderr, "*** mpw_%s %p[%d]\t", fname, MPW_DATA(z), MPW_SIZE(z)), mpfprintln(stderr, MPW_SIZE(z), MPW_DATA(z));
@@ -1567,15 +1723,6 @@ mpw_divmod(mpwObject * a, mpwObject * b)
        return NULL;
     }
 
-    if ((z = PyTuple_New(2)) == NULL
-     || (q = mpw_New()) == NULL
-     || (r = mpw_New()) == NULL) {
-       Py_XDECREF(z);
-       Py_XDECREF(q);
-       Py_XDECREF(r);
-       return NULL;
-    }
-
     if (anorm < asize) {
        asize -= anorm;
        adata += anorm;
@@ -1597,7 +1744,9 @@ fprintf(stderr, "    z %p[%d]:\t", zdata, zsize), mpfprintln(stderr, zsize, zdat
 }
 
     zsize -= bsize;
-    mpnset(&r->n, bsize, zdata+zsize);
+    r = mpw_FromMPW(bsize, zdata+zsize);
+    if (r == NULL)
+       return NULL;
 
     znorm = mpsize(zsize, zdata);
     znorm--;   /* XXX hack to preserve positive integer. */
@@ -1605,16 +1754,26 @@ fprintf(stderr, "    z %p[%d]:\t", zdata, zsize), mpfprintln(stderr, zsize, zdat
        zsize -= znorm;
        zdata += znorm;
     }
-    mpnset(&q->n, zsize, zdata);
+    q = mpw_FromMPW(zsize, zdata);
+    if (q == NULL) {
+       Py_DECREF(r);
+       return NULL;
+    }
 
 if (_mpw_debug) {
 prtmpw("q", q);
 prtmpw("r", r);
 fprintf(stderr, "*** mpw_divmod(%p,%p)\n", a, b);
 }
+    if ((z = PyTuple_New(2)) == NULL) {
+       Py_DECREF(q);
+       Py_DECREF(r);
+       return NULL;
+    }
 
     (void) PyTuple_SetItem(z, 0, (PyObject *)q);
     (void) PyTuple_SetItem(z, 1, (PyObject *)r);
+
     return (PyObject *)z;
 }
 
@@ -1665,10 +1824,11 @@ mpw_absolute(mpwObject * a)
        return (PyObject *)a;
     }
 
-    if ((z = mpw_New()) != NULL) {
-       mpninit(&z->n, asize, adata);
-       mpneg(MPW_SIZE(z), MPW_DATA(z));
-    }
+    z = mpw_FromMPW(asize, adata);
+    if (z == NULL)
+       return NULL;
+
+    mpneg(MPW_SIZE(z), MPW_DATA(z));
 
 if (_mpw_debug)
 fprintf(stderr, "*** mpw_absolute(%p):\t", a), mpfprintln(stderr, MPW_SIZE(z), MPW_DATA(z));
@@ -1737,47 +1897,25 @@ static int
 mpw_coerce(PyObject ** pv, PyObject ** pw)
        /*@modifies *pv, *pw @*/
 {
-    size_t words = 0;
-    long l = 0;
 
 if (_mpw_debug)
 fprintf(stderr, "*** mpw_coerce(%p[%s],%p[%s])\n", pv, lbl(*pv), pw, lbl(*pw));
 
-    if (is_mpw(*pw)) {
+    if (mpw_Check(*pw))
        Py_INCREF(*pw);
-    } else if (PyInt_Check(*pw)) {
-       l = PyInt_AsLong(*pw);
-       words = sizeof(l)/sizeof(words);
-    } else if (PyLong_Check(*pw)) {
-       l = PyLong_AsLong(*pw);
-       words = sizeof(l)/sizeof(words);
-    } else if (PyFloat_Check(*pw)) {
-       double d = PyFloat_AsDouble(*pw);
-       /* XXX TODO: check for overflow/underflow. */
-       l = (long) (d + 0.5);
-       words = sizeof(l)/sizeof(words);
-    } else {
+    else if (PyInt_Check(*pw))
+       *pw = (PyObject *) mpw_FromLong(PyInt_AsLong(*pw));
+    else if (PyLong_Check(*pw))
+       *pw = (PyObject *) mpw_FromLongObject((PyLongObject *)(*pw));
+    else if (PyFloat_Check(*pw))
+       *pw = (PyObject *) mpw_FromDouble(PyFloat_AsDouble(*pw));
+    else if (PyString_Check(*pw))
+       *pw = (PyObject *) mpw_FromHEX(PyString_AS_STRING(*pw));
+    else {
        PyErr_SetString(PyExc_TypeError, "non-numeric coercion failed (mpw_coerce)");
        return 1;
     }
 
-    if (words > 0) {
-       mpwObject * z = mpw_New();
-       mpnsize(&z->n, words);
-       switch (words) {
-       case 2:
-/*@-shiftimplementation @*/
-           z->n.data[0] = (l >> 32) & 0xffffffff;
-/*@=shiftimplementation @*/
-           z->n.data[1] = (l      ) & 0xffffffff;
-           break;
-       case 1:
-           z->n.data[0] = (l      ) & 0xffffffff;
-           break;
-       }
-       (*pw) = (PyObject *) z;
-    }
-
     Py_INCREF(*pv);
     return 0;
 }
@@ -1938,7 +2076,7 @@ PyTypeObject mpw_Type = {
        0,                              /* ob_size */
        "rpm.mpw",                      /* tp_name */
        sizeof(mpwObject) - sizeof(mpw),/* tp_basicsize */
-       0,                              /* tp_itemsize */
+       sizeof(mpw),                    /* tp_itemsize */
        /* methods */
        (destructor) mpw_dealloc,       /* tp_dealloc */
        0,                              /* tp_print */
@@ -1955,29 +2093,28 @@ PyTypeObject mpw_Type = {
        (getattrofunc) mpw_getattro,    /* tp_getattro */
        (setattrofunc) mpw_setattro,    /* tp_setattro */
        0,                              /* tp_as_buffer */
-       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,               /* tp_flags */
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+               Py_TPFLAGS_BASETYPE,    /* tp_flags */
        mpw_doc,                        /* tp_doc */
-#if Py_TPFLAGS_HAVE_ITER
-       (traverseproc)0,                /* tp_traverse */
-       (inquiry)0,                     /* tp_clear */
-       (richcmpfunc)0,                 /* tp_richcompare */
+       0,                              /* tp_traverse */
+       0,                              /* tp_clear */
+       0,                              /* tp_richcompare */
        0,                              /* tp_weaklistoffset */
-       (getiterfunc)0,                 /* tp_iter */
-       (iternextfunc)0,                /* tp_iternext */
+       0,                              /* tp_iter */
+       0,                              /* tp_iternext */
        mpw_methods,                    /* tp_methods */
        0,                              /* tp_members */
        0,                              /* tp_getset */
        0,                              /* tp_base */
-       (PyObject *)0,                  /* tp_dict */
-       (descrgetfunc)0,                /* tp_descr_get */
-       (descrsetfunc)0,                /* tp_descr_set */
+       0,                              /* tp_dict */
+       0,                              /* tp_descr_get */
+       0,                              /* tp_descr_set */
        0,                              /* tp_dictoffset */
-       (initproc) mpw_init,            /* tp_init */
-       (allocfunc) mpw_alloc,          /* tp_alloc */
+       0,                              /* tp_init */
+       0,                              /* tp_alloc */
        (newfunc) mpw_new,              /* tp_new */
        (destructor) mpw_free,          /* tp_free */
-       (inquiry) 0,                    /* tp_is_gc */
-#endif
+       0,                              /* tp_is_gc */
 };
 /*@=fullinitblock@*/
 
index acb7b25..57216b7 100644 (file)
@@ -11,8 +11,7 @@
  */
 typedef struct mpwObject_s {
     PyObject_HEAD
-    PyObject *md_dict;         /*!< to look like PyModuleObject */
-    mpnumber n;
+    int ob_size;
     mpw data[1];
 } mpwObject;
 
@@ -21,11 +20,22 @@ typedef struct mpwObject_s {
 /*@unchecked@*/
 extern PyTypeObject mpw_Type;
 
-#define is_mpw(o)      ((o)->ob_type == &mpw_Type)
+#define        mpw_Check(_o)           PyObject_TypeCheck((_o), &mpw_Type)
+#define mpw_CheckExact(_o)     ((_o)->ob_type == &mpw_Type)
+
+#define        MP_ROUND_B2W(_b)        MP_BITS_TO_WORDS((_b) + MP_WBITS - 1)
+
+#define        MPW_SIZE(_a)    (size_t)((_a)->ob_size < 0 ? -(_a)->ob_size : (_a)->ob_size)
+#define        MPW_DATA(_a)    ((_a)->data)
+
+/**
+ */
+mpwObject * mpw_New(int ob_size)
+       /*@*/;
 
 /**
  */
-mpwObject * mpw_New(void)
+mpwObject * mpw_FromMPW(size_t size, mpw* data)
        /*@*/;
 
 #endif
index 7c3f7b9..f5d1777 100644 (file)
@@ -156,10 +156,10 @@ rng_Seed(rngObject * s, PyObject * args)
 
     if (!PyArg_ParseTuple(args, "O:Seed", &o)) return NULL;
 
-    if (!is_mpw(o) || (z = (mpwObject*)o)->n.size > 0)
+    if (!mpw_Check(o) || MPW_SIZE(z = (mpwObject*)o) > 0)
        return NULL;
 
-    rc->rng->seed(rc->param, (byte*) z->n.data, z->n.size);
+    rc->rng->seed(rc->param, (byte*) MPW_DATA(z), MPW_SIZE(z));
 
 if (_rng_debug < 0)
 fprintf(stderr, "*** rng_Seed(%p)\n", s);
@@ -182,28 +182,26 @@ rng_Next(rngObject * s, PyObject * args)
     if (!PyArg_ParseTuple(args, "|O:Next", &o)) return NULL;
 
     if (o) {
-       if (is_mpw(o) && (z = (mpwObject*)o)->n.size > 0) {
+       if (mpw_Check(o) && MPW_SIZE(z = (mpwObject*)o) > 0) {
            b = alloca(sizeof(*b));
            mpbzero(b);
            /* XXX z probably needs normalization here. */
-           mpbset(b, z->n.size, z->n.data);
+           mpbset(b, MPW_SIZE(z), MPW_DATA(z));
        } else
            ;   /* XXX error? */
     }
 
-    z = mpw_New();
     if (b == NULL || b->size == 0 || b->modl == NULL) {
-       mpw val;
-       rc->rng->next(rc->param, (byte*) &val, sizeof(val));
-       mpnsetw(&z->n, val);
+       z = mpw_New(1);
+       rc->rng->next(rc->param, (byte*) MPW_DATA(z), sizeof(*MPW_DATA(z)));
     } else {
-       mpw* wksp = alloca(b->size*sizeof(*wksp));
-       mpnsize(&z->n, b->size);
-       mpbrnd_w(b, rc, z->n.data, wksp);
+       mpw* wksp = alloca(b->size * sizeof(*wksp));
+       z = mpw_New(b->size);
+       mpbrnd_w(b, rc, MPW_DATA(z), wksp);
     }
 
 if (_rng_debug)
-fprintf(stderr, "*** rng_Next(%p) %p[%d]\t", s, z->n.data, z->n.size), mpfprintln(stderr, z->n.size, z->n.data);
+fprintf(stderr, "*** rng_Next(%p) %p[%d]\t", s, MPW_DATA(z), MPW_SIZE(z)), mpfprintln(stderr, MPW_SIZE(z), MPW_DATA(z));
 
     return (PyObject *)z;
 }
@@ -218,28 +216,29 @@ rng_Prime(rngObject * s, PyObject * args)
     unsigned pbits = 160;
     int trials = -1;
     size_t psize;
+    mpbarrett* b;
+    mpw *temp;
     mpwObject *z;
 
     if (!PyArg_ParseTuple(args, "|ii:Prime", &pbits, &trials)) return NULL;
 
-    psize = MP_BITS_TO_WORDS(pbits + MP_WBITS - 1);
-    if((z = mpw_New()) != NULL) {
-       mpbarrett* b = alloca(sizeof(*b));
-       mpw *temp = alloca((8*psize+2) * sizeof(*temp));
+    psize = MP_ROUND_B2W(pbits);
+    temp = alloca((8*psize+2) * sizeof(*temp));
 
-       mpbzero(b);
-       if (trials <= 2)
-           trials = mpptrials(pbits);
+    b = alloca(sizeof(*b));
+    mpbzero(b);
+
+    if (trials <= 2)
+       trials = mpptrials(pbits);
 #if 1
-       mpprnd_w(b, rc, pbits, trials, (const mpnumber*) 0, temp);
+    mpprnd_w(b, rc, pbits, trials, (const mpnumber*) 0, temp);
 #else
-       mpprndsafe_w(b, rc, pbits, trials, temp);
+    mpprndsafe_w(b, rc, pbits, trials, temp);
 #endif
-       mpnset(&z->n, b->size, b->modl);
 
-if (_rng_debug)
-fprintf(stderr, "*** rng_Prime(%p) %p[%d]\t", s, z->n.data, z->n.size), mpfprintln(stderr, z->n.size, z->n.data);
-    }
+    z = mpw_FromMPW(b->size, b->modl);
+if (z != NULL && _rng_debug)
+fprintf(stderr, "*** rng_Prime(%p) %p[%d]\t", s, MPW_DATA(z), MPW_SIZE(z)), mpfprintln(stderr, MPW_SIZE(z), MPW_DATA(z));
 
     return (PyObject *)z;
 }