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)); }
/* Simple test of _PyLong_NumBits and _PyLong_Sign. */ static PyObject * test_long_numbits(PyObject *self) { struct triple { long input; size_t nbits; int sign; } testcases[] = {{0, 0, 0}, {1L, 1, 1}, {-1L, 1, -1}, {2L, 2, 1}, {-2L, 2, -1}, {3L, 2, 1}, {-3L, 2, -1}, {4L, 3, 1}, {-4L, 3, -1}, {0x7fffL, 15, 1}, /* one Python long digit */ {-0x7fffL, 15, -1}, {0xffffL, 16, 1}, {-0xffffL, 16, -1}, {0xfffffffL, 28, 1}, {-0xfffffffL, 28, -1}}; int i; for (i = 0; i < sizeof(testcases) / sizeof(struct triple); ++i) { PyObject *plong = PyLong_FromLong(testcases[i].input); size_t nbits = _PyLong_NumBits(plong); int sign = _PyLong_Sign(plong); Py_DECREF(plong); if (nbits != testcases[i].nbits) return raiseTestError("test_long_numbits", "wrong result for _PyLong_NumBits"); if (sign != testcases[i].sign) return raiseTestError("test_long_numbits", "wrong result for _PyLong_Sign"); } Py_INCREF(Py_None); return Py_None; }
/* 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); }