sqlite_int64 _pysqlite_long_as_int64(PyObject * py_val) { int overflow; #ifdef HAVE_LONG_LONG PY_LONG_LONG value = PyLong_AsLongLongAndOverflow(py_val, &overflow); #else long value = PyLong_AsLongAndOverflow(py_val, &overflow); #endif if (value == -1 && PyErr_Occurred()) return -1; if (!overflow) { #ifdef HAVE_LONG_LONG # if SIZEOF_LONG_LONG > 8 if (-0x8000000000000000LL <= value && value <= 0x7FFFFFFFFFFFFFFFLL) # endif #else # if SIZEOF_LONG > 8 if (-0x8000000000000000L <= value && value <= 0x7FFFFFFFFFFFFFFFL) # endif #endif return value; } else if (sizeof(value) < sizeof(sqlite_int64)) { sqlite_int64 int64val; if (_PyLong_AsByteArray((PyLongObject *)py_val, (unsigned char *)&int64val, sizeof(int64val), IS_LITTLE_ENDIAN, 1 /* signed */) >= 0) { return int64val; } } PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to SQLite INTEGER"); return -1; }
static int lp_ulonglong(char *p, PyObject *v, const formatdef *f) { int res; v = get_pylong(v); if (v == NULL) return -1; res = _PyLong_AsByteArray((PyLongObject*)v, (unsigned char *)p, 8, 1, /* little_endian */ 0 /* signed */); Py_DECREF(v); return res; }
jobject JySync_Init_JyLong_From_PyLong(PyObject* src, jclass subtype) { env(NULL); size_t numBits = _PyLong_NumBits(src); size_t n = 1+numBits/8; if (numBits%8 != 0) ++n; jarray jbytes = (*env)->NewByteArray(env, (jsize) n); jbyte* bbytes = (*env)->GetByteArrayElements(env, jbytes, NULL); //memcpy(bbytes, bytes, n); _PyLong_AsByteArray(src, bbytes, n, JNI_FALSE, JNI_TRUE); (*env)->ReleaseByteArrayElements(env, jbytes, bbytes, 0); //jobject bival; return (*env)->CallStaticObjectMethod(env, pyPyClass, pyPy_newLongFromBigInt, (*env)->NewObject(env, bigIntClass, bigInt_fromByteArrayConstructor, jbytes)); }
extern "C" unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject* vv) noexcept { unsigned PY_LONG_LONG bytes; int one = 1; int res; if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); return (unsigned PY_LONG_LONG) - 1; } res = _PyLong_AsByteArray((PyLongObject*)vv, (unsigned char*)&bytes, SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ if (res < 0) return (unsigned PY_LONG_LONG)res; else return bytes; }
extern "C" PY_LONG_LONG PyLong_AsLongLong(PyObject* vv) noexcept { PY_LONG_LONG bytes; int one = 1; int res; if (vv == NULL) { PyErr_BadInternalCall(); return -1; } if (!PyLong_Check(vv)) { PyNumberMethods* nb; PyObject* io; if (PyInt_Check(vv)) return (PY_LONG_LONG)PyInt_AsLong(vv); if ((nb = vv->cls->tp_as_number) == NULL || nb->nb_int == NULL) { PyErr_SetString(PyExc_TypeError, "an integer is required"); return -1; } io = (*nb->nb_int)(vv); if (io == NULL) return -1; if (PyInt_Check(io)) { bytes = PyInt_AsLong(io); Py_DECREF(io); return bytes; } if (PyLong_Check(io)) { bytes = PyLong_AsLongLong(io); Py_DECREF(io); return bytes; } Py_DECREF(io); PyErr_SetString(PyExc_TypeError, "integer conversion failed"); return -1; } res = _PyLong_AsByteArray((PyLongObject*)vv, (unsigned char*)&bytes, SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ if (res < 0) return (PY_LONG_LONG)-1; else return bytes; }
/* py2sq: Create and return a Squeak oop from a PyObject. Returns the new OOP or NULL on failure. Arguments: obj: The PyObject reference to convert to Squeak. */ OOP py2sq(PyObject *obj) { if(obj == NULL) { pyErr = "py2sq: NULL PyObject reference encountered"; return 0; } /* nil, true, false */ if(obj == Py_None) { return vm->nilObject(); } if(obj == Py_True) { return vm->trueObject(); } if(obj == Py_False) { return vm->falseObject(); } /* 32bit signed integer value */ if(PyObject_TypeCheck(obj, &PyInt_Type)) { return vm->signed32BitIntegerFor(PyInt_AsLong(obj)); } /* BigNums */ if(PyObject_TypeCheck(obj, &PyLong_Type)) { int nBits = _PyLong_NumBits(obj); int i, nBytes = (nBits + 7) / 8; OOP sqInt, sqIntClass; /* Cover PyLongs <= 32 bit */ if(nBits < 32) { int value = PyLong_AsLong(obj); return vm->signed32BitIntegerFor(value); } #if 0 /* At this point (VM proxy 1.x), Squeak's signed64BitIntegerFor() is HORRIBLY broken. Once a fixed version exists the above should be defined as if VM_PROXY_MINOR > xxx to enable the fast conversion below */ /* Cover PyLongs <= 64 bit */ if(nBits < 64) { long long veryLong = PyLong_AsLongLong(obj); return vm->signed64BitIntegerFor(veryLong); } #endif /* Cover large positive integers */ if(_PyLong_Sign(obj) >= 0) { sqIntClass = vm->classLargePositiveInteger(); sqInt = vm->instantiateClassindexableSize(sqIntClass, nBytes); _PyLong_AsByteArray((PyLongObject*)obj, vm->firstIndexableField(sqInt), nBytes, 1, 0); return sqInt; } /* Cover the remaining case of large negative integers. Unfortunately, Python only gives us an interface using the 2s complement so we have to recompute the magnitude from it. Sigh. */ nBytes++; /* one extra in case we need the sign bit */ if(nBytes >= longBufMax) { longBufMax = nBytes; if(longBuf) free(longBuf); longBuf = malloc(longBufMax); } _PyLong_AsByteArray((PyLongObject*)obj, longBuf, nBytes, 1, 1); for(i=0; i < nBytes; i++) longBuf[i] ^= 255; for(i=0; i < nBytes; i++) if(++longBuf[i]) break; while(longBuf[nBytes-1] == 0) nBytes--; sqIntClass = vm->classLargeNegativeInteger(); sqInt = vm->instantiateClassindexableSize(sqIntClass, nBytes); memcpy(vm->firstIndexableField(sqInt), longBuf, nBytes); return sqInt; } /* 64bit double float value */ if(PyObject_TypeCheck(obj, &PyFloat_Type)) { return vm->floatObjectOf(PyFloat_AsDouble(obj)); } /* string -- only deals with byte strings here */ if(PyObject_TypeCheck(obj, &PyString_Type)) { int sz = PyString_Size(obj); char *src = PyString_AsString(obj); OOP strOop = vm->instantiateClassindexableSize(vm->classString(), sz); char *dst = vm->firstIndexableField(strOop); memcpy(dst, src, sz); return strOop; } /* tuples -- convert those to arrays */ if(PyObject_TypeCheck(obj, &PyTuple_Type)) { int i, sz; OOP arrayOop, itemOop; sz = PyObject_Length(obj); arrayOop = vm->instantiateClassindexableSize(vm->classArray(), sz); for(i = 0; i < sz; i++) { vm->pushRemappableOop(arrayOop); itemOop = py2sq(PyTuple_GetItem(obj, i)); arrayOop = vm->popRemappableOop(); if(itemOop == 0) return 0; vm->storePointerofObjectwithValue(i, arrayOop, itemOop); } return arrayOop; } return py2sqGeneric(obj); }