Example #1
0
/* Insert item in external memory list.
 *
 * XXX: Support slice objects and negative indices?
 */
static int em_list_setitem(em_list_t *self, PyObject *key, PyObject *value)
{
    Py_ssize_t index;

    int ret = -1;

    /* Python 3 supports only long integers. */
#if PY_MAJOR_VERSION < 3
    if(PyInt_CheckExact(key))
    {
        index = PyInt_AsSsize_t(key);
        ret = em_list_setitem_safe(self, index, value);
    }
    else if(PyLong_CheckExact(key))
#else
    if(PyLong_CheckExact(key))
#endif
    {
        index = PyLong_AsSsize_t(key);
        ret = em_list_setitem_safe(self, index, value);
    }
    else
        PyErr_SetString(PyExc_TypeError, "Invalid index type");

    return ret;
}
static INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
#if PY_VERSION_HEX < 0x03000000
    if (likely(PyInt_CheckExact(x) || PyInt_Check(x))) {
        long val = PyInt_AS_LONG(x);
        if (unlikely(val < 0)) {
            PyErr_SetString(PyExc_OverflowError,
                            "can't convert negative value to unsigned PY_LONG_LONG");
            return (unsigned PY_LONG_LONG)-1;
        }
        return (unsigned PY_LONG_LONG)val;
    } else
#endif
    if (likely(PyLong_CheckExact(x) || PyLong_Check(x))) {
        if (unlikely(Py_SIZE(x) < 0)) {
            PyErr_SetString(PyExc_OverflowError,
                            "can't convert negative value to unsigned PY_LONG_LONG");
            return (unsigned PY_LONG_LONG)-1;
        }
        return PyLong_AsUnsignedLongLong(x);
    } else {
        unsigned PY_LONG_LONG val;
        PyObject *tmp = __Pyx_PyNumber_Int(x);
        if (!tmp) return (unsigned PY_LONG_LONG)-1;
        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
        Py_DECREF(tmp);
        return val;
    }
}
Example #3
0
/* Write a single value to the buffer (also write it's type_byte, for which
 * space has already been reserved.
 *
 * returns 0 on failure */
static int write_element_to_buffer(bson_buffer* buffer, int type_byte, PyObject* value, unsigned char check_keys) {
    /* TODO this isn't quite the same as the Python version:
     * here we check for type equivalence, not isinstance in some
     * places. */
    if (PyInt_CheckExact(value) || PyLong_CheckExact(value)) {
        const long long_value = PyInt_AsLong(value);
        const int int_value = (int)long_value;
        if (PyErr_Occurred() || long_value != int_value) { /* Overflow */
            long long long_long_value;
            PyErr_Clear();
            long_long_value = PyLong_AsLongLong(value);
            if (PyErr_Occurred()) { /* Overflow AGAIN */
                PyErr_SetString(PyExc_OverflowError,
                                "MongoDB can only handle up to 8-byte ints");
                return 0;
            }
            *(buffer->buffer + type_byte) = 0x12;
            return buffer_write_bytes(buffer, (const char*)&long_long_value, 8);
        }
        *(buffer->buffer + type_byte) = 0x10;
        return buffer_write_bytes(buffer, (const char*)&int_value, 4);
    } else if (PyBool_Check(value)) {
        const long bool = PyInt_AsLong(value);
        const char c = bool ? 0x01 : 0x00;
        *(buffer->buffer + type_byte) = 0x08;
        return buffer_write_bytes(buffer, &c, 1);
    } else if (PyFloat_CheckExact(value)) {
Example #4
0
/* Retrieve item from external memory list.
 *
 * XXX: Support slice objects and negative indices?
 */
static PyObject *em_list_getitem(em_list_t *self, PyObject *key)
{
    Py_ssize_t index;

    PyObject *r = NULL;

    /* Python 3 supports only long integers. */
#if PY_MAJOR_VERSION < 3
    if(PyInt_CheckExact(key))
    {
        index = PyInt_AsSsize_t(key);
        r = em_list_getitem_internal(self, index);
    }
    else if(PyLong_CheckExact(key))
#else
    if(PyLong_CheckExact(key))
#endif
    {
        index = PyLong_AsSsize_t(key);
        r = em_list_getitem_internal(self, index);
    }
    else
        PyErr_SetString(PyExc_TypeError, "Invalid key object type");

    return r;
}
Example #5
0
static void py_variable_to_json_internal( PyObject *obj,
                                          json_writer_t *writer )
{
  if ( PyString_CheckExact( obj ) ) {
    json_writer_write_str( writer, PyString_AS_STRING( obj ) );
  }
  else if ( PyInt_CheckExact( obj ) ) {
    json_writer_write_integer( writer, PyInt_AS_LONG( obj ) );
  }
  else if ( PyFloat_CheckExact( obj ) ) {
    json_writer_write_number( writer, PyFloat_AS_DOUBLE( obj ) );
  }
  else if ( PyBool_Check( obj ) ) {
    json_writer_write_boolean( writer, ( obj == Py_True ) );
  }
  else if ( PyUnicode_CheckExact( obj ) ) {
    /* Create a new string object that is UTF-8 encoded. */
    Py_UNICODE *unicode = PyUnicode_AS_UNICODE( obj );
    Py_ssize_t size = PyUnicode_GET_SIZE( obj );
    PyObject *str_obj = PyUnicode_EncodeUTF8( unicode, size, NULL );
    py_variable_to_json_internal( str_obj, writer );
    PyObject_Free( str_obj );
  }
  else if ( PyDict_CheckExact( obj ) ) {
    py_dict_to_json( obj, writer );
  }
  else if ( PyList_CheckExact( obj ) ) {
    py_list_to_json( obj, writer );
  }
  else if ( PyTuple_CheckExact( obj ) ) {
    py_tuple_to_json( obj, writer ); 
  }
}
Example #6
0
static PyObject *
buf_abs(PyObject *self, PyObject *args)
{
	PyObject *oaddr, *olen;
	int addr, len;

	if(!PyArg_UnpackTuple(args, "abs", 2, 2, &oaddr, &olen))
		return NULL;
	if(!PyInt_CheckExact(oaddr) ||
	   !PyInt_CheckExact(olen))
		return NULL;

	addr = PyInt_AS_LONG(oaddr);
	len  = PyInt_AS_LONG(olen);

	return PyBuffer_FromReadWriteMemory((void *)addr, len);
}
Example #7
0
static PyObject *
int_pos(PyIntObject *v)
{
	if (PyInt_CheckExact(v)) {
		Py_INCREF(v);
		return (PyObject *)v;
	}
	else
		return PyInt_FromLong(v->ob_ival);
}
// This is Python2 int, for Python3 the LONG variant is to be used.
bool BINARY_OPERATION_ADD_INT_OBJECT_INPLACE(PyObject **operand1, PyObject *operand2) {
    assert(operand1);
    CHECK_OBJECT(*operand1);
    CHECK_OBJECT(operand2);
    assert(PyInt_CheckExact(*operand1));

    // Something similar for Python3 should exist too.
    if (PyInt_CheckExact(operand2)) {
        long a, b, i;

        a = PyInt_AS_LONG(*operand1);
        b = PyInt_AS_LONG(operand2);

        i = a + b;

        // Detect overflow, in which case, a "long" object would have to be
        // created, which we won't handle here. TODO: Add an else for that
        // case.
        if (likely(!((i ^ a) < 0 && (i ^ b) < 0))) {
            PyObject *result = PyInt_FromLong(i);
            Py_DECREF(*operand1);

            *operand1 = result;

            return true;
        }
    }

    PyObject *result = PyNumber_InPlaceAdd(*operand1, operand2);

    if (unlikely(result == NULL)) {
        return false;
    }

    // We got an object handed, that we have to release.
    Py_DECREF(*operand1);

    // That's our return value then. As we use a dedicated variable, it's
    // OK that way.
    *operand1 = result;

    return true;
}
Example #9
0
static void
int_dealloc(PyIntObject *v)
{
	if (PyInt_CheckExact(v)) {
		v->ob_type = (struct _typeobject *)free_list;
		free_list = v;
	}
	else
		v->ob_type->tp_free((PyObject *)v);
}
Example #10
0
static PyObject *
pint_getquoted(pintObject *self, PyObject *args)
{
    PyObject *res = NULL;

    /* Convert subclass to int to handle IntEnum and other subclasses
     * whose str() is not the number. */
    if (PyLong_CheckExact(self->wrapped)
#if PY_MAJOR_VERSION < 2
        || PyInt_CheckExact(self->wrapped)
#endif
       ) {
        res = PyObject_Str(self->wrapped);
    } else {
        PyObject *tmp;
        if (!(tmp = PyObject_CallFunctionObjArgs(
                (PyObject *)&PyLong_Type, self->wrapped, NULL))) {
            goto exit;
        }
        res = PyObject_Str(tmp);
        Py_DECREF(tmp);
    }

    if (!res) {
        goto exit;
    }

#if PY_MAJOR_VERSION > 2
    /* unicode to bytes in Py3 */
    {
        PyObject *tmp = PyUnicode_AsUTF8String(res);
        Py_DECREF(res);
        if (!(res = tmp)) {
            goto exit;
        }
    }
#endif

    if ('-' == Bytes_AS_STRING(res)[0]) {
        /* Prepend a space in front of negative numbers (ticket #57) */
        PyObject *tmp;
        if (!(tmp = Bytes_FromString(" "))) {
            Py_DECREF(res);
            res = NULL;
            goto exit;
        }
        Bytes_ConcatAndDel(&tmp, res);
        if (!(res = tmp)) {
            goto exit;
        }
    }

exit:
    return res;
}
Example #11
0
    static void *convertible(::PyObject *obj_ptr)
    {
        if (!obj_ptr
            || (
#if PY_MAJOR_VERSION < 3
                   !PyInt_CheckExact(obj_ptr) &&
#endif
                   !PyLong_CheckExact(obj_ptr))) {
            return nullptr;
        }
        return obj_ptr;
    }
Example #12
0
static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) {
    if (PyInt_CheckExact(x)) {
        return PyInt_AS_LONG(x);
    }
    else if (PyLong_CheckExact(x)) {
        return PyLong_AsLongLong(x);
    }
    else {
        PY_LONG_LONG val;
        PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
        val = __pyx_PyInt_AsLongLong(tmp);
        Py_DECREF(tmp);
        return val;
    }
}
Example #13
0
static PyObject *
buf_bss(PyObject *self, PyObject *args)
{
	PyObject *olen;
	int len;

	if(!PyArg_UnpackTuple(args, "bss", 1, 1, &olen))
		return NULL;
	if(!PyInt_CheckExact(olen))
		return NULL;

	len = PyInt_AS_LONG(olen);

	return PyBuffer_FromReadWriteMemory(malloc(len), len);
}
Example #14
0
/*
 * PyArray_GetAttrString_SuppressException:
 *
 * Stripped down version of PyObject_GetAttrString,
 * avoids lookups for None, tuple, and List objects,
 * and doesn't create a PyErr since this code ignores it.
 *
 * This can be much faster then PyObject_GetAttrString where
 * exceptions are not used by caller.
 *
 * 'obj' is the object to search for attribute.
 *
 * 'name' is the attribute to search for.
 *
 * Returns attribute value on success, 0 on failure.
 */
PyObject *
PyArray_GetAttrString_SuppressException(PyObject *obj, char *name)
{
    PyTypeObject *tp = Py_TYPE(obj);
    PyObject *res = (PyObject *)NULL;

    /* We do not need to check for special attributes on trivial types */
    if (obj == Py_None ||
            /* Basic number types */
#if !defined(NPY_PY3K)
            PyInt_CheckExact(obj) ||
#endif
            PyLong_CheckExact(obj) ||
            PyFloat_CheckExact(obj) ||
            /* Basic sequence types */
            PyList_CheckExact(obj) ||
            PyTuple_CheckExact(obj)) {
        return NULL;
    }

    /* Attribute referenced by (char *)name */
    if (tp->tp_getattr != NULL) {
        res = (*tp->tp_getattr)(obj, name);
        if (res == NULL) {
            PyErr_Clear();
        }
    }
    /* Attribute referenced by (PyObject *)name */
    else if (tp->tp_getattro != NULL) {
#if defined(NPY_PY3K)
        PyObject *w = PyUnicode_InternFromString(name);
#else
        PyObject *w = PyString_InternFromString(name);
#endif
        if (w == NULL) {
            return (PyObject *)NULL;
        }
        res = (*tp->tp_getattro)(obj, w);
        Py_DECREF(w);
        if (res == NULL) {
            PyErr_Clear();
        }
    }
    return res;
}
Example #15
0
static PyObject *
python_compress(PyObject *self, PyObject *args) {
    char *input, *output;
    Py_ssize_t inlen;
    PyObject *pyoutlen = Py_None;
    long outlen;
    PyObject *result;

    if (!PyArg_ParseTuple(args, "s#|O", &input, &inlen, &pyoutlen))
        return NULL;

    if (pyoutlen == Py_None)
        outlen = inlen - 1;
    else if (PyInt_CheckExact(pyoutlen))
        outlen = PyInt_AsLong(pyoutlen);
    else if (PyLong_CheckExact(pyoutlen))
        outlen = PyLong_AsLong(pyoutlen);
    else {
        PyErr_SetString(PyExc_TypeError, "max_len must be an integer");
        return NULL;
    }

    if (inlen == 1) outlen++; /* work around for what looks like a liblzf bug */
    if (outlen <= 0) {
        PyErr_SetString(PyExc_ValueError, "max_len must be > 0");
        return NULL;
    }

    output = (char *)malloc(outlen + 1);
    if (output == NULL) {
        PyErr_SetString(PyExc_MemoryError, "out of memory");
        return NULL;
    }
    outlen = lzf_compress(input, inlen, output, outlen + 1);

    if (outlen)
        result = PYBYTES_FSAS(output, outlen);
    else {
        Py_XINCREF(Py_None);
        result = Py_None;
    }
    free(output);

    return result;
}
static INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
#if PY_VERSION_HEX < 0x03000000
    if (likely(PyInt_CheckExact(x) || PyInt_Check(x))) {
        long val = PyInt_AS_LONG(x);
        return (signed PY_LONG_LONG)val;
    } else
#endif
    if (likely(PyLong_CheckExact(x) || PyLong_Check(x))) {
        return PyLong_AsLongLong(x);
    } else {
        signed PY_LONG_LONG val;
        PyObject *tmp = __Pyx_PyNumber_Int(x);
        if (!tmp) return (signed PY_LONG_LONG)-1;
        val = __Pyx_PyInt_AsSignedLongLong(tmp);
        Py_DECREF(tmp);
        return val;
    }
}
Example #17
0
File: _speedups.c Project: 10sr/hue
static PyObject*
escape(PyObject *self, PyObject *text)
{
	PyObject *s = NULL, *rv = NULL, *html;

	/* we don't have to escape integers, bools or floats */
	if (PyLong_CheckExact(text) ||
#if PY_MAJOR_VERSION < 3
	    PyInt_CheckExact(text) ||
#endif
	    PyFloat_CheckExact(text) || PyBool_Check(text) ||
	    text == Py_None)
		return PyObject_CallFunctionObjArgs(markup, text, NULL);

	/* if the object has an __html__ method that performs the escaping */
	html = PyObject_GetAttrString(text, "__html__");
	if (html) {
		rv = PyObject_CallObject(html, NULL);
		Py_DECREF(html);
		return rv;
	}

	/* otherwise make the object unicode if it isn't, then escape */
	PyErr_Clear();
	if (!PyUnicode_Check(text)) {
#if PY_MAJOR_VERSION < 3
		PyObject *unicode = PyObject_Unicode(text);
#else
		PyObject *unicode = PyObject_Str(text);
#endif
		if (!unicode)
			return NULL;
		s = escape_unicode((PyUnicodeObject*)unicode);
		Py_DECREF(unicode);
	}
	else
		s = escape_unicode((PyUnicodeObject*)text);

	/* convert the unicode string into a markup object. */
	rv = PyObject_CallFunctionObjArgs(markup, (PyObject*)s, NULL);
	Py_DECREF(s);
	return rv;
}
Example #18
0
File: myson.c Project: S-YOU/myson
void encode_object(PyObject *arg) {
	Py_ssize_t size, i;
	char *p;

	if (PyString_CheckExact(arg)) {
		uint8_t *s, *sEnd;
		*d++ = '"';
		ENCODE_STR(arg, s, sEnd)
		*d++ = '"';
	} else if (PyUnicode_CheckExact(arg)) {
		*d++ = '"';
		Py_UNICODE *u, *uEnd;
		ENCODE_UNICODE(arg, u, uEnd)
		*d++ = '"';
	} else if (PyInt_CheckExact(arg) || PyLong_CheckExact(arg)) {
		i = PyInt_AsSsize_t(arg);
		uint64_t val = i < 0 ? *d++ = '-', (uint64_t)(~i + 1) : i;
		ITOA(val)
	} else if (PyList_CheckExact(arg)) {
Example #19
0
static PyObject *
builtin_videomode(PyObject *self, PyObject *args)
{
	PyObject *v = NULL;

	if (!PyArg_UnpackTuple(args, "inb", 1, 1, &v))
		return NULL;
	
	if (!PyInt_CheckExact(v))
		return NULL;

	switch(PyInt_AS_LONG(v))	{
	case 0:	set80x25();		break;
	case 1: set640x480x16();	break;
	case 2: set320x200x256();	break;
	}
	Py_INCREF(Py_True);
	return Py_True;
}
Example #20
0
static PyObject *
builtin_inb(PyObject *self, PyObject *args)
{
	PyObject *v = NULL;

	if (!PyArg_UnpackTuple(args, "inb", 1, 1, &v))
		return NULL;
	
	if (!PyInt_CheckExact(v)) {
		/* ERROR */
		return NULL;
	} else {
		unsigned short port = PyInt_AS_LONG(v);
		unsigned char data = in(port);
		PyObject *result = PyInt_FromLong(data);

		return result;
	}
}
Example #21
0
static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
    if (PyInt_CheckExact(x)) {
        long val = PyInt_AS_LONG(x);
        if (unlikely(val < 0)) {
            PyErr_SetString(PyExc_TypeError, "Negative assignment to unsigned type.");
            return (unsigned PY_LONG_LONG)-1;
        }
        return val;
    }
    else if (PyLong_CheckExact(x)) {
        return PyLong_AsUnsignedLongLong(x);
    }
    else {
        PY_LONG_LONG val;
        PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
        val = __pyx_PyInt_AsUnsignedLongLong(tmp);
        Py_DECREF(tmp);
        return val;
    }
}
Example #22
0
static PyObject*
convert_nested(PyObject *ob, convert_func convert_string)
{
    /* dict. */
    if (PyDict_CheckExact(ob)) {
        return convert_dict(ob, convert_string);
    }

    /* sequence. */
    if (PyTuple_CheckExact(ob) || PyList_CheckExact(ob)) {
        return convert_seq(ob, convert_string);
    }

    /* numbers. */
    if (PyInt_CheckExact(ob) || PyLong_CheckExact(ob) || PyFloat_CheckExact(ob)) {
        Py_INCREF(ob);
        return ob;
    }

    /* bool. */
    if (PyBool_Check(ob)) {
        Py_INCREF(ob);
        return ob;
    }

    /* none. */
    if (ob == Py_None) {
        Py_INCREF(ob);
        return ob;
    }

    if (PyString_CheckExact(ob) || PyUnicode_CheckExact(ob)) {
        return convert_string(ob);
    }

    return PyErr_Format(
        PyExc_TypeError,
        "Got wrong type: %s",
        ob->ob_type->tp_name);
}
Example #23
0
static PyObject *bip_sum(term_t t) {
  PyObject *seq;
  PyObject *result = NULL;
  PyObject *temp, *item, *iter;

  if (!PL_get_arg(1, t, t))
    return NULL;
  seq = term_to_python(t, true);
  iter = PyObject_GetIter(seq);
  if (iter == NULL)
    return NULL;

  if (result == NULL) {
#if PY_MAJOR_VERSION < 3
    result = PyInt_FromLong(0);
#else
    result = PyLong_FromLong(0);
#endif
    if (result == NULL) {
      Py_DECREF(iter);
      return NULL;
    }
  } else {
#if PY_MAJOR_VERSION < 3
    /* reject string values for 'start' parameter */
    if (PyObject_TypeCheck(result, &PyBaseString_Type)) {
      PyErr_SetString(PyExc_TypeError,
                      "sum() can't sum strings [use ''.join(seq) instead]");
      Py_DECREF(iter);
      return NULL;
    }
    Py_INCREF(result);
#endif
  }

#ifndef SLOW_SUM
/* Fast addition by keeping temporary sums in C instead of new Python objects.
Assumes all inputs are the same type.  If the assumption fails, default
to the more general routine.
*/
#if PY_MAJOR_VERSION < 3
  if (PyInt_CheckExact(result)) {
    long i_result = PyInt_AS_LONG(result);
#else
  if (PyLong_CheckExact(result)) {
    long i_result = PyLong_AS_LONG(result);
#endif
    Py_DECREF(result);
    result = NULL;
    while (result == NULL) {
      item = PyIter_Next(iter);
      if (item == NULL) {
        Py_DECREF(iter);
        if (PyErr_Occurred())
          return NULL;
#if PY_MAJOR_VERSION < 3
        return PyInt_FromLong(i_result);
#else
        return PyLong_FromLong(i_result);
#endif
      }
#if PY_MAJOR_VERSION < 3
      if (PyInt_CheckExact(item)) {
        long b = PyInt_AS_LONG(item);
#else
      if (PyLong_CheckExact(item)) {
        long b = PyLong_AS_LONG(item);
#endif
        long x = i_result + b;
        if ((x ^ i_result) >= 0 || (x ^ b) >= 0) {
          i_result = x;
          Py_DECREF(item);
          continue;
        }
      }
/* Either overflowed or is not an int. Restore real objects and process normally
 */
#if PY_MAJOR_VERSION < 3
      result = PyInt_FromLong(i_result);
#else
      result = PyLong_FromLong(i_result);
#endif
      temp = PyNumber_Add(result, item);
      Py_DECREF(result);
      Py_DECREF(item);
      result = temp;
      if (result == NULL) {
        Py_DECREF(iter);
        return NULL;
      }
    }
  }

  if (PyFloat_CheckExact(result)) {
    double f_result = PyFloat_AS_DOUBLE(result);
    Py_DECREF(result);
    result = NULL;
    while (result == NULL) {
      item = PyIter_Next(iter);
      if (item == NULL) {
        Py_DECREF(iter);
        if (PyErr_Occurred())
          return NULL;
        return PyFloat_FromDouble(f_result);
      }
      if (PyFloat_CheckExact(item)) {
        PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0)
            f_result += PyFloat_AS_DOUBLE(item);
        PyFPE_END_PROTECT(f_result) Py_DECREF(item);
        continue;
      }
#if PY_MAJOR_VERSION < 3
      if (PyInt_CheckExact(item)) {
        PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0)
            f_result += (double)PyInt_AS_LONG(item);
        PyFPE_END_PROTECT(f_result) Py_DECREF(item);
        continue;
      }
#else
      if (PyLong_CheckExact(item)) {
        PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0)
            f_result += PyLong_AsDouble(item);
        PyFPE_END_PROTECT(f_result) Py_DECREF(item);
        continue;
      }
#endif
      result = PyFloat_FromDouble(f_result);
      temp = PyNumber_Add(result, item);
      Py_DECREF(result);
      Py_DECREF(item);
      result = temp;
      if (result == NULL) {
        Py_DECREF(iter);
        return NULL;
      }
    }
#endif
  }

  for (;;) {
    item = PyIter_Next(iter);
    if (item == NULL) {
      /* error, or end-of-sequence */
      if (PyErr_Occurred()) {
        Py_DECREF(result);
        result = NULL;
      }
      break;
    }
    /* It's tempting to use PyNumber_InPlaceAdd instead of
    PyNumber_Add here, to avoid quadratic running time
    when doing 'sum(list_of_lists, [])'.  However, this
    would produce a change in behaviour: a snippet like

    empty = []
    sum([[x] for x in range(10)], empty)

    would change the value of empty. */
    temp = PyNumber_Add(result, item);
    Py_DECREF(result);
    Py_DECREF(item);
    result = temp;
    if (result == NULL)
      break;
  }
  Py_DECREF(iter);
  return result;
}

//@}

static long get_int(term_t arg, bool eval) {
  long low;

  if (!PL_get_long(arg, &low)) {
    PyObject *low = term_to_python(arg, eval);
    if (PyLong_Check(low)) {
      return PyLong_AsLong(low);
#if PY_MAJOR_VERSION < 3
    } else if (PyInt_Check(low)) {
      return PyInt_AsLong(low);
#endif
    } else {
      return 0;
    }
  }
  return low;
}

/* Return number of items in range/xrange (lo, hi, step).  step > 0
* required.  Return a value < 0 if & only if the true value is too
* large to fit in a signed long.
*/
static long get_len_of_range(long lo, long hi, long step) {
  /* -------------------------------------------------------------
  If lo >= hi, the range is empty.
  Else if n values are in the range, the last one is
  lo + (n-1)*step, which must be <= hi-1.  Rearranging,
  n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
  the proper value.  Since lo < hi in this case, hi-lo-1 >= 0, so
  the RHS is non-negative and so truncation is the same as the
  floor.  Letting M be the largest positive long, the worst case
  for the RHS numerator is hi=M, lo=-M-1, and then
  hi-lo-1 = M-(-M-1)-1 = 2*M.  Therefore unsigned long has enough
  precision to compute the RHS exactly.
  ---------------------------------------------------------------*/
  long n = 0;
  if (lo < hi) {
    unsigned long uhi = (unsigned long)hi;
    unsigned long ulo = (unsigned long)lo;
    unsigned long diff = uhi - ulo - 1;
    n = (long)(diff / (unsigned long)step + 1);
  }
  return n;
}
Example #24
0
static int do_python(REQUEST *request, PyObject *pFunc,
		     char const *funcname)
{
	vp_cursor_t	cursor;
	VALUE_PAIR      *vp;
	PyObject	*pRet = NULL;
	PyObject	*pArgs = NULL;
	int		tuplelen;
	int		ret;
	
	PyGILState_STATE gstate;
	
	/* Return with "OK, continue" if the function is not defined. */
	if (!pFunc)
		return RLM_MODULE_OK;
	
	/* Default return value is "OK, continue" */
	ret = RLM_MODULE_OK;
	
	/*
	 *	We will pass a tuple containing (name, value) tuples
	 *	We can safely use the Python function to build up a
	 *	tuple, since the tuple is not used elsewhere.
	 *
	 *	Determine the size of our tuple by walking through the packet.
	 *	If request is NULL, pass None.
	 */
	tuplelen = 0;
	if (request != NULL) {
		for (vp = paircursor(&cursor, &request->packet->vps);
		     vp;
		     vp = pairnext(&cursor)) {
			tuplelen++;
		}
	}

	gstate = PyGILState_Ensure();
	
	if (tuplelen == 0) {
		Py_INCREF(Py_None);
		pArgs = Py_None;
	} else {
		int i = 0;
		if ((pArgs = PyTuple_New(tuplelen)) == NULL)
			goto failed;

		for (vp = paircursor(&cursor, &request->packet->vps);
		     vp;
		     vp = pairnext(&cursor), i++) {
			PyObject *pPair;
			
			/* The inside tuple has two only: */
			if ((pPair = PyTuple_New(2)) == NULL)
				goto failed;
			
			if (mod_populate_vptuple(pPair, vp) == 0) {
				/* Put the tuple inside the container */
				PyTuple_SET_ITEM(pArgs, i, pPair);
			} else {
				Py_INCREF(Py_None);
				PyTuple_SET_ITEM(pArgs, i, Py_None);
				Py_DECREF(pPair);
			}
		}
	}
	
	/* Call Python function. */
	pRet = PyObject_CallFunctionObjArgs(pFunc, pArgs, NULL);
	
	if (!pRet)
		goto failed;
	
	if (!request)
		goto okay;

	/*
	 *	The function returns either:
	 *  1. (returnvalue, replyTuple, configTuple), where
	 *   - returnvalue is one of the constants RLM_*
	 *   - replyTuple and configTuple are tuples of string
	 *      tuples of size 2
	 *
	 *  2. the function return value alone
	 *
	 *  3. None - default return value is set
	 *
	 * xxx This code is messy!
	 */
	if (PyTuple_CheckExact(pRet)) {
		PyObject *pTupleInt;
		
		if (PyTuple_GET_SIZE(pRet) != 3) {
			ERROR("rlm_python:%s: tuple must be (return, replyTuple, configTuple)", funcname);
			goto failed;
		}
		
		pTupleInt = PyTuple_GET_ITEM(pRet, 0);
		if (!PyInt_CheckExact(pTupleInt)) {
			ERROR("rlm_python:%s: first tuple element not an integer", funcname);
			goto failed;
		}
		/* Now have the return value */
		ret = PyInt_AsLong(pTupleInt);
		/* Reply item tuple */
		mod_vptuple(request->reply, &request->reply->vps,
			    PyTuple_GET_ITEM(pRet, 1), funcname);
		/* Config item tuple */
		mod_vptuple(request, &request->config_items,
			    PyTuple_GET_ITEM(pRet, 2), funcname);

	} else if (PyInt_CheckExact(pRet)) {
		/* Just an integer */
		ret = PyInt_AsLong(pRet);

	} else if (pRet == Py_None) {
		/* returned 'None', return value defaults to "OK, continue." */
		ret = RLM_MODULE_OK;
	} else {
		/* Not tuple or None */
		ERROR("rlm_python:%s: function did not return a tuple or None", funcname);
		goto failed;
	}

okay:
	Py_DECREF(pArgs);
	Py_DECREF(pRet);
	PyGILState_Release(gstate);
	return ret;
	
failed:
	mod_error();
	Py_XDECREF(pArgs);
	Py_XDECREF(pRet);
	PyGILState_Release(gstate);
	
	return -1;
}
Example #25
0
static rlm_rcode_t do_python(rlm_python_t *inst, REQUEST *request, PyObject *pFunc, char const *funcname, bool worker)
{
	vp_cursor_t	cursor;
	VALUE_PAIR      *vp;
	PyObject	*pRet = NULL;
	PyObject	*pArgs = NULL;
	int		tuplelen;
	int		ret;

	PyGILState_STATE gstate;
	PyThreadState	*prev_thread_state = NULL;	/* -Wuninitialized */
	memset(&gstate, 0, sizeof(gstate));		/* -Wuninitialized */

	/* Return with "OK, continue" if the function is not defined. */
	if (!pFunc)
		return RLM_MODULE_NOOP;

#ifdef HAVE_PTHREAD_H
	gstate = PyGILState_Ensure();
	if (worker) {
		PyThreadState *my_thread_state;
		my_thread_state = fr_thread_local_init(local_thread_state, do_python_cleanup);
		if (!my_thread_state) {
			my_thread_state = PyThreadState_New(inst->main_thread_state->interp);
			if (!my_thread_state) {
				REDEBUG("Failed initialising local PyThreadState on first run");
				PyGILState_Release(gstate);
				return RLM_MODULE_FAIL;
			}

			ret = fr_thread_local_set(local_thread_state, my_thread_state);
			if (ret != 0) {
				REDEBUG("Failed storing PyThreadState in TLS: %s", fr_syserror(ret));
				PyThreadState_Clear(my_thread_state);
				PyThreadState_Delete(my_thread_state);
				PyGILState_Release(gstate);
				return RLM_MODULE_FAIL;
			}
		}
		prev_thread_state = PyThreadState_Swap(my_thread_state);	/* Swap in our local thread state */
	}
#endif

	/* Default return value is "OK, continue" */
	ret = RLM_MODULE_OK;

	/*
	 *	We will pass a tuple containing (name, value) tuples
	 *	We can safely use the Python function to build up a
	 *	tuple, since the tuple is not used elsewhere.
	 *
	 *	Determine the size of our tuple by walking through the packet.
	 *	If request is NULL, pass None.
	 */
	tuplelen = 0;
	if (request != NULL) {
		for (vp = paircursor(&cursor, &request->packet->vps);
		     vp;
		     vp = pairnext(&cursor)) {
			tuplelen++;
		}
	}

	if (tuplelen == 0) {
		Py_INCREF(Py_None);
		pArgs = Py_None;
	} else {
		int i = 0;
		if ((pArgs = PyTuple_New(tuplelen)) == NULL) {
			ret = RLM_MODULE_FAIL;
			goto finish;
		}

		for (vp = paircursor(&cursor, &request->packet->vps);
		     vp;
		     vp = pairnext(&cursor), i++) {
			PyObject *pPair;

			/* The inside tuple has two only: */
			if ((pPair = PyTuple_New(2)) == NULL) {
				ret = RLM_MODULE_FAIL;
				goto finish;
			}

			if (mod_populate_vptuple(pPair, vp) == 0) {
				/* Put the tuple inside the container */
				PyTuple_SET_ITEM(pArgs, i, pPair);
			} else {
				Py_INCREF(Py_None);
				PyTuple_SET_ITEM(pArgs, i, Py_None);
				Py_DECREF(pPair);
			}
		}
	}

	/* Call Python function. */
	pRet = PyObject_CallFunctionObjArgs(pFunc, pArgs, NULL);

	if (!pRet) {
		ret = RLM_MODULE_FAIL;
		goto finish;
	}

	if (!request)
		goto finish;

	/*
	 *	The function returns either:
	 *  1. (returnvalue, replyTuple, configTuple), where
	 *   - returnvalue is one of the constants RLM_*
	 *   - replyTuple and configTuple are tuples of string
	 *      tuples of size 2
	 *
	 *  2. the function return value alone
	 *
	 *  3. None - default return value is set
	 *
	 * xxx This code is messy!
	 */
	if (PyTuple_CheckExact(pRet)) {
		PyObject *pTupleInt;

		if (PyTuple_GET_SIZE(pRet) != 3) {
			ERROR("rlm_python:%s: tuple must be (return, replyTuple, configTuple)", funcname);
			ret = RLM_MODULE_FAIL;
			goto finish;
		}

		pTupleInt = PyTuple_GET_ITEM(pRet, 0);
		if (!PyInt_CheckExact(pTupleInt)) {
			ERROR("rlm_python:%s: first tuple element not an integer", funcname);
			ret = RLM_MODULE_FAIL;
			goto finish;
		}
		/* Now have the return value */
		ret = PyInt_AsLong(pTupleInt);
		/* Reply item tuple */
		mod_vptuple(request->reply, &request->reply->vps,
			    PyTuple_GET_ITEM(pRet, 1), funcname);
		/* Config item tuple */
		mod_vptuple(request, &request->config_items,
			    PyTuple_GET_ITEM(pRet, 2), funcname);

	} else if (PyInt_CheckExact(pRet)) {
		/* Just an integer */
		ret = PyInt_AsLong(pRet);

	} else if (pRet == Py_None) {
		/* returned 'None', return value defaults to "OK, continue." */
		ret = RLM_MODULE_OK;
	} else {
		/* Not tuple or None */
		ERROR("rlm_python:%s: function did not return a tuple or None", funcname);
		ret = RLM_MODULE_FAIL;
		goto finish;
	}

finish:
	if (pArgs) {
		Py_DECREF(pArgs);
	}
	if (pRet) {
		Py_DECREF(pRet);
	}

#ifdef HAVE_PTHREAD_H
	if (worker) {
		PyThreadState_Swap(prev_thread_state);
	}
	PyGILState_Release(gstate);
#endif

	return ret;
}
Example #26
0
static PyObject *py_sorted_tree_items(PyObject *self, PyObject *entries)
{
    struct tree_item *qsort_entries;
    int num, i;
    PyObject *ret;
    Py_ssize_t pos = 0;
    PyObject *key, *value;

    if (!PyDict_Check(entries)) {
        PyErr_SetString(PyExc_TypeError, "Argument not a dictionary");
        return NULL;
    }

    num = PyDict_Size(entries);
    qsort_entries = malloc(num * sizeof(struct tree_item));
    if (qsort_entries == NULL) {
        PyErr_NoMemory();
        return NULL;
    }

    i = 0;
    while (PyDict_Next(entries, &pos, &key, &value)) {
        PyObject *py_mode, *py_sha;

        if (PyTuple_Size(value) != 2) {
            PyErr_SetString(PyExc_ValueError, "Tuple has invalid size");
            free(qsort_entries);
            return NULL;
        }

        py_mode = PyTuple_GET_ITEM(value, 0);
        py_sha = PyTuple_GET_ITEM(value, 1);
        qsort_entries[i].tuple = Py_BuildValue("(OOO)", key, py_mode, py_sha);
        if (!PyString_CheckExact(key)) {
            PyErr_SetString(PyExc_TypeError, "Name is not a string");
            free(qsort_entries);
            return NULL;
        }
        qsort_entries[i].name = PyString_AS_STRING(key);
        if (!PyInt_CheckExact(py_mode)) {
            PyErr_SetString(PyExc_TypeError, "Mode is not an int");
            free(qsort_entries);
            return NULL;
        }
        qsort_entries[i].mode = PyInt_AS_LONG(py_mode);
        i++;
    }

    qsort(qsort_entries, num, sizeof(struct tree_item), cmp_tree_item);

    ret = PyList_New(num);
    if (ret == NULL) {
        free(qsort_entries);
        PyErr_NoMemory();
        return NULL;
    }

    for (i = 0; i < num; i++) {
        PyList_SET_ITEM(ret, i, qsort_entries[i].tuple);
    }

    free(qsort_entries);

    return ret;
}
Example #27
0
static PyObject *
ip_store_load(PyObject *self, PyObject *o){

    PyObject *record, *item, *item2;
    Py_ssize_t size, i, j;
    unsigned long ip_ul;
    ip_seg* new_db = NULL;

    if(!PySequence_Check(o)){
        PyErr_SetString(PyExc_TypeError, "need sequence");
        return NULL;
    }

    size = PySequence_Length(o);
    if(size < 0){
        return NULL;
    }else if (size == 0){
        goto finish;
    }

    new_db = (ip_seg*)PyMem_Malloc(size * sizeof(ip_seg));
    if(new_db == NULL){
        return PyErr_NoMemory();
    }else{
        for(i = 0; i < size; i++){
            new_db[i].area = NULL;
            new_db[i].isp = NULL;
        }
    }

    for(i = 0; i < size; i++){
        record = PySequence_GetItem(o, i);
        if (!PySequence_Check(record)){
            PyErr_SetString(PyExc_TypeError, "need sequence for each record");
            goto record_failed;
        }

        for(j = 0; j < 2; j++){
            item = PySequence_GetItem(record, j);
            if(item == NULL){
                goto record_failed;
            }
#ifdef IS_PY3K
            if(!PyLong_Check(item)){
#else
            if(!PyInt_CheckExact(item)){
#endif
                Py_DECREF(item);
                PyErr_Format(PyExc_TypeError,
                             "expected int, %s found",
                             Py_TYPE(item)->tp_name); 
                goto record_failed;
            }

#ifdef IS_PY3K
            ip_ul = PyLong_AsUnsignedLong(item);
            if (ip_ul == (unsigned long) -1 && PyErr_Occurred()){
                Py_DECREF(item);
                goto record_failed;
            }
#else
            ip_ul = PyInt_AsUnsignedLongMask(item);
#endif

            ((unsigned long *)(new_db + i))[j] = ip_ul;
            Py_DECREF(item);
        }

        item = PySequence_GetItem(record, 2);
        item2 = PySequence_GetItem(record, 3);
        if(item == NULL || item2 == NULL){
            Py_XDECREF(item);
            Py_XDECREF(item2);
            goto record_failed;
        }
        new_db[i].area = item;
        new_db[i].isp = item2;
    }
    
finish:    
    free_db(ipdb, ipdb_size);
    ipdb_size = size;
    ipdb = new_db;
    Py_RETURN_NONE;
record_failed:
    Py_XDECREF(record);
    free_db(new_db, size);
    return NULL;
}


static PyObject *
ip_store_get(PyObject *self, PyObject *o){

    Py_ssize_t i;

#ifdef IS_PY3K
    if(!PyLong_Check(o)){
#else
    if(!PyInt_CheckExact(o)){
#endif
        PyErr_SetString(PyExc_TypeError, "need int");
        return NULL;
    }

#ifdef IS_PY3K
    i = PyLong_AsSsize_t(o);
    if(PyErr_Occurred()){
        return NULL;
    }
#else
    i = PyInt_AsSsize_t(o);
#endif

    if (i < 0 || i > ipdb_size -1){
        PyErr_SetString(PyExc_IndexError, "");
        return NULL;
    }

    return build_record(ipdb[i]);
}


static PyObject *
ip_store_search(PyObject *self, PyObject *o){

    int found = 0;
    unsigned long ip_ul;
    Py_ssize_t begin = 0, end = ipdb_size -1, mid;
    ip_seg *m_record;
    PyObject *result;

    if (ipdb_size == 0){
        Py_RETURN_NONE;
    }

    if(!inner_atohl(o, &ip_ul)){
        return NULL;
    }

    /* releasing GIL has been tested in the situation where there is
     * no IO operation. The result is that releasing GIL make worse
     * performance */

    /*
    Py_INCREF(o);
    Py_BEGIN_ALLOW_THREADS */

    while(begin <= end){
        mid = (begin + end)/2;
        m_record = ipdb + mid;

        if (ip_ul < m_record->begin){
            end = mid - 1;
        } else if (ip_ul > m_record->end){
            begin = mid + 1;
        } else{
            if (ip_ul <= m_record->end && ip_ul >= m_record->begin){
                found = 1;
            }
            break;
        }
    }

    /*
    Py_END_ALLOW_THREADS
    Py_DECREF(o); */

    if (found){
        result = PyTuple_New(2);
        if (result == NULL){
            return NULL;
        }

        Py_INCREF(m_record->area);
        Py_INCREF(m_record->isp);
        PyTuple_SetItem(result, 0, m_record->area);
        PyTuple_SetItem(result, 1, m_record->isp);

        return result;
    } else {
        Py_RETURN_NONE;
    }
}
Example #28
0
static PyObject *
eval_frame(PyFrameObject *f)
{
	LOG("> eval_frame\n"); {
	PyObject **stack_pointer; /* Next free slot in value stack */
	register unsigned char *next_instr;
	register int opcode=0;	/* Current opcode */
	register int oparg=0;	/* Current opcode argument, if any */
	register enum why_code why; /* Reason for block stack unwind */
	register int err;	/* Error status -- nonzero if error */
	register PyObject *x;	/* Result object -- NULL if error */
	register PyObject *t, *u, *v;	/* Temporary objects popped off stack */
	register PyObject *w;
	register PyObject **fastlocals, **freevars;
	PyObject *retval = NULL;	/* Return value */
	PyThreadState *tstate = PyThreadState_GET();
	PyCodeObject *co;

	unsigned char *first_instr;
	PyObject *names;
	PyObject *consts;

/* Tuple access macros */

#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))

/* Code access macros */

#define INSTR_OFFSET()	(next_instr - first_instr)
#define NEXTOP()	(*next_instr++)
#define NEXTARG()	(next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
#define JUMPTO(x)	(next_instr = first_instr + (x))
#define JUMPBY(x)	(next_instr += (x))

/* OpCode prediction macros
	Some opcodes tend to come in pairs thus making it possible to predict
	the second code when the first is run.  For example, COMPARE_OP is often
	followed by JUMP_IF_FALSE or JUMP_IF_TRUE.  And, those opcodes are often
	followed by a POP_TOP.

	Verifying the prediction costs a single high-speed test of register
	variable against a constant.  If the pairing was good, then the
	processor has a high likelihood of making its own successful branch
	prediction which results in a nearly zero overhead transition to the
	next opcode.

	A successful prediction saves a trip through the eval-loop including
	its two unpredictable branches, the HASARG test and the switch-case.
*/

#define PREDICT(op)		if (*next_instr == op) goto PRED_##op
#define PREDICTED(op)		PRED_##op: next_instr++
#define PREDICTED_WITH_ARG(op)	PRED_##op: oparg = (next_instr[2]<<8) + \
				next_instr[1]; next_instr += 3

/* Stack manipulation macros */

#define STACK_LEVEL()	(stack_pointer - f->f_valuestack)
#define EMPTY()		(STACK_LEVEL() == 0)
#define TOP()		(stack_pointer[-1])
#define SECOND()	(stack_pointer[-2])
#define THIRD() 	(stack_pointer[-3])
#define FOURTH()	(stack_pointer[-4])
#define SET_TOP(v)	(stack_pointer[-1] = (v))
#define SET_SECOND(v)	(stack_pointer[-2] = (v))
#define SET_THIRD(v)	(stack_pointer[-3] = (v))
#define SET_FOURTH(v)	(stack_pointer[-4] = (v))
#define BASIC_STACKADJ(n)	(stack_pointer += n)
#define BASIC_PUSH(v)	(*stack_pointer++ = (v))
#define BASIC_POP()	(*--stack_pointer)

#define PUSH(v)		BASIC_PUSH(v)
#define POP()		BASIC_POP()
#define STACKADJ(n)	BASIC_STACKADJ(n)

/* Local variable macros */

#define GETLOCAL(i)	(fastlocals[i])

/* The SETLOCAL() macro must not DECREF the local variable in-place and
   then store the new value; it must copy the old value to a temporary
   value, then store the new value, and then DECREF the temporary value.
   This is because it is possible that during the DECREF the frame is
   accessed by other code (e.g. a __del__ method or gc.collect()) and the
   variable would be pointing to already-freed memory. */
#define SETLOCAL(i, value)	do { PyObject *tmp = GETLOCAL(i); \
				     GETLOCAL(i) = value; \
                                     Py_XDECREF(tmp); } while (0)

/* Start of code */

	if (f == NULL)
		return NULL;

	/* push frame */
	if (++tstate->recursion_depth > recursion_limit) {
		--tstate->recursion_depth;
		/* ERROR */
		tstate->frame = f->f_back;
		return NULL;
	}

	tstate->frame = f;

	/* tracing elided */

	co = f->f_code;
	names = co->co_names;
	consts = co->co_consts;
	fastlocals = f->f_localsplus;
	freevars = f->f_localsplus + f->f_nlocals;

	_PyCode_GETCODEPTR(co, &first_instr);

	/* An explanation is in order for the next line.

	   f->f_lasti now refers to the index of the last instruction
	   executed.  You might think this was obvious from the name, but
	   this wasn't always true before 2.3!  PyFrame_New now sets
	   f->f_lasti to -1 (i.e. the index *before* the first instruction)
	   and YIELD_VALUE doesn't fiddle with f_lasti any more.  So this
	   does work.  Promise. */
	next_instr = first_instr + f->f_lasti + 1;
	stack_pointer = f->f_stacktop;

	f->f_stacktop = NULL;	/* remains NULL unless yield suspends frame */

	why = WHY_NOT;
	err = 0;
	x = Py_None;	/* Not a reference, just anything non-NULL */
	w = NULL;

	for (;;) {

		/* Do periodic things.  Doing this every time through
		   the loop would add too much overhead, so we do it
		   only every Nth instruction.  We also do it if
		   ``things_to_do'' is set, i.e. when an asynchronous
		   event needs attention (e.g. a signal handler or
		   async I/O handler); see Py_AddPendingCall() and
		   Py_MakePendingCalls() above. */

		if (--_Py_Ticker < 0) {
			/* @@@ check for SETUP_FINALLY elided */

			_Py_Ticker = _Py_CheckInterval;
			tstate->tick_counter++;
			if (things_to_do) {
				if (Py_MakePendingCalls() < 0) {
					why = WHY_EXCEPTION;
					goto on_error;
				}
			}
		}

	fast_next_opcode:
		f->f_lasti = INSTR_OFFSET();

		/* Extract opcode and argument */

		opcode = NEXTOP();
		if (HAS_ARG(opcode))
			oparg = NEXTARG();

		/* Main switch on opcode */

		switch (opcode) {

		/* BEWARE!
		   It is essential that any operation that fails sets either
		   x to NULL, err to nonzero, or why to anything but WHY_NOT,
		   and that no operation that succeeds does this! */

		/* case STOP_CODE: this is an error! */

		case LOAD_FAST:
			x = GETLOCAL(oparg);
			if (x != NULL) {
				Py_INCREF(x);
				PUSH(x);
				goto fast_next_opcode;
			}
			/* ERROR? */
			break;

                case STORE_FAST:
                        v = POP();
                        SETLOCAL(oparg, v);
                        continue;

		case LOAD_CONST:
			x = GETITEM(consts, oparg);
			Py_INCREF(x);
			PUSH(x);
			goto fast_next_opcode;

		PREDICTED(POP_TOP);
		case POP_TOP:
			v = POP();
			Py_DECREF(v);
			goto fast_next_opcode;

		case UNARY_NOT:
			v = TOP();
			err = PyObject_IsTrue(v);
			Py_DECREF(v);
			if (err == 0) {
				Py_INCREF(Py_True);
				SET_TOP(Py_True);
				continue;
			}
			else if (err > 0) {
				Py_INCREF(Py_False);
				SET_TOP(Py_False);
				err = 0;
				continue;
			}
			STACKADJ(-1);
			break;

		case BINARY_MODULO:
			w = POP();
			v = TOP();
			x = PyNumber_Remainder(v, w);
			Py_DECREF(v);
			Py_DECREF(w);
			SET_TOP(x);
			if (x != NULL) continue;
			break;
			
		case BINARY_ADD:
			w = POP();
			v = TOP();
			if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
				/* INLINE: int + int */
				register long a, b, i;
				a = PyInt_AS_LONG(v);
				b = PyInt_AS_LONG(w);
				i = a + b;
				if ((i^a) < 0 && (i^b) < 0)
					goto slow_add;
				x = PyInt_FromLong(i);
			}
			else {
			  slow_add:
				Py_FatalError("slow add not supported.");
			}
			Py_DECREF(v);
			Py_DECREF(w);
			SET_TOP(x);
			if (x != NULL) continue;
			break;

                case STORE_SLICE+0:
                case STORE_SLICE+1:
                case STORE_SLICE+2:
                case STORE_SLICE+3:
                        if ((opcode-STORE_SLICE) & 2)
                                w = POP();
                        else
                                w = NULL;
                        if ((opcode-STORE_SLICE) & 1)
                                v = POP();
                        else
                                v = NULL;
                        u = POP();
                        t = POP();
                        err = assign_slice(u, v, w, t); /* u[v:w] = t */
                        Py_DECREF(t);
                        Py_DECREF(u);
                        Py_XDECREF(v);
                        Py_XDECREF(w);
                        if (err == 0) continue;
                        break;

                case STORE_SUBSCR:
                        w = POP();
                        v = POP();
                        u = POP();
                        /* v[w] = u */
                        err = PyObject_SetItem(v, w, u);
                        Py_DECREF(u);
                        Py_DECREF(v);
                        Py_DECREF(w);
                        if (err == 0) continue;
                        break;

                case BINARY_SUBSCR:
                        w = POP();
                        v = TOP();
                        if (PyList_CheckExact(v) && PyInt_CheckExact(w)) {
                                /* INLINE: list[int] */
                                long i = PyInt_AsLong(w);
                                if (i < 0)
                                        i += PyList_GET_SIZE(v);
                                if (i < 0 ||
                                    i >= PyList_GET_SIZE(v)) {
                                        /* ERROR */
                                        printf("list index out of range\n");
                                        x = NULL;
                                }
                                else {
                                        x = PyList_GET_ITEM(v, i);
                                        Py_INCREF(x);
                                }
                        }
                        else
                                x = PyObject_GetItem(v, w);
                        Py_DECREF(v);
                        Py_DECREF(w);
                        SET_TOP(x);
                        if (x != NULL) continue;
                        break;

		case BINARY_AND:
			w = POP();
			v = TOP();
			x = PyNumber_And(v, w);
			Py_DECREF(v);
			Py_DECREF(w);
			SET_TOP(x);
			if (x != NULL) continue;
			break;

		case PRINT_ITEM:
			v = POP();

			PyObject_Print(v);
			Py_DECREF(v);
			break;

		case PRINT_NEWLINE:
			printf("\n");
			break;

		case RETURN_VALUE:
			retval = POP();
			why = WHY_RETURN;
			break;

		case POP_BLOCK:
			{
				PyTryBlock *b = PyFrame_BlockPop(f);
				while (STACK_LEVEL() > b->b_level) {
					v = POP();
					Py_DECREF(v);
				}
			}
			break;

		case STORE_NAME:
			w = GETITEM(names, oparg);
			v = POP();
			if ((x = f->f_locals) == NULL) {
				/* ERROR */
				printf("STORE_NAME ERROR\n");
				break;
			}
			err = PyDict_SetItem(x, w, v);
			Py_DECREF(v);
			break;

		case LOAD_NAME:
			w = GETITEM(names, oparg);
			if ((x = f->f_locals) == NULL) {
				/* ERROR */
				printf("LOAD_NAME ERROR\n");
				break;
			}
			x = PyDict_GetItem(x, w);
			if (x == NULL) {
				x = PyDict_GetItem(f->f_globals, w);
				if (x == NULL) {
					x = PyDict_GetItem(f->f_builtins, w);
					if (x == NULL) {
						printf("can't find %s\n", ((PyStringObject *)w)->ob_sval);
						/* format_exc_check_arg */
						break;
					}
				}
			}
			Py_INCREF(x);
			PUSH(x);
			break;
			
		case LOAD_GLOBAL:
			w = GETITEM(names, oparg);
			if (PyString_CheckExact(w)) {
				/* Inline the PyDict_GetItem() calls.
				   WARNING: this is an extreme speed hack.
				   Do not try this at home. */
				long hash = ((PyStringObject *)w)->ob_shash;
				if (hash != -1) {
					PyDictObject *d;
					d = (PyDictObject *)(f->f_globals);
					x = d->ma_lookup(d, w, hash)->me_value;
					if (x != NULL) {
						Py_INCREF(x);
						PUSH(x);
						continue;
					}
					d = (PyDictObject *)(f->f_builtins);
					x = d->ma_lookup(d, w, hash)->me_value;
					if (x != NULL) {
						Py_INCREF(x);
						PUSH(x);
						continue;
					}
					goto load_global_error;
				}
			}
			/* This is the un-inlined version of the code above */
			x = PyDict_GetItem(f->f_globals, w);
			if (x == NULL) {
				x = PyDict_GetItem(f->f_builtins, w);
				if (x == NULL) {
				  load_global_error:
					printf("LOAD_GLOBAL ERROR %s", ((PyStringObject *)w)->ob_sval);
					break;
				}
			}
			Py_INCREF(x);
			PUSH(x);
			break;

		case LOAD_ATTR:
			w = GETITEM(names, oparg);
			v = TOP();
			x = PyObject_GetAttr(v, w);
			Py_DECREF(v);
			SET_TOP(x);
			if (x != NULL) continue;
			break;

		case IMPORT_NAME:
			w = GETITEM(names, oparg);
			x = PyDict_GetItemString(f->f_builtins, "__import__");
			if (x == NULL) {
				printf("__import__ not found");
				break;
			}
			u = TOP();
			w = Py_BuildValue("(O)", w);
			Py_DECREF(u);
			if (w == NULL) {
				u = POP();
				x = NULL;
				break;
			}
			x = PyEval_CallObject(x, w);
			Py_DECREF(w);
			SET_TOP(x);
			if (x != NULL) continue;
			break;

		case JUMP_FORWARD:
			JUMPBY(oparg);
			goto fast_next_opcode;

		PREDICTED_WITH_ARG(JUMP_IF_FALSE);
		case JUMP_IF_FALSE:
			w = TOP();
			if (w == Py_True) {
				PREDICT(POP_TOP);
				goto fast_next_opcode;
			}
			if (w == Py_False) {
				JUMPBY(oparg);
				goto fast_next_opcode;
			}
			err = PyObject_IsTrue(w);
			if (err > 0)
				err = 0;
			else if (err == 0)
				JUMPBY(oparg);
			else
				break;
			continue;
			
		case JUMP_ABSOLUTE:
			JUMPTO(oparg);
			continue;

		case SETUP_LOOP:
			PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg, STACK_LEVEL());
			continue;

		case CALL_FUNCTION:
			x = call_function(&stack_pointer, oparg);
			PUSH(x);
			if (x != NULL)
				continue;
			break;
			
		case MAKE_FUNCTION:
			v = POP(); /* code object */
			x = PyFunction_New(v, f->f_globals);
			Py_DECREF(v);
			/* XXX Maybe this should be a separate opcode? */
			if (x != NULL && oparg > 0) {
				v = PyTuple_New(oparg);
				if (v == NULL) {
					Py_DECREF(x);
					x = NULL;
			break;
				}
				while (--oparg >= 0) {
					w = POP();
					PyTuple_SET_ITEM(v, oparg, w);
				}
				err = PyFunction_SetDefaults(x, v);
				Py_DECREF(v);
			}
			PUSH(x);
			break;
			
		case SET_LINENO:
			break;

		default:
			printf("opcode: %d\n", opcode);
			Py_FatalError("unknown opcode");
		} /* switch */

	  on_error:
		
		if (why == WHY_NOT) {
			if (err == 0 && x != NULL) {
					continue; /* Normal, fast path */
			}
			why = WHY_EXCEPTION;
			x = Py_None;
			err = 0;
		}

		/* End the loop if we still have an error (or return) */

		if (why != WHY_NOT)
			break;

	} /* main loop */

	if (why != WHY_YIELD) {
		/* Pop remaining stack entries -- but when yielding */
		while (!EMPTY()) {
			v = POP();
			Py_XDECREF(v);
		}
	}

	if (why != WHY_RETURN && why != WHY_YIELD)
		retval = NULL;

	/* pop frame */
	--tstate->recursion_depth;
	tstate->frame = f->f_back;

	return retval;
}}
Example #29
0
NUITKA_MAY_BE_UNUSED static bool BINARY_OPERATION_ADD_INPLACE( PyObject **operand1, PyObject *operand2 )
{
    assert( operand1 );
    CHECK_OBJECT( *operand1 );
    CHECK_OBJECT( operand2 );

#if PYTHON_VERSION < 300
    // Something similar for Python3 should exist too.
    if ( PyInt_CheckExact( *operand1 ) && PyInt_CheckExact( operand2 ) )
    {
        long a, b, i;

        a = PyInt_AS_LONG( *operand1 );
        b = PyInt_AS_LONG( operand2 );

        i = a + b;

        // Detect overflow, in which case, a "long" object would have to be
        // created, which we won't handle here. TODO: Add an else for that
        // case.
        if (likely(!( (i^a) < 0 && (i^b) < 0 ) ))
        {
            PyObject *result = PyInt_FromLong( i );
            Py_DECREF( *operand1 );

            *operand1 = result;

            return true;
        }
    }
#endif

#if PYTHON_VERSION < 300
    if ( Py_REFCNT( *operand1 ) == 1 )
    {
        // We more or less own the operand, so we might re-use its storage and
        // execute stuff in-place.
        if ( PyString_CheckExact( *operand1 ) &&
             !PyString_CHECK_INTERNED( *operand1 ) &&
             PyString_CheckExact( operand2 ) )
        {
            return STRING_ADD_INCREMENTAL( operand1, operand2 );
        }
        else if ( PyFloat_CheckExact( *operand1 ) &&
                  PyFloat_CheckExact( operand2 ) )
        {
            return FLOAT_ADD_INCREMENTAL( operand1, operand2 );

        }
    }

    // Strings are to be treated differently.
    if ( PyString_CheckExact( *operand1 ) && PyString_CheckExact( operand2 ) )
    {
        PyString_Concat( operand1, operand2 );
        return !ERROR_OCCURRED();
    }
#else
    if ( Py_REFCNT( *operand1 ) == 1 )
    {
        // We more or less own the operand, so we might re-use its storage and
        // execute stuff in-place.
        if ( PyUnicode_CheckExact( *operand1 ) &&
             !PyUnicode_CHECK_INTERNED( *operand1 ) &&
             PyUnicode_CheckExact( operand2 ) )
        {
            return UNICODE_ADD_INCREMENTAL( operand1, operand2 );
        }
        else if ( PyFloat_CheckExact( *operand1 ) &&
                  PyFloat_CheckExact( operand2 ) )
        {
            return FLOAT_ADD_INCREMENTAL( operand1, operand2 );
        }
    }

    // Strings are to be treated differently.
    if ( PyUnicode_CheckExact( *operand1 ) && PyUnicode_CheckExact( operand2 ) )
    {
        PyObject *result = PyUnicode_Concat( *operand1, operand2 );

        if (unlikely( result == NULL ))
        {
            return false;
        }

        Py_DECREF( *operand1 );
        *operand1 = result;

        return true;
    }
#endif

    PyObject *result = PyNumber_InPlaceAdd( *operand1, operand2 );

    if (unlikely( result == NULL ))
    {
        return false;
    }

    // We got an object handed, that we have to release.
    Py_DECREF( *operand1 );

    // That's our return value then. As we use a dedicated variable, it's
    // OK that way.
    *operand1 = result;

    return true;
}
Example #30
0
NUITKA_MAY_BE_UNUSED static PyObject *BINARY_OPERATION_ADD( PyObject *operand1, PyObject *operand2 )
{
    CHECK_OBJECT( operand1 );
    CHECK_OBJECT( operand2 );

#if PYTHON_VERSION < 300
    // Something similar for Python3 should exist too.
    if ( PyInt_CheckExact( operand1 ) && PyInt_CheckExact( operand2 ) )
    {
        long a, b, i;

        a = PyInt_AS_LONG( operand1 );
        b = PyInt_AS_LONG( operand2 );

        i = a + b;

        // Detect overflow, in which case, a "long" object would have to be
        // created, which we won't handle here.
        if (likely(!( (i^a) < 0 && (i^b) < 0 ) ))
        {
            return PyInt_FromLong( i );
        }
    }
#endif

    binaryfunc slot1 = NULL;
    binaryfunc slot2 = NULL;

    PyTypeObject *type1 = Py_TYPE( operand1 );
    PyTypeObject *type2 = Py_TYPE( operand2 );

    if ( type1->tp_as_number != NULL && NEW_STYLE_NUMBER( operand1 ) )
    {
        slot1 = type1->tp_as_number->nb_add;
    }

    if ( type1 != type2 )
    {
        if ( type2->tp_as_number != NULL && NEW_STYLE_NUMBER( operand2 ) )
        {
            slot2 = type2->tp_as_number->nb_add;

            if ( slot1 == slot2 )
            {
                slot2 = NULL;
            }
        }
    }

    if ( slot1 != NULL )
    {
        if ( slot2 && PyType_IsSubtype( type2, type1 ) )
        {
            PyObject *x = slot2( operand1, operand2 );

            if ( x != Py_NotImplemented )
            {
                if (unlikely( x == NULL ))
                {
                    return NULL;
                }

                return x;
            }

            Py_DECREF( x );
            slot2 = NULL;
        }

        PyObject *x = slot1( operand1, operand2 );

        if ( x != Py_NotImplemented )
        {
            if (unlikely( x == NULL ))
            {
                return NULL;
            }

            return x;
        }

        Py_DECREF( x );
    }

    if ( slot2 != NULL )
    {
        PyObject *x = slot2( operand1, operand2 );

        if ( x != Py_NotImplemented )
        {
            if (unlikely( x == NULL ))
            {
                return NULL;
            }

            return x;
        }

        Py_DECREF( x );
    }

#if PYTHON_VERSION < 300
    if ( !NEW_STYLE_NUMBER( operand1 ) || !NEW_STYLE_NUMBER( operand2 ) )
    {
        int err = PyNumber_CoerceEx( &operand1, &operand2 );

        if ( err < 0 )
        {
            return NULL;
        }

        if ( err == 0 )
        {
            PyNumberMethods *mv = Py_TYPE( operand1 )->tp_as_number;

            if ( mv )
            {
                binaryfunc slot = mv->nb_add;

                if ( slot != NULL )
                {
                    PyObject *x = slot( operand1, operand2 );

                    Py_DECREF( operand1 );
                    Py_DECREF( operand2 );

                    if (unlikely( x == NULL ))
                    {
                        return NULL;
                    }

                    return x;
                }
            }

            // CoerceEx did that
            Py_DECREF( operand1 );
            Py_DECREF( operand2 );
        }
    }
#endif

    // Special case for "+", also works as sequence concat.
    PySequenceMethods *seq_methods = Py_TYPE( operand1 )->tp_as_sequence;

    if ( seq_methods && seq_methods->sq_concat )
    {
        PyObject *result = (*seq_methods->sq_concat)( operand1, operand2 );

        if (unlikely( result == NULL ))
        {
            return NULL;
        }

        return result;
    }

    PyErr_Format(
        PyExc_TypeError,
        "unsupported operand type(s) for +: '%s' and '%s'",
        type1->tp_name,
        type2->tp_name
    );

    return NULL;
}