py_object.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include "pocketpy/interpreter/vm.h"
  2. #include "pocketpy/common/sstream.h"
  3. #include "pocketpy/pocketpy.h"
  4. bool pk__object_new(int argc, py_Ref argv) {
  5. if(argc == 0) return TypeError("object.__new__(): not enough arguments");
  6. py_TypeInfo* ti = py_touserdata(argv);
  7. py_Type cls = ti->index;
  8. if(!ti->is_python) {
  9. return TypeError("object.__new__(%t) is not safe, use %t.__new__() instead", cls, cls);
  10. }
  11. py_newobject(py_retval(), cls, -1, 0);
  12. return true;
  13. }
  14. static bool object__hash__(int argc, py_Ref argv) {
  15. PY_CHECK_ARGC(1);
  16. assert(argv->is_ptr);
  17. py_newint(py_retval(), (intptr_t)argv->_obj);
  18. return true;
  19. }
  20. static bool object__eq__(int argc, py_Ref argv) {
  21. PY_CHECK_ARGC(2);
  22. bool res = py_isidentical(py_arg(0), py_arg(1));
  23. py_newbool(py_retval(), res);
  24. return true;
  25. }
  26. static bool object__ne__(int argc, py_Ref argv) {
  27. PY_CHECK_ARGC(2);
  28. bool res = py_isidentical(py_arg(0), py_arg(1));
  29. py_newbool(py_retval(), !res);
  30. return true;
  31. }
  32. static bool object__repr__(int argc, py_Ref argv) {
  33. PY_CHECK_ARGC(1);
  34. c11_sbuf buf;
  35. c11_sbuf__ctor(&buf);
  36. if(argv->is_ptr) {
  37. pk_sprintf(&buf, "<%t object at %p>", argv->type, argv->_obj);
  38. } else {
  39. pk_sprintf(&buf, "<%t trivial object>", argv->type);
  40. }
  41. c11_sbuf__py_submit(&buf, py_retval());
  42. return true;
  43. }
  44. static bool object__dict__(int argc, py_Ref argv) {
  45. PY_CHECK_ARGC(1);
  46. if(argv->is_ptr && argv->_obj->slots == -1) {
  47. pk_mappingproxy__namedict(py_retval(), argv);
  48. } else {
  49. py_newnone(py_retval());
  50. }
  51. return true;
  52. }
  53. static bool type__repr__(int argc, py_Ref argv) {
  54. PY_CHECK_ARGC(1);
  55. c11_sbuf buf;
  56. c11_sbuf__ctor(&buf);
  57. pk_sprintf(&buf, "<class '%t'>", py_totype(argv));
  58. c11_sbuf__py_submit(&buf, py_retval());
  59. return true;
  60. }
  61. static bool type__new__(int argc, py_Ref argv) {
  62. PY_CHECK_ARGC(2);
  63. py_Type type = py_typeof(py_arg(1));
  64. py_assign(py_retval(), py_tpobject(type));
  65. return true;
  66. }
  67. static bool type__base__(int argc, py_Ref argv) {
  68. PY_CHECK_ARGC(1);
  69. py_TypeInfo* ti = py_touserdata(argv);
  70. if(ti->base) {
  71. py_assign(py_retval(), &ti->base_ti->self);
  72. } else {
  73. py_newnone(py_retval());
  74. }
  75. return true;
  76. }
  77. static bool type__name__(int argc, py_Ref argv) {
  78. PY_CHECK_ARGC(1);
  79. py_TypeInfo* ti = py_touserdata(argv);
  80. py_assign(py_retval(), py_name2ref(ti->name));
  81. return true;
  82. }
  83. static bool type__getitem__(int argc, py_Ref argv) {
  84. py_assign(py_retval(), argv);
  85. return true;
  86. }
  87. static bool type__or__(int argc, py_Ref argv) {
  88. py_assign(py_retval(), argv);
  89. return true;
  90. }
  91. static bool type__module__(int argc, py_Ref argv) {
  92. PY_CHECK_ARGC(1);
  93. py_TypeInfo* ti = py_touserdata(argv);
  94. if(py_isnil(ti->module)) {
  95. py_newnone(py_retval());
  96. } else {
  97. py_ModuleInfo* mi = py_touserdata(ti->module);
  98. py_newstrv(py_retval(), c11_string__sv(mi->path));
  99. }
  100. return true;
  101. }
  102. static bool type__annotations__(int argc, py_Ref argv) {
  103. PY_CHECK_ARGC(1);
  104. py_TypeInfo* ti = py_touserdata(argv);
  105. if(py_isnil(&ti->annotations)) {
  106. py_newdict(py_retval());
  107. } else {
  108. py_assign(py_retval(), &ti->annotations);
  109. }
  110. return true;
  111. }
  112. static bool type__subclasses__(int argc, py_Ref argv) {
  113. PY_CHECK_ARGC(1);
  114. py_TypeInfo* base_ti = py_touserdata(argv);
  115. py_newlist(py_retval());
  116. for(py_Type i = 1; i < pk_current_vm->types.length; i++) {
  117. py_TypeInfo* ti = pk_typeinfo(i);
  118. if(ti->base == base_ti->index) {
  119. py_list_append(py_retval(), &ti->self);
  120. }
  121. }
  122. return true;
  123. }
  124. void pk_object__register() {
  125. py_bindmagic(tp_object, __new__, pk__object_new);
  126. py_bindmagic(tp_object, __hash__, object__hash__);
  127. py_bindmagic(tp_object, __eq__, object__eq__);
  128. py_bindmagic(tp_object, __ne__, object__ne__);
  129. py_bindmagic(tp_object, __repr__, object__repr__);
  130. py_bindmagic(tp_type, __repr__, type__repr__);
  131. py_bindmagic(tp_type, __new__, type__new__);
  132. py_bindmagic(tp_type, __getitem__, type__getitem__);
  133. py_bindmagic(tp_type, __or__, type__or__);
  134. py_bindproperty(tp_type, "__module__", type__module__, NULL);
  135. py_bindproperty(tp_type, "__base__", type__base__, NULL);
  136. py_bindproperty(tp_type, "__name__", type__name__, NULL);
  137. py_bindproperty(tp_object, "__dict__", object__dict__, NULL);
  138. py_bindproperty(tp_type, "__annotations__", type__annotations__, NULL);
  139. py_bindmethod(tp_type, "__subclasses__", type__subclasses__);
  140. }