typeinfo.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #include "pocketpy/interpreter/vm.h"
  2. py_ItemRef pk_tpfindname(py_TypeInfo* ti, py_Name name) {
  3. assert(ti != NULL);
  4. do {
  5. py_Ref res = py_getdict(&ti->self, name);
  6. if(res) return res;
  7. ti = ti->base_ti;
  8. } while(ti);
  9. return NULL;
  10. }
  11. py_ItemRef py_tpfindname(py_Type type, py_Name name) {
  12. py_TypeInfo* ti = pk_typeinfo(type);
  13. return pk_tpfindname(ti, name);
  14. }
  15. py_Ref py_tpfindmagic(py_Type t, py_Name name) {
  16. // assert(py_ismagicname(name));
  17. return py_tpfindname(t, name);
  18. }
  19. py_Type py_tpbase(py_Type t) {
  20. assert(t);
  21. py_TypeInfo* ti = pk_typeinfo(t);
  22. return ti->base;
  23. }
  24. PK_DEPRECATED py_Ref py_tpgetmagic(py_Type type, py_Name name) {
  25. // assert(py_ismagicname(name));
  26. py_TypeInfo* ti = pk_typeinfo(type);
  27. py_Ref retval = py_getdict(&ti->self, name);
  28. return retval != NULL ? retval : py_NIL();
  29. }
  30. py_Ref py_tpobject(py_Type type) {
  31. assert(type);
  32. return &pk_typeinfo(type)->self;
  33. }
  34. const char* py_tpname(py_Type type) {
  35. if(!type) return "nil";
  36. py_Name name = pk_typeinfo(type)->name;
  37. return py_name2str(name);
  38. }
  39. py_TypeInfo* pk_typeinfo(py_Type type) {
  40. return c11__getitem(TypePointer, &pk_current_vm->types, type).ti;
  41. }
  42. static void py_TypeInfo__common_init(py_Name name,
  43. py_Type base,
  44. py_Type index,
  45. const py_GlobalRef module,
  46. void (*dtor)(void*),
  47. bool is_python,
  48. bool is_sealed,
  49. py_TypeInfo* self,
  50. py_TValue* typeobject) {
  51. py_TypeInfo* base_ti = base ? pk_typeinfo(base) : NULL;
  52. if(base_ti && base_ti->is_sealed) {
  53. c11__abort("type '%s' is not an acceptable base type", py_name2str(base_ti->name));
  54. }
  55. self->name = name;
  56. self->index = index;
  57. self->base = base;
  58. self->base_ti = base_ti;
  59. py_assign(&self->self, typeobject);
  60. self->module = module ? module : py_NIL();
  61. if(!dtor && base) dtor = base_ti->dtor;
  62. self->is_python = is_python;
  63. self->is_sealed = is_sealed;
  64. self->annotations = *py_NIL();
  65. self->dtor = dtor;
  66. self->on_end_subclass = NULL;
  67. }
  68. py_Type pk_newtype(const char* name,
  69. py_Type base,
  70. const py_GlobalRef module,
  71. void (*dtor)(void*),
  72. bool is_python,
  73. bool is_sealed) {
  74. py_Type index = pk_current_vm->types.length;
  75. py_TypeInfo* self = py_newobject(py_retval(), tp_type, -1, sizeof(py_TypeInfo));
  76. py_TypeInfo__common_init(py_name(name),
  77. base,
  78. index,
  79. module,
  80. dtor,
  81. is_python,
  82. is_sealed,
  83. self,
  84. py_retval());
  85. TypePointer* pointer = c11_vector__emplace(&pk_current_vm->types);
  86. pointer->ti = self;
  87. pointer->dtor = self->dtor;
  88. return index;
  89. }
  90. py_Type pk_newtypewithmode(py_Name name,
  91. py_Type base,
  92. const py_GlobalRef module,
  93. void (*dtor)(void*),
  94. bool is_python,
  95. bool is_sealed,
  96. enum py_CompileMode mode) {
  97. if(mode == RELOAD_MODE && module != NULL) {
  98. py_ItemRef old_class = py_getdict(module, name);
  99. if(old_class != NULL && py_istype(old_class, tp_type)) {
  100. #ifndef NDEBUG
  101. const char* name_cstr = py_name2str(name);
  102. (void)name_cstr; // avoid unused warning
  103. #endif
  104. py_cleardict(old_class);
  105. py_TypeInfo* self = py_touserdata(old_class);
  106. py_Type index = self->index;
  107. py_TypeInfo__common_init(name,
  108. base,
  109. index,
  110. module,
  111. dtor,
  112. is_python,
  113. is_sealed,
  114. self,
  115. &self->self);
  116. TypePointer* pointer = c11__at(TypePointer, &pk_current_vm->types, index);
  117. pointer->ti = self;
  118. pointer->dtor = self->dtor;
  119. return index;
  120. }
  121. }
  122. return pk_newtype(py_name2str(name), base, module, dtor, is_python, is_sealed);
  123. }
  124. py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) {
  125. if(strlen(name) == 0) c11__abort("type name cannot be empty");
  126. py_Type type = pk_newtype(name, base, module, dtor, false, false);
  127. if(module) py_setdict(module, py_name(name), py_tpobject(type));
  128. return type;
  129. }