Exemplo n.º 1
0
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));
}
Exemplo n.º 2
0
/* 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;
}
Exemplo n.º 3
0
/* 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);
}