py_exception.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "pocketpy/objects/codeobject.h"
  2. #include "pocketpy/objects/error.h"
  3. #include "pocketpy/pocketpy.h"
  4. #include "pocketpy/common/utils.h"
  5. #include "pocketpy/objects/object.h"
  6. #include "pocketpy/interpreter/vm.h"
  7. #include "pocketpy/common/sstream.h"
  8. typedef struct BaseExceptionFrame {
  9. pk_SourceData_ src;
  10. int lineno;
  11. c11_string* name;
  12. } BaseExceptionFrame;
  13. typedef struct BaseException {
  14. const Bytecode* ip_backup;
  15. const CodeObject* code_backup;
  16. c11_vector /*T=BaseExceptionFrame*/ stacktrace;
  17. } BaseException;
  18. void py_BaseException__record(py_Ref self, const Bytecode* ip, const CodeObject* code) {
  19. BaseException* ud = py_touserdata(self);
  20. ud->ip_backup = ip;
  21. ud->code_backup = code;
  22. }
  23. void py_BaseException__stpush(py_Ref self, pk_SourceData_ src, int lineno, const char *func_name){
  24. BaseException* ud = py_touserdata(self);
  25. if(ud->stacktrace.count >= 7) return;
  26. BaseExceptionFrame* frame = c11_vector__emplace(&ud->stacktrace);
  27. PK_INCREF(src);
  28. frame->src = src;
  29. frame->lineno = lineno;
  30. frame->name = func_name ? c11_string__new(func_name) : NULL;
  31. }
  32. static void BaseException__dtor(void* ud) {
  33. BaseException* self = (BaseException*)ud;
  34. c11__foreach(BaseExceptionFrame, &self->stacktrace, it) {
  35. PK_DECREF(it->src);
  36. if(it->name) c11_string__delete(it->name);
  37. }
  38. c11_vector__dtor(&self->stacktrace);
  39. }
  40. static bool _py_BaseException__new__(int argc, py_Ref argv) {
  41. py_Type cls = py_totype(argv);
  42. BaseException* ud = py_newobject(py_retval(), cls, 1, sizeof(BaseException));
  43. c11_vector__ctor(&ud->stacktrace, sizeof(BaseExceptionFrame));
  44. ud->ip_backup = NULL;
  45. ud->code_backup = NULL;
  46. return true;
  47. }
  48. static bool _py_BaseException__init__(int argc, py_Ref argv) {
  49. if(argc == 1 + 0) { return true; }
  50. if(argc == 1 + 1) {
  51. py_setslot(py_arg(0), 0, py_arg(1));
  52. return true;
  53. }
  54. return TypeError("__init__() takes at most 2 arguments but %d were given", argc);
  55. }
  56. static bool _py_BaseException__repr__(int argc, py_Ref argv) {
  57. c11_sbuf ss;
  58. c11_sbuf__ctor(&ss);
  59. pk_sprintf(&ss, "%t(", argv->type);
  60. py_Ref arg = py_getslot(argv, 0);
  61. if(!py_isnil(arg)) {
  62. if(!py_repr(arg)) return false;
  63. c11_sbuf__write_sv(&ss, py_tosv(py_retval()));
  64. }
  65. c11_sbuf__write_char(&ss, ')');
  66. c11_string* res = c11_sbuf__submit(&ss);
  67. py_newstrn(py_retval(), res->data, res->size);
  68. c11_string__delete(res);
  69. return true;
  70. }
  71. static bool _py_BaseException__str__(int argc, py_Ref argv) {
  72. c11_sbuf ss;
  73. c11_sbuf__ctor(&ss);
  74. py_Ref arg = py_getslot(argv, 0);
  75. if(!py_isnil(arg)) {
  76. if(!py_str(arg)) return false;
  77. c11_sbuf__write_sv(&ss, py_tosv(py_retval()));
  78. }
  79. c11_string* res = c11_sbuf__submit(&ss);
  80. py_newstrn(py_retval(), res->data, res->size);
  81. c11_string__delete(res);
  82. return true;
  83. }
  84. py_Type pk_BaseException__register() {
  85. py_Type type = pk_newtype("BaseException", tp_object, NULL, BaseException__dtor, false, false);
  86. py_bindmagic(type, __new__, _py_BaseException__new__);
  87. py_bindmagic(type, __init__, _py_BaseException__init__);
  88. py_bindmagic(type, __repr__, _py_BaseException__repr__);
  89. py_bindmagic(type, __str__, _py_BaseException__str__);
  90. return type;
  91. }
  92. py_Type pk_Exception__register() {
  93. py_Type type = pk_newtype("Exception", tp_BaseException, NULL, NULL, false, true);
  94. return type;
  95. }