Beispiel #1
0
static PyObject*
slice_indices(PySliceObject* self, PyObject* len)
{
    PyObject *start, *stop, *step;
    PyObject *length;
    int error;

    /* Convert length to an integer if necessary; raise for negative length. */
    length = PyNumber_Index(len);
    if (length == NULL)
        return NULL;

    if (_PyLong_Sign(length) < 0) {
        PyErr_SetString(PyExc_ValueError,
                        "length should not be negative");
        Py_DECREF(length);
        return NULL;
    }

    error = _PySlice_GetLongIndices(self, length, &start, &stop, &step);
    Py_DECREF(length);
    if (error == -1)
        return NULL;
    else
        return Py_BuildValue("(NNN)", start, stop, step);
}
Beispiel #2
0
extern "C" void* PyLong_AsVoidPtr(PyObject* vv) noexcept {
/* This function will allow int or long objects. If vv is neither,
   then the PyLong_AsLong*() functions will raise the exception:
   PyExc_SystemError, "bad argument to internal function"
*/
#if SIZEOF_VOID_P <= SIZEOF_LONG
    long x;

    if (PyInt_Check(vv))
        x = PyInt_AS_LONG(vv);
    else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
        x = PyLong_AsLong(vv);
    else
        x = PyLong_AsUnsignedLong(vv);
#else

#ifndef HAVE_LONG_LONG
#error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
#endif
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
#error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
#endif
    PY_LONG_LONG x;

    if (PyInt_Check(vv))
        x = PyInt_AS_LONG(vv);
    else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
        x = PyLong_AsLongLong(vv);
    else
        x = PyLong_AsUnsignedLongLong(vv);

#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */

    if (x == -1 && PyErr_Occurred())
        return NULL;
    return (void*)x;
}
Beispiel #3
0
Py_off_t
PyNumber_AsOff_t(PyObject *item, PyObject *err)
{
    Py_off_t result;
    PyObject *runerr;
    PyObject *value = PyNumber_Index(item);
    if (value == NULL)
        return -1;

    if (PyInt_Check(value)) {
        /* We assume a long always fits in a Py_off_t... */
        result = (Py_off_t) PyInt_AS_LONG(value);
        goto finish;
    }

    /* We're done if PyLong_AsSsize_t() returns without error. */
    result = PyLong_AsOff_t(value);
    if (result != -1 || !(runerr = PyErr_Occurred()))
        goto finish;

    /* Error handling code -- only manage OverflowError differently */
    if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError))
        goto finish;

    PyErr_Clear();
    /* If no error-handling desired then the default clipping
       is sufficient.
     */
    if (!err) {
        assert(PyLong_Check(value));
        /* Whether or not it is less than or equal to
           zero is determined by the sign of ob_size
        */
        if (_PyLong_Sign(value) < 0)
            result = PY_OFF_T_MIN;
        else
            result = PY_OFF_T_MAX;
    }
    else {
        /* Otherwise replace the error with caller's error object. */
        PyErr_Format(err,
                     "cannot fit '%.200s' into an offset-sized integer",
                     item->ob_type->tp_name);
    }

 finish:
    Py_DECREF(value);
    return result;
}
Beispiel #4
0
/* Helper function for validating step.  Always returns a new reference or
   NULL on error.
*/
static PyObject *
validate_step(PyObject *step)
{
    /* No step specified, use a step of 1. */
    if (!step)
        return PyLong_FromLong(1);

    step = PyNumber_Index(step);
    if (step && _PyLong_Sign(step) == 0) {
        PyErr_SetString(PyExc_ValueError,
                        "range() arg 3 must not be zero");
        Py_CLEAR(step);
    }

    return step;
}
/* 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;
}
Beispiel #6
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);
}
Beispiel #7
0
int
_PySlice_GetLongIndices(PySliceObject *self, PyObject *length,
                        PyObject **start_ptr, PyObject **stop_ptr,
                        PyObject **step_ptr)
{
    PyObject *start=NULL, *stop=NULL, *step=NULL;
    PyObject *upper=NULL, *lower=NULL;
    int step_is_negative, cmp_result;

    /* Convert step to an integer; raise for zero step. */
    if (self->step == Py_None) {
        step = _PyLong_One;
        Py_INCREF(step);
        step_is_negative = 0;
    }
    else {
        int step_sign;
        step = evaluate_slice_index(self->step);
        if (step == NULL)
            goto error;
        step_sign = _PyLong_Sign(step);
        if (step_sign == 0) {
            PyErr_SetString(PyExc_ValueError,
                            "slice step cannot be zero");
            goto error;
        }
        step_is_negative = step_sign < 0;
    }

    /* Find lower and upper bounds for start and stop. */
    if (step_is_negative) {
        lower = PyLong_FromLong(-1L);
        if (lower == NULL)
            goto error;

        upper = PyNumber_Add(length, lower);
        if (upper == NULL)
            goto error;
    }
    else {
        lower = _PyLong_Zero;
        Py_INCREF(lower);
        upper = length;
        Py_INCREF(upper);
    }

    /* Compute start. */
    if (self->start == Py_None) {
        start = step_is_negative ? upper : lower;
        Py_INCREF(start);
    }
    else {
        start = evaluate_slice_index(self->start);
        if (start == NULL)
            goto error;

        if (_PyLong_Sign(start) < 0) {
            /* start += length */
            PyObject *tmp = PyNumber_Add(start, length);
            Py_DECREF(start);
            start = tmp;
            if (start == NULL)
                goto error;

            cmp_result = PyObject_RichCompareBool(start, lower, Py_LT);
            if (cmp_result < 0)
                goto error;
            if (cmp_result) {
                Py_INCREF(lower);
                Py_DECREF(start);
                start = lower;
            }
        }
        else {
            cmp_result = PyObject_RichCompareBool(start, upper, Py_GT);
            if (cmp_result < 0)
                goto error;
            if (cmp_result) {
                Py_INCREF(upper);
                Py_DECREF(start);
                start = upper;
            }
        }
    }

    /* Compute stop. */
    if (self->stop == Py_None) {
        stop = step_is_negative ? lower : upper;
        Py_INCREF(stop);
    }
    else {
        stop = evaluate_slice_index(self->stop);
        if (stop == NULL)
            goto error;

        if (_PyLong_Sign(stop) < 0) {
            /* stop += length */
            PyObject *tmp = PyNumber_Add(stop, length);
            Py_DECREF(stop);
            stop = tmp;
            if (stop == NULL)
                goto error;

            cmp_result = PyObject_RichCompareBool(stop, lower, Py_LT);
            if (cmp_result < 0)
                goto error;
            if (cmp_result) {
                Py_INCREF(lower);
                Py_DECREF(stop);
                stop = lower;
            }
        }
        else {
            cmp_result = PyObject_RichCompareBool(stop, upper, Py_GT);
            if (cmp_result < 0)
                goto error;
            if (cmp_result) {
                Py_INCREF(upper);
                Py_DECREF(stop);
                stop = upper;
            }
        }
    }

    *start_ptr = start;
    *stop_ptr = stop;
    *step_ptr = step;
    Py_DECREF(upper);
    Py_DECREF(lower);
    return 0;

  error:
    *start_ptr = *stop_ptr = *step_ptr = NULL;
    Py_XDECREF(start);
    Py_XDECREF(stop);
    Py_XDECREF(step);
    Py_XDECREF(upper);
    Py_XDECREF(lower);
    return -1;
}