X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/91e56f0647ff205643debd5cdb93797ea0e8da24..7fefaba255cc71f03c36d868f11c957c8322b86a:/mp.c diff --git a/mp.c b/mp.c index 2fc82b2..b25fdce 100644 --- a/mp.c +++ b/mp.c @@ -33,6 +33,17 @@ PyTypeObject *mp_pytype = 0; PyTypeObject *gf_pytype = 0; +#ifndef PyLong_SHIFT +# define PyLong_SHIFT SHIFT +#endif + +#ifndef PyLong_MASK +# define PyLong_MASK MASK +#endif + +STATIC_ASSERT(MPW_BITS >= PyLong_SHIFT, + "Catacomb's limbs are now narrower than than Python's!"); + mp *mp_frompylong(PyObject *obj) { unsigned long bits; @@ -45,16 +56,15 @@ mp *mp_frompylong(PyObject *obj) mp *x; mpw *p; - sz = l->ob_size; + sz = Py_SIZE(l); if (sz < 0) sz = -sz; - assert(MPW_BITS >= SHIFT); - bits = (unsigned long)sz * SHIFT; + bits = (unsigned long)sz * PyLong_SHIFT; w = (bits + MPW_BITS - 1)/MPW_BITS; - x = mp_new(w, l->ob_size < 0 ? MP_NEG : 0); + x = mp_new(w, Py_SIZE(l) < 0 ? MP_NEG : 0); p = x->v; for (i = 0; i < sz; i++) { r |= (mpd)l->ob_digit[i] << b; - b += SHIFT; + b += PyLong_SHIFT; while (b >= MPW_BITS) { *p++ = MPW(r); r >>= MPW_BITS; @@ -73,28 +83,27 @@ mp *mp_frompylong(PyObject *obj) PyObject *mp_topylong(mp *x) { unsigned long bits = mp_bits(x); - int sz = (bits + SHIFT - 1)/SHIFT; + int sz = (bits + PyLong_SHIFT - 1)/PyLong_SHIFT; PyLongObject *l = _PyLong_New(sz); mpd r = 0; int b = 0; mpw *p = x->v; int i = 0; - assert(MPW_BITS >= SHIFT); while (i < sz && p < x->vl) { r |= (mpd)*p++ << b; b += MPW_BITS; - while (i < sz && b >= SHIFT) { - l->ob_digit[i++] = r & MASK; - r >>= SHIFT; - b -= SHIFT; + while (i < sz && b >= PyLong_SHIFT) { + l->ob_digit[i++] = r & PyLong_MASK; + r >>= PyLong_SHIFT; + b -= PyLong_SHIFT; } } while (i < sz && r) { - l->ob_digit[i++] = r & MASK; - r >>= SHIFT; + l->ob_digit[i++] = r & PyLong_MASK; + r >>= PyLong_SHIFT; } - l->ob_size = (x->f & MP_NEG) ? -sz : sz; + Py_SIZE(l) = (x->f & MP_NEG) ? -sz : sz; return ((PyObject *)l); } @@ -102,11 +111,11 @@ mp *mp_frompyobject(PyObject *o, int radix) { mp *x; - if (PyString_Check(o)) { + if (TEXT_CHECK(o)) { mptext_stringctx sc; mp *x; - sc.buf = PyString_AS_STRING(o); - sc.lim = sc.buf + PyString_GET_SIZE(o); + size_t sz; + TEXT_PTRLEN(o, sc.buf, sz); sc.lim = sc.buf + sz; x = mp_read(MP_NEW, radix, &mptext_stringops, &sc); if (!x) return (0); if (sc.buf < sc.lim) { MP_DROP(x); return (0); } @@ -128,8 +137,7 @@ PyObject *mp_topystring(mp *x, int radix, const char *xpre, size_t postlen = post ? strlen(post) : 0; char *p; MP_COPY(x); - o = PyString_FromStringAndSize(0, len + 1 + xprelen + prelen + postlen); - p = PyString_AS_STRING(o); + TEXT_PREPAREWRITE(o, p, len + 1 + xprelen + prelen + postlen); sc.buf = p; if (xpre) { memcpy(sc.buf, xpre, xprelen); sc.buf += xprelen; } if (MP_NEGP(x)) { *sc.buf++ = '-'; x = mp_neg(x, x); } @@ -138,7 +146,7 @@ PyObject *mp_topystring(mp *x, int radix, const char *xpre, mp_write(x, radix, &mptext_stringops, &sc); if (post) { memcpy(sc.buf, post, postlen); sc.buf += postlen; } MP_DROP(x); - _PyString_Resize(&o, sc.buf - p); + TEXT_DONEWRITE(o, sc.buf - p); return (o); } @@ -238,7 +246,7 @@ mp *getmp(PyObject *o) if (!o) return (0); if ((x = tomp(o)) == 0) { PyErr_Format(PyExc_TypeError, "can't convert %.100s to mp", - o->ob_type->tp_name); + Py_TYPE(o)->tp_name); } return (x); } @@ -257,7 +265,7 @@ mp *getgf(PyObject *o) if (!o) return (0); if ((x = tomp(o)) == 0) { PyErr_Format(PyExc_TypeError, "can't convert %.100s to gf", - o->ob_type->tp_name); + Py_TYPE(o)->tp_name); } return (x); } @@ -536,7 +544,7 @@ static PyObject *mp_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) if (!good_radix_p(radix, 1)) VALERR("bad radix"); if ((z = mp_frompyobject(x, radix)) == 0) { PyErr_Format(PyExc_TypeError, "can't convert %.100s to mp", - x->ob_type->tp_name); + Py_TYPE(x)->tp_name); goto end; } zz = (mp_pyobj *)ty->tp_alloc(ty, 0); @@ -545,14 +553,14 @@ end: return ((PyObject *)zz); } -long mphash(mp *x) +Py_hash_t mphash(mp *x) { PyObject *l = mp_topylong(x); - long h = PyObject_Hash(l); + Py_hash_t h = PyObject_Hash(l); Py_DECREF(l); return (h); } -static long mp_pyhash(PyObject *me) { return (mphash(MP_X(me))); } +static Py_hash_t mp_pyhash(PyObject *me) { return (mphash(MP_X(me))); } static PyObject *mpmeth_jacobi(PyObject *me, PyObject *arg) { @@ -709,7 +717,7 @@ end: if (!len) len = 1; \ } \ rc = bytestring_pywrap(0, len); \ - mp_##name(MP_X(me), PyString_AS_STRING(rc), len); \ + mp_##name(MP_X(me), BIN_PTR(rc), len); \ end: \ return (rc); \ } @@ -723,13 +731,12 @@ STOREOP(storeb2c, 2c) static PyObject *ty##meth_frombuf(PyObject *me, PyObject *arg) \ { \ buf b; \ - char *p; \ - Py_ssize_t sz; \ + struct bin in; \ PyObject *rc = 0; \ mp *x; \ \ - if (!PyArg_ParseTuple(arg, "s#:frombuf", &p, &sz)) goto end; \ - buf_init(&b, p, sz); \ + if (!PyArg_ParseTuple(arg, "O&:frombuf", convbin, &in)) goto end; \ + buf_init(&b, (/*unconst*/ void *)in.p, in.sz); \ if ((x = buf_getmp(&b)) == 0) VALERR("malformed data"); \ rc = Py_BuildValue("(NN)", ty##_pywrap(x), \ bytestring_pywrapbuf(&b)); \ @@ -750,10 +757,10 @@ static PyObject *mpmeth_tobuf(PyObject *me) x = MP_X(me); n = mp_octets(x) + 3; rc = bytestring_pywrap(0, n); - buf_init(&b, PyString_AS_STRING(rc), n); + buf_init(&b, BIN_PTR(rc), n); buf_putmp(&b, x); assert(BOK(&b)); - _PyString_Resize(&rc, BLEN(&b)); + BIN_SETLEN(rc, BLEN(&b)); return (rc); } @@ -815,10 +822,9 @@ static PyObject *mpmeth_fibonacci(PyObject *me, PyObject *arg) #define LOADOP(pre, name) \ static PyObject *pre##meth_##name(PyObject *me, PyObject *arg) \ { \ - char *p; \ - Py_ssize_t len; \ - if (!PyArg_ParseTuple(arg, "s#:" #name, &p, &len)) return (0); \ - return (pre##_pywrap(mp_##name(MP_NEW, p, len))); \ + struct bin in; \ + if (!PyArg_ParseTuple(arg, "O&:" #name, convbin, &in)) return (0); \ + return (pre##_pywrap(mp_##name(MP_NEW, in.p, in.sz))); \ } LOADOP(mp, loadl) LOADOP(mp, loadb) @@ -931,8 +937,8 @@ static const PyNumberMethods mp_pynumber = { 0, /* @nb_inplace_true_divide@ */ }; -static PyTypeObject mp_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject mp_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "MP", /* @tp_name@ */ sizeof(mp_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -995,6 +1001,8 @@ static PyTypeObject mp_pytype_skel = { /*----- Products of small integers ----------------------------------------*/ +static PyTypeObject *mpmul_pytype; + typedef struct mpmul_pyobj { PyObject_HEAD int livep; @@ -1088,8 +1096,8 @@ static const PyMethodDef mpmul_pymethods[] = { { 0 } }; -static PyTypeObject *mpmul_pytype, mpmul_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject mpmul_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "MPMul", /* @tp_name@ */ sizeof(mpmul_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1138,6 +1146,8 @@ static PyTypeObject *mpmul_pytype, mpmul_pytype_skel = { /*----- Montgomery reduction ----------------------------------------------*/ +static PyTypeObject *mpmont_pytype; + typedef struct mpmont_pyobj { PyObject_HEAD mpmont mm; @@ -1355,8 +1365,8 @@ static const PyMethodDef mpmont_pymethods[] = { { 0 } }; -static PyTypeObject *mpmont_pytype, mpmont_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject mpmont_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "MPMont", /* @tp_name@ */ sizeof(mpmont_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1405,6 +1415,8 @@ static PyTypeObject *mpmont_pytype, mpmont_pytype_skel = { /*----- Barrett reduction -------------------------------------------------*/ +static PyTypeObject *mpbarrett_pytype; + typedef struct mpbarrett_pyobj { PyObject_HEAD mpbarrett mb; @@ -1494,8 +1506,8 @@ static const PyMethodDef mpbarrett_pymethods[] = { { 0 } }; -static PyTypeObject *mpbarrett_pytype, mpbarrett_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject mpbarrett_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "MPBarrett", /* @tp_name@ */ sizeof(mpbarrett_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1544,6 +1556,8 @@ static PyTypeObject *mpbarrett_pytype, mpbarrett_pytype_skel = { /*----- Nice prime reduction ----------------------------------------------*/ +static PyTypeObject *mpreduce_pytype; + typedef struct mpreduce_pyobj { PyObject_HEAD mpreduce mr; @@ -1622,8 +1636,8 @@ static const const PyMethodDef mpreduce_pymethods[] = { { 0 } }; -static PyTypeObject *mpreduce_pytype, mpreduce_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject mpreduce_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "MPReduce", /* @tp_name@ */ sizeof(mpreduce_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1672,6 +1686,8 @@ static PyTypeObject *mpreduce_pytype, mpreduce_pytype_skel = { /*----- Chinese Remainder Theorem solution --------------------------------*/ +static PyTypeObject *mpcrt_pytype; + typedef struct mpcrt_pyobj { PyObject_HEAD mpcrt c; @@ -1804,8 +1820,8 @@ static const PyMethodDef mpcrt_pymethods[] = { { 0 } }; -static PyTypeObject *mpcrt_pytype, mpcrt_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject mpcrt_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "MPCRT", /* @tp_name@ */ sizeof(mpcrt_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1897,7 +1913,7 @@ static PyObject *gf_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) if (!good_radix_p(radix, 1)) VALERR("radix out of range"); if ((z = mp_frompyobject(x, radix)) == 0) { PyErr_Format(PyExc_TypeError, "can't convert %.100s to gf", - x->ob_type->tp_name); + Py_TYPE(x)->tp_name); goto end; } if (MP_NEGP(z)) { @@ -2104,8 +2120,8 @@ static const PyNumberMethods gf_pynumber = { 0, /* @nb_inplace_true_divide@ */ }; -static PyTypeObject gf_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject gf_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "GF", /* @tp_name@ */ sizeof(mp_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -2169,6 +2185,8 @@ static PyTypeObject gf_pytype_skel = { /*----- Sparse poly reduction ---------------------------------------------*/ +static PyTypeObject *gfreduce_pytype; + typedef struct gfreduce_pyobj { PyObject_HEAD gfreduce mr; @@ -2303,8 +2321,8 @@ static const PyMethodDef gfreduce_pymethods[] = { { 0 } }; -static PyTypeObject *gfreduce_pytype, gfreduce_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject gfreduce_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "GFReduce", /* @tp_name@ */ sizeof(gfreduce_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -2353,14 +2371,14 @@ static PyTypeObject *gfreduce_pytype, gfreduce_pytype_skel = { /*----- Normal/poly transformation ----------------------------------------*/ +static PyTypeObject *gfn_pytype; + typedef struct gfn_pyobj { PyObject_HEAD mp *p; gfn ntop, pton; } gfn_pyobj; -static PyTypeObject *gfn_pytype, gfn_pytype_skel; - #define GFN_P(o) (((gfn_pyobj *)(o))->p) #define GFN_PTON(o) (&((gfn_pyobj *)(o))->pton) #define GFN_NTOP(o) (&((gfn_pyobj *)(o))->ntop) @@ -2441,8 +2459,8 @@ static const PyMethodDef gfn_pymethods[] = { { 0 } }; -static PyTypeObject gfn_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ +static const PyTypeObject gfn_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ "GFN", /* @tp_name@ */ sizeof(gfn_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -2492,6 +2510,11 @@ static PyTypeObject gfn_pytype_skel = { /*----- Glue --------------------------------------------------------------*/ +static const struct nameval consts[] = { + CONST(MPW_MAX), + { 0 } +}; + void mp_pyinit(void) { INITTYPE(mp, root); @@ -2516,6 +2539,7 @@ void mp_pyinsert(PyObject *mod) INSERT("GF", gf_pytype); INSERT("GFReduce", gfreduce_pytype); INSERT("GFN", gfn_pytype); + setconstants(mod, consts); } /*----- That's all, folks -------------------------------------------------*/