diff options
| -rw-r--r-- | miasm/jitter/compat_py23.h | 88 |
1 files changed, 79 insertions, 9 deletions
diff --git a/miasm/jitter/compat_py23.h b/miasm/jitter/compat_py23.h index 60cf8c96..596f14cc 100644 --- a/miasm/jitter/compat_py23.h +++ b/miasm/jitter/compat_py23.h @@ -1,14 +1,48 @@ #ifndef __COMPAT_PY23_H__ #define __COMPAT_PY23_H__ - - #if PY_MAJOR_VERSION >= 3 +#include "bn.h" #define PyGetInt_uint_t(size_type, item, value) \ if (PyLong_Check(item)) { \ - unsigned long long tmp; \ - tmp = PyLong_AsLongLong(item); \ - if ( tmp > (size_type) -1) { \ + bn_t bn; \ + int j; \ + PyObject* py_long = item; \ + PyObject* py_long_new; \ + PyObject* py_tmp; \ + PyObject* cst_32; \ + PyObject* cst_ffffffff; \ + uint64_t tmp; \ + cst_ffffffff = PyLong_FromLong(0xffffffff); \ + cst_32 = PyLong_FromLong(32); \ + bn = bignum_from_int(0); \ + int neg = 0; \ + \ + if (Py_SIZE(py_long) < 0) { \ + neg = 1; \ + py_long_new = PyObject_CallMethod(py_long, "__neg__", NULL); \ + Py_DECREF(py_long); \ + py_long = py_long_new; \ + } \ + \ + for (j = 0; j < BN_BYTE_SIZE; j += 4) { \ + py_tmp = PyObject_CallMethod(py_long, "__and__", "O", cst_ffffffff); \ + py_long_new = PyObject_CallMethod(py_long, "__rshift__", "O", cst_32); \ + Py_DECREF(py_long); \ + py_long = py_long_new; \ + tmp = PyLong_AsUnsignedLongLongMask(py_tmp); \ + Py_DECREF(py_tmp); \ + bn = bignum_or(bn, bignum_lshift(bignum_from_uint64(tmp), 8 * j)); \ + } \ + tmp = bignum_to_uint64(bn); \ + \ + if (neg) { \ + if ( tmp > (size_type) -1) { \ + RAISE(PyExc_TypeError, "Arg too big for " #size_type ""); \ + } \ + tmp = (1<<(sizeof(size_type)*8))-tmp; \ + } \ + else if ( tmp > (size_type) -1) { \ RAISE(PyExc_TypeError, "Arg too big for " #size_type ""); \ } \ value = (size_type) tmp; \ @@ -20,11 +54,47 @@ #define PyGetInt_uint_t_retneg(size_type, item, value) \ if (PyLong_Check(item)) { \ - unsigned long long tmp; \ - tmp = PyLong_AsLongLong(item); \ - if ( tmp > (size_type) -1) { \ + bn_t bn; \ + int j; \ + PyObject* py_long = item; \ + PyObject* py_long_new; \ + PyObject* py_tmp; \ + PyObject* cst_32; \ + PyObject* cst_ffffffff; \ + uint64_t tmp; \ + cst_ffffffff = PyLong_FromLong(0xffffffff); \ + cst_32 = PyLong_FromLong(32); \ + bn = bignum_from_int(0); \ + int neg = 0; \ + \ + if (Py_SIZE(py_long) < 0) { \ + neg = 1; \ + py_long_new = PyObject_CallMethod(py_long, "__neg__", NULL); \ + Py_DECREF(py_long); \ + py_long = py_long_new; \ + } \ + \ + for (j = 0; j < BN_BYTE_SIZE; j += 4) { \ + py_tmp = PyObject_CallMethod(py_long, "__and__", "O", cst_ffffffff); \ + py_long_new = PyObject_CallMethod(py_long, "__rshift__", "O", cst_32); \ + Py_DECREF(py_long); \ + py_long = py_long_new; \ + tmp = PyLong_AsUnsignedLongLongMask(py_tmp); \ + Py_DECREF(py_tmp); \ + bn = bignum_or(bn, bignum_lshift(bignum_from_uint64(tmp), 8 * j)); \ + } \ + tmp = bignum_to_uint64(bn); \ + \ + if (neg) { \ + if ( tmp > (size_type) -1) { \ + PyErr_SetString(PyExc_TypeError, "Arg too big for " #size_type ""); \ + return -1; \ + } \ + tmp = (1<<(sizeof(size_type)*8))-tmp; \ + } \ + else if ( tmp > (size_type) -1) { \ PyErr_SetString(PyExc_TypeError, "Arg too big for " #size_type ""); \ - return -1; \ + return -1; \ } \ value = (size_type) tmp; \ } \ |