mypyc_util.h 2.1 KB

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