1 #ifndef MYPYC_UTIL_H 2 #define MYPYC_UTIL_H 3 4 #include <Python.h> 5 #include <frameobject.h> 6 #include <assert.h> 7 8 #if defined(__clang__) || defined(__GNUC__) 9 #define likely(x) __builtin_expect((x),1) 10 #define unlikely(x) __builtin_expect((x),0) 11 #define CPy_Unreachable() __builtin_unreachable() 12 #else 13 #define likely(x) (x) 14 #define unlikely(x) (x) 15 #define CPy_Unreachable() abort() 16 #endif 17 18 #if defined(__clang__) || defined(__GNUC__) 19 #define CPy_NOINLINE __attribute__((noinline)) 20 #elif defined(_MSC_VER) 21 #define CPy_NOINLINE __declspec(noinline) 22 #else 23 #define CPy_NOINLINE 24 #endif 25 26 // INCREF and DECREF that assert the pointer is not NULL. 27 // asserts are disabled in release builds so there shouldn't be a perf hit. 28 // I'm honestly kind of surprised that this isn't done by default. 29 #define CPy_INCREF(p) do { assert(p); Py_INCREF(p); } while (0) 30 #define CPy_DECREF(p) do { assert(p); Py_DECREF(p); } while (0) 31 // Here just for consistency 32 #define CPy_XDECREF(p) Py_XDECREF(p) 33 34 // Tagged integer -- our representation of Python 'int' objects. 35 // Small enough integers are represented as unboxed integers (shifted 36 // left by 1); larger integers (larger than 63 bits on a 64-bit 37 // platform) are stored as a tagged pointer (PyObject *) 38 // representing a Python int object, with the lowest bit set. 39 // Tagged integers are always normalized. A small integer *must not* 40 // have the tag bit set. 41 typedef size_t CPyTagged; 42 43 typedef size_t CPyPtr; 44 45 #define CPY_INT_BITS (CHAR_BIT * sizeof(CPyTagged)) 46 47 #define CPY_TAGGED_MAX (((Py_ssize_t)1 << (CPY_INT_BITS - 2)) - 1) 48 #define CPY_TAGGED_MIN (-((Py_ssize_t)1 << (CPY_INT_BITS - 2))) 49 #define CPY_TAGGED_ABS_MIN (0-(size_t)CPY_TAGGED_MIN) 50 51 typedef PyObject CPyModule; 52 53 // Tag bit used for long integers 54 #define CPY_INT_TAG 1 55 56 typedef void (*CPyVTableItem)(void); 57 CPyTagged_ShortFromInt(int x)58static inline CPyTagged CPyTagged_ShortFromInt(int x) { 59 return x << 1; 60 } 61 CPyTagged_ShortFromSsize_t(Py_ssize_t x)62static inline CPyTagged CPyTagged_ShortFromSsize_t(Py_ssize_t x) { 63 return x << 1; 64 } 65 66 #endif 67