TExceptionState.cpp 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #ifndef GREENLET_EXCEPTION_STATE_CPP
  2. #define GREENLET_EXCEPTION_STATE_CPP
  3. #include <Python.h>
  4. #include "TGreenlet.hpp"
  5. namespace greenlet {
  6. ExceptionState::ExceptionState()
  7. {
  8. this->clear();
  9. }
  10. void ExceptionState::operator<<(const PyThreadState *const tstate) noexcept
  11. {
  12. this->exc_info = tstate->exc_info;
  13. this->exc_state = tstate->exc_state;
  14. }
  15. void ExceptionState::operator>>(PyThreadState *const tstate) noexcept
  16. {
  17. tstate->exc_state = this->exc_state;
  18. tstate->exc_info =
  19. this->exc_info ? this->exc_info : &tstate->exc_state;
  20. this->clear();
  21. }
  22. void ExceptionState::clear() noexcept
  23. {
  24. this->exc_info = nullptr;
  25. this->exc_state.exc_value = nullptr;
  26. #if !GREENLET_PY311
  27. this->exc_state.exc_type = nullptr;
  28. this->exc_state.exc_traceback = nullptr;
  29. #endif
  30. this->exc_state.previous_item = nullptr;
  31. }
  32. int ExceptionState::tp_traverse(visitproc visit, void* arg) noexcept
  33. {
  34. Py_VISIT(this->exc_state.exc_value);
  35. #if !GREENLET_PY311
  36. Py_VISIT(this->exc_state.exc_type);
  37. Py_VISIT(this->exc_state.exc_traceback);
  38. #endif
  39. return 0;
  40. }
  41. void ExceptionState::tp_clear() noexcept
  42. {
  43. Py_CLEAR(this->exc_state.exc_value);
  44. #if !GREENLET_PY311
  45. Py_CLEAR(this->exc_state.exc_type);
  46. Py_CLEAR(this->exc_state.exc_traceback);
  47. #endif
  48. }
  49. }; // namespace greenlet
  50. #endif // GREENLET_EXCEPTION_STATE_CPP