vm.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. #include "pocketpy/interpreter/vm.h"
  2. #include "pocketpy/common/memorypool.h"
  3. #include "pocketpy/common/utils.h"
  4. #include "pocketpy/interpreter/generator.h"
  5. #include "pocketpy/interpreter/modules.h"
  6. #include "pocketpy/interpreter/typeinfo.h"
  7. #include "pocketpy/objects/base.h"
  8. #include "pocketpy/interpreter/types.h"
  9. #include "pocketpy/common/_generated.h"
  10. #include "pocketpy/pocketpy.h"
  11. #include <stdbool.h>
  12. #include <assert.h>
  13. static char* pk_default_importfile(const char* path) {
  14. #if PK_ENABLE_OS
  15. FILE* f = fopen(path, "rb");
  16. if(f == NULL) return NULL;
  17. fseek(f, 0, SEEK_END);
  18. long size = ftell(f);
  19. fseek(f, 0, SEEK_SET);
  20. char* buffer = PK_MALLOC(size + 1);
  21. size = fread(buffer, 1, size, f);
  22. buffer[size] = 0;
  23. fclose(f);
  24. return buffer;
  25. #else
  26. return NULL;
  27. #endif
  28. }
  29. static void pk_default_print(const char* data) { printf("%s", data); }
  30. static void pk_default_flush() { fflush(stdout); }
  31. static int pk_default_getchr() { return getchar(); }
  32. void LineProfiler__tracefunc(py_Frame* frame, enum py_TraceEvent event) {
  33. LineProfiler* self = &pk_current_vm->line_profiler;
  34. if(self->enabled && event == TRACE_EVENT_LINE) { LineProfiler__tracefunc_line(self, frame); }
  35. }
  36. static int BinTree__cmp_cstr(void* lhs, void* rhs) {
  37. const char* l = (const char*)lhs;
  38. const char* r = (const char*)rhs;
  39. return strcmp(l, r);
  40. }
  41. void VM__ctor(VM* self) {
  42. self->top_frame = NULL;
  43. const static BinTreeConfig modules_config = {
  44. .f_cmp = BinTree__cmp_cstr,
  45. .need_free_key = false,
  46. };
  47. BinTree__ctor(&self->modules, "", py_NIL(), &modules_config);
  48. c11_vector__ctor(&self->types, sizeof(TypePointer));
  49. self->builtins = NULL;
  50. self->main = NULL;
  51. self->callbacks.importfile = pk_default_importfile;
  52. self->callbacks.print = pk_default_print;
  53. self->callbacks.flush = pk_default_flush;
  54. self->callbacks.getchr = pk_default_getchr;
  55. self->last_retval = *py_NIL();
  56. self->curr_exception = *py_NIL();
  57. self->recursion_depth = 0;
  58. self->max_recursion_depth = 1000;
  59. self->is_curr_exc_handled = false;
  60. self->ctx = NULL;
  61. self->curr_class = NULL;
  62. self->curr_decl_based_function = NULL;
  63. memset(&self->trace_info, 0, sizeof(TraceInfo));
  64. memset(&self->watchdog_info, 0, sizeof(WatchdogInfo));
  65. LineProfiler__ctor(&self->line_profiler);
  66. FixedMemoryPool__ctor(&self->pool_frame, sizeof(py_Frame), 32);
  67. ManagedHeap__ctor(&self->heap);
  68. ValueStack__ctor(&self->stack);
  69. CachedNames__ctor(&self->cached_names);
  70. NameDict__ctor(&self->compile_time_funcs, PK_TYPE_ATTR_LOAD_FACTOR);
  71. /* Init Builtin Types */
  72. // 0: unused
  73. TypePointer* placeholder = c11_vector__emplace(&self->types);
  74. placeholder->ti = NULL;
  75. placeholder->dtor = NULL;
  76. #define validate(t, expr) \
  77. if(t != (expr)) abort()
  78. validate(tp_object, pk_newtype("object", tp_nil, NULL, NULL, true, false));
  79. validate(tp_type, pk_newtype("type", tp_object, NULL, NULL, false, true));
  80. pk_object__register();
  81. validate(tp_int, pk_newtype("int", tp_object, NULL, NULL, false, true));
  82. validate(tp_float, pk_newtype("float", tp_object, NULL, NULL, false, true));
  83. validate(tp_bool, pk_newtype("bool", tp_object, NULL, NULL, false, true));
  84. pk_number__register();
  85. validate(tp_str, pk_str__register());
  86. validate(tp_str_iterator, pk_str_iterator__register());
  87. validate(tp_list, pk_list__register());
  88. validate(tp_tuple, pk_tuple__register());
  89. validate(tp_list_iterator, pk_list_iterator__register());
  90. validate(tp_tuple_iterator, pk_tuple_iterator__register());
  91. validate(tp_slice, pk_slice__register());
  92. validate(tp_range, pk_range__register());
  93. validate(tp_range_iterator, pk_range_iterator__register());
  94. validate(tp_module, pk_module__register());
  95. validate(tp_function, pk_function__register());
  96. validate(tp_nativefunc, pk_nativefunc__register());
  97. validate(tp_boundmethod, pk_boundmethod__register());
  98. validate(tp_super, pk_super__register());
  99. validate(tp_BaseException, pk_BaseException__register());
  100. validate(tp_Exception, pk_Exception__register());
  101. validate(tp_bytes, pk_bytes__register());
  102. validate(tp_namedict, pk_namedict__register());
  103. validate(tp_locals, pk_newtype("locals", tp_object, NULL, NULL, false, true));
  104. validate(tp_code, pk_code__register());
  105. validate(tp_dict, pk_dict__register());
  106. validate(tp_dict_iterator, pk_dict_items__register());
  107. validate(tp_property, pk_property__register());
  108. validate(tp_star_wrapper, pk_newtype("star_wrapper", tp_object, NULL, NULL, false, true));
  109. validate(tp_staticmethod, pk_staticmethod__register());
  110. validate(tp_classmethod, pk_classmethod__register());
  111. validate(tp_NoneType, pk_newtype("NoneType", tp_object, NULL, NULL, false, true));
  112. validate(tp_NotImplementedType,
  113. pk_newtype("NotImplementedType", tp_object, NULL, NULL, false, true));
  114. validate(tp_ellipsis, pk_newtype("ellipsis", tp_object, NULL, NULL, false, true));
  115. validate(tp_generator, pk_generator__register());
  116. self->builtins = pk_builtins__register();
  117. // inject some builtin exceptions
  118. #define INJECT_BUILTIN_EXC(name, TBase) \
  119. do { \
  120. py_Type type = pk_newtype(#name, TBase, self->builtins, NULL, false, true); \
  121. py_setdict(self->builtins, py_name(#name), py_tpobject(type)); \
  122. validate(tp_##name, type); \
  123. } while(0)
  124. INJECT_BUILTIN_EXC(SystemExit, tp_BaseException);
  125. INJECT_BUILTIN_EXC(KeyboardInterrupt, tp_BaseException);
  126. validate(tp_StopIteration, pk_StopIteration__register());
  127. py_setdict(self->builtins, py_name("StopIteration"), py_tpobject(tp_StopIteration));
  128. INJECT_BUILTIN_EXC(SyntaxError, tp_Exception);
  129. INJECT_BUILTIN_EXC(RecursionError, tp_Exception);
  130. INJECT_BUILTIN_EXC(OSError, tp_Exception);
  131. INJECT_BUILTIN_EXC(NotImplementedError, tp_Exception);
  132. INJECT_BUILTIN_EXC(TypeError, tp_Exception);
  133. INJECT_BUILTIN_EXC(IndexError, tp_Exception);
  134. INJECT_BUILTIN_EXC(ValueError, tp_Exception);
  135. INJECT_BUILTIN_EXC(RuntimeError, tp_Exception);
  136. INJECT_BUILTIN_EXC(TimeoutError, tp_Exception);
  137. INJECT_BUILTIN_EXC(ZeroDivisionError, tp_Exception);
  138. INJECT_BUILTIN_EXC(NameError, tp_Exception);
  139. INJECT_BUILTIN_EXC(UnboundLocalError, tp_Exception);
  140. INJECT_BUILTIN_EXC(AttributeError, tp_Exception);
  141. INJECT_BUILTIN_EXC(ImportError, tp_Exception);
  142. INJECT_BUILTIN_EXC(AssertionError, tp_Exception);
  143. INJECT_BUILTIN_EXC(KeyError, tp_Exception);
  144. #undef INJECT_BUILTIN_EXC
  145. #undef validate
  146. /* Setup Public Builtin Types */
  147. py_Type public_types[] = {
  148. tp_object,
  149. tp_type,
  150. tp_int,
  151. tp_float,
  152. tp_bool,
  153. tp_str,
  154. tp_list,
  155. tp_tuple,
  156. tp_slice,
  157. tp_range,
  158. tp_bytes,
  159. tp_dict,
  160. tp_property,
  161. tp_staticmethod,
  162. tp_classmethod,
  163. tp_super,
  164. tp_BaseException,
  165. tp_Exception,
  166. };
  167. for(int i = 0; i < c11__count_array(public_types); i++) {
  168. py_TypeInfo* ti = pk_typeinfo(public_types[i]);
  169. py_setdict(self->builtins, ti->name, &ti->self);
  170. }
  171. py_newnotimplemented(py_emplacedict(self->builtins, py_name("NotImplemented")));
  172. pk__add_module_vmath();
  173. pk__add_module_array2d();
  174. pk__add_module_colorcvt();
  175. // add modules
  176. pk__add_module_os();
  177. pk__add_module_sys();
  178. pk__add_module_io();
  179. pk__add_module_math();
  180. pk__add_module_dis();
  181. pk__add_module_random();
  182. pk__add_module_json();
  183. pk__add_module_gc();
  184. pk__add_module_time();
  185. pk__add_module_easing();
  186. pk__add_module_traceback();
  187. pk__add_module_enum();
  188. pk__add_module_inspect();
  189. pk__add_module_pickle();
  190. pk__add_module_base64();
  191. pk__add_module_importlib();
  192. pk__add_module_unicodedata();
  193. pk__add_module_conio();
  194. pk__add_module_lz4(); // optional
  195. pk__add_module_libhv(); // optional
  196. pk__add_module_pkpy();
  197. // add python builtins
  198. do {
  199. bool ok;
  200. ok = py_exec(kPythonLibs_builtins, "<builtins>", EXEC_MODE, self->builtins);
  201. if(!ok) goto __ABORT;
  202. break;
  203. __ABORT:
  204. py_printexc();
  205. c11__abort("failed to load python builtins!");
  206. } while(0);
  207. self->main = py_newmodule("__main__");
  208. }
  209. void VM__dtor(VM* self) {
  210. // reset traceinfo
  211. py_sys_settrace(NULL, true);
  212. LineProfiler__dtor(&self->line_profiler);
  213. // destroy all objects
  214. ManagedHeap__dtor(&self->heap);
  215. // clear frames
  216. while(self->top_frame)
  217. VM__pop_frame(self);
  218. BinTree__dtor(&self->modules);
  219. FixedMemoryPool__dtor(&self->pool_frame);
  220. ValueStack__dtor(&self->stack);
  221. CachedNames__dtor(&self->cached_names);
  222. NameDict__dtor(&self->compile_time_funcs);
  223. c11_vector__dtor(&self->types);
  224. }
  225. void VM__push_frame(VM* self, py_Frame* frame) {
  226. frame->f_back = self->top_frame;
  227. self->top_frame = frame;
  228. self->recursion_depth++;
  229. if(self->trace_info.func) self->trace_info.func(frame, TRACE_EVENT_PUSH);
  230. }
  231. void VM__pop_frame(VM* self) {
  232. assert(self->top_frame);
  233. py_Frame* frame = self->top_frame;
  234. if(self->trace_info.func) self->trace_info.func(frame, TRACE_EVENT_POP);
  235. // reset stack pointer
  236. self->stack.sp = frame->p0;
  237. // pop frame and delete
  238. self->top_frame = frame->f_back;
  239. Frame__delete(frame);
  240. self->recursion_depth--;
  241. }
  242. static void _clip_int(int* value, int min, int max) {
  243. if(*value < min) *value = min;
  244. if(*value > max) *value = max;
  245. }
  246. bool pk__parse_int_slice(py_Ref slice,
  247. int length,
  248. int* restrict start,
  249. int* restrict stop,
  250. int* restrict step) {
  251. if(py_isint(slice)) {
  252. int index = py_toint(slice);
  253. bool ok = pk__normalize_index(&index, length);
  254. if(!ok) return false;
  255. *start = index;
  256. *stop = index + 1;
  257. *step = 1;
  258. return true;
  259. }
  260. if(!py_istype(slice, tp_slice)) c11__abort("pk__parse_int_slice(): not a slice object");
  261. py_Ref s_start = py_getslot(slice, 0);
  262. py_Ref s_stop = py_getslot(slice, 1);
  263. py_Ref s_step = py_getslot(slice, 2);
  264. if(py_isnone(s_step))
  265. *step = 1;
  266. else {
  267. if(!py_checkint(s_step)) return false;
  268. *step = py_toint(s_step);
  269. }
  270. if(*step == 0) return ValueError("slice step cannot be zero");
  271. if(*step > 0) {
  272. if(py_isnone(s_start))
  273. *start = 0;
  274. else {
  275. if(!py_checkint(s_start)) return false;
  276. *start = py_toint(s_start);
  277. if(*start < 0) *start += length;
  278. _clip_int(start, 0, length);
  279. }
  280. if(py_isnone(s_stop))
  281. *stop = length;
  282. else {
  283. if(!py_checkint(s_stop)) return false;
  284. *stop = py_toint(s_stop);
  285. if(*stop < 0) *stop += length;
  286. _clip_int(stop, 0, length);
  287. }
  288. } else {
  289. if(py_isnone(s_start))
  290. *start = length - 1;
  291. else {
  292. if(!py_checkint(s_start)) return false;
  293. *start = py_toint(s_start);
  294. if(*start < 0) *start += length;
  295. _clip_int(start, -1, length - 1);
  296. }
  297. if(py_isnone(s_stop))
  298. *stop = -1;
  299. else {
  300. if(!py_checkint(s_stop)) return false;
  301. *stop = py_toint(s_stop);
  302. if(*stop < 0) *stop += length;
  303. _clip_int(stop, -1, length - 1);
  304. }
  305. }
  306. return true;
  307. }
  308. bool pk__normalize_index(int* index, int length) {
  309. if(*index < 0) *index += length;
  310. if(*index < 0 || *index >= length) return IndexError("%d not in [0, %d)", *index, length);
  311. return true;
  312. }
  313. static bool
  314. prepare_py_call(py_TValue* buffer, py_Ref argv, py_Ref p1, int kwargc, const FuncDecl* decl) {
  315. const CodeObject* co = &decl->code;
  316. int decl_argc = decl->args.length;
  317. if(p1 - argv < decl_argc) {
  318. return TypeError("%s() takes %d positional arguments but %d were given",
  319. co->name->data,
  320. decl_argc,
  321. (int)(p1 - argv));
  322. }
  323. py_TValue* t = argv;
  324. // prepare args
  325. memset(buffer, 0, co->nlocals * sizeof(py_TValue));
  326. c11__foreach(int, &decl->args, index) buffer[*index] = *t++;
  327. // prepare kwdefaults
  328. c11__foreach(FuncDeclKwArg, &decl->kwargs, kv) buffer[kv->index] = kv->value;
  329. // handle *args
  330. if(decl->starred_arg != -1) {
  331. int exceed_argc = p1 - t;
  332. py_Ref vargs = &buffer[decl->starred_arg];
  333. py_Ref data = py_newtuple(vargs, exceed_argc);
  334. for(int j = 0; j < exceed_argc; j++) {
  335. data[j] = *t++;
  336. }
  337. } else {
  338. // kwdefaults override
  339. // def f(a, b, c=None)
  340. // f(1, 2, 3) -> c=3
  341. c11__foreach(FuncDeclKwArg, &decl->kwargs, kv) {
  342. if(t >= p1) break;
  343. buffer[kv->index] = *t++;
  344. }
  345. // not able to consume all args
  346. if(t < p1) return TypeError("too many arguments (%s)", co->name->data);
  347. }
  348. if(decl->starred_kwarg != -1) py_newdict(&buffer[decl->starred_kwarg]);
  349. for(int j = 0; j < kwargc; j++) {
  350. py_Name key = (py_Name)py_toint(&p1[2 * j]);
  351. int index = c11_smallmap_n2d__get(&decl->kw_to_index, key, -1);
  352. // if key is an explicit key, set as local variable
  353. if(index >= 0) {
  354. buffer[index] = p1[2 * j + 1];
  355. } else {
  356. // otherwise, set as **kwargs if possible
  357. if(decl->starred_kwarg == -1) {
  358. return TypeError("'%n' is an invalid keyword argument for %s()",
  359. key,
  360. co->name->data);
  361. } else {
  362. // add to **kwargs
  363. bool ok =
  364. py_dict_setitem(&buffer[decl->starred_kwarg], py_name2ref(key), &p1[2 * j + 1]);
  365. if(!ok) return false;
  366. }
  367. }
  368. }
  369. return true;
  370. }
  371. FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall) {
  372. #ifndef NDEBUG
  373. pk_print_stack(self, self->top_frame, (Bytecode){0});
  374. #endif
  375. py_Ref p1 = self->stack.sp - kwargc * 2;
  376. py_Ref p0 = p1 - argc - 2;
  377. // [callable, <self>, args..., kwargs...]
  378. // ^p0 ^p1 ^_sp
  379. // handle boundmethod, do a patch
  380. if(p0->type == tp_boundmethod) {
  381. assert(py_isnil(p0 + 1)); // self must be NULL
  382. py_TValue* slots = PyObject__slots(p0->_obj);
  383. p0[0] = slots[1]; // callable
  384. p0[1] = slots[0]; // self
  385. // [unbound, self, args..., kwargs...]
  386. }
  387. py_Ref argv = p0 + 1 + (int)py_isnil(p0 + 1);
  388. if(p0->type == tp_function) {
  389. Function* fn = py_touserdata(p0);
  390. const CodeObject* co = &fn->decl->code;
  391. switch(fn->decl->type) {
  392. case FuncType_NORMAL: {
  393. bool ok = prepare_py_call(self->vectorcall_buffer, argv, p1, kwargc, fn->decl);
  394. if(!ok) return RES_ERROR;
  395. // copy buffer back to stack
  396. self->stack.sp = argv + co->nlocals;
  397. memcpy(argv, self->vectorcall_buffer, co->nlocals * sizeof(py_TValue));
  398. // submit the call
  399. if(!fn->cfunc) {
  400. // python function
  401. VM__push_frame(self, Frame__new(co, p0, fn->module, fn->globals, argv, false));
  402. return opcall ? RES_CALL : VM__run_top_frame(self);
  403. } else {
  404. // decl-based binding
  405. self->curr_decl_based_function = p0;
  406. bool ok = py_callcfunc(fn->cfunc, co->nlocals, argv);
  407. self->stack.sp = p0;
  408. self->curr_decl_based_function = NULL;
  409. return ok ? RES_RETURN : RES_ERROR;
  410. }
  411. }
  412. case FuncType_SIMPLE:
  413. if(p1 - argv != fn->decl->args.length) {
  414. const char* fmt = "%s() takes %d positional arguments but %d were given";
  415. TypeError(fmt, co->name->data, fn->decl->args.length, (int)(p1 - argv));
  416. return RES_ERROR;
  417. }
  418. if(kwargc) {
  419. TypeError("%s() takes no keyword arguments", co->name->data);
  420. return RES_ERROR;
  421. }
  422. // [callable, <self>, args..., local_vars...]
  423. // ^p0 ^p1 ^_sp
  424. self->stack.sp = argv + co->nlocals;
  425. // initialize local variables to py_NIL
  426. memset(p1, 0, (char*)self->stack.sp - (char*)p1);
  427. // submit the call
  428. if(!fn->cfunc) {
  429. // python function
  430. VM__push_frame(self, Frame__new(co, p0, fn->module, fn->globals, argv, false));
  431. return opcall ? RES_CALL : VM__run_top_frame(self);
  432. } else {
  433. // decl-based binding
  434. self->curr_decl_based_function = p0;
  435. bool ok = py_callcfunc(fn->cfunc, co->nlocals, argv);
  436. self->stack.sp = p0;
  437. self->curr_decl_based_function = NULL;
  438. return ok ? RES_RETURN : RES_ERROR;
  439. }
  440. case FuncType_GENERATOR: {
  441. bool ok = prepare_py_call(self->vectorcall_buffer, argv, p1, kwargc, fn->decl);
  442. if(!ok) return RES_ERROR;
  443. // copy buffer back to stack
  444. self->stack.sp = argv + co->nlocals;
  445. memcpy(argv, self->vectorcall_buffer, co->nlocals * sizeof(py_TValue));
  446. py_Frame* frame = Frame__new(co, p0, fn->module, fn->globals, argv, false);
  447. pk_newgenerator(py_retval(), frame, p0, self->stack.sp);
  448. self->stack.sp = p0; // reset the stack
  449. return RES_RETURN;
  450. }
  451. default: c11__unreachable();
  452. };
  453. c11__unreachable();
  454. /*****************_py_call*****************/
  455. }
  456. if(p0->type == tp_nativefunc) {
  457. if(kwargc && p0->_cfunc != pk__object_new) {
  458. TypeError("nativefunc does not accept keyword arguments");
  459. return RES_ERROR;
  460. }
  461. bool ok = py_callcfunc(p0->_cfunc, p1 - argv, argv);
  462. self->stack.sp = p0;
  463. return ok ? RES_RETURN : RES_ERROR;
  464. }
  465. if(p0->type == tp_type) {
  466. // [cls, NULL, args..., kwargs...]
  467. py_Ref new_f = py_tpfindmagic(py_totype(p0), __new__);
  468. assert(new_f && py_isnil(p0 + 1));
  469. // prepare a copy of args and kwargs
  470. int span = self->stack.sp - argv;
  471. *self->stack.sp++ = *new_f; // push __new__
  472. *self->stack.sp++ = *p0; // push cls
  473. memcpy(self->stack.sp, argv, span * sizeof(py_TValue));
  474. self->stack.sp += span;
  475. // [new_f, cls, args..., kwargs...]
  476. if(VM__vectorcall(self, argc, kwargc, false) == RES_ERROR) return RES_ERROR;
  477. // by recursively using vectorcall, args and kwargs are consumed
  478. // try __init__
  479. // NOTE: previously we use `get_unbound_method` but here we just use `tpfindmagic`
  480. // >> [cls, NULL, args..., kwargs...]
  481. // >> py_retval() is the new instance
  482. py_Ref init_f = py_tpfindmagic(py_totype(p0), __init__);
  483. if(init_f) {
  484. // do an inplace patch
  485. *p0 = *init_f; // __init__
  486. p0[1] = self->last_retval; // self
  487. // [__init__, self, args..., kwargs...]
  488. if(VM__vectorcall(self, argc, kwargc, false) == RES_ERROR) return RES_ERROR;
  489. *py_retval() = p0[1]; // restore the new instance
  490. }
  491. // reset the stack
  492. self->stack.sp = p0;
  493. return RES_RETURN;
  494. }
  495. // handle `__call__` overload
  496. if(pk_loadmethod(p0, __call__)) {
  497. // [__call__, self, args..., kwargs...]
  498. return VM__vectorcall(self, argc, kwargc, opcall);
  499. }
  500. TypeError("'%t' object is not callable", p0->type);
  501. return RES_ERROR;
  502. }
  503. /****************************************/
  504. void FuncDecl__gc_mark(const FuncDecl* self, c11_vector* p_stack) {
  505. CodeObject__gc_mark(&self->code, p_stack);
  506. for(int j = 0; j < self->kwargs.length; j++) {
  507. FuncDeclKwArg* kw = c11__at(FuncDeclKwArg, &self->kwargs, j);
  508. pk__mark_value(&kw->value);
  509. }
  510. }
  511. void CodeObject__gc_mark(const CodeObject* self, c11_vector* p_stack) {
  512. for(int i = 0; i < self->consts.length; i++) {
  513. py_TValue* p = c11__at(py_TValue, &self->consts, i);
  514. pk__mark_value(p);
  515. }
  516. for(int i = 0; i < self->func_decls.length; i++) {
  517. FuncDecl_ decl = c11__getitem(FuncDecl_, &self->func_decls, i);
  518. FuncDecl__gc_mark(decl, p_stack);
  519. }
  520. }
  521. static void pk__mark_value_func(py_Ref val, void* ctx) {
  522. c11_vector* p_stack = ctx;
  523. pk__mark_value(val);
  524. }
  525. void ManagedHeap__mark(ManagedHeap* self) {
  526. VM* vm = pk_current_vm;
  527. c11_vector* p_stack = &self->gc_roots;
  528. assert(p_stack->length == 0);
  529. // mark value stack
  530. for(py_TValue* p = vm->stack.begin; p != vm->stack.end; p++) {
  531. pk__mark_value(p);
  532. }
  533. // mark modules
  534. BinTree__apply_mark(&vm->modules, p_stack);
  535. // mark cached names
  536. for(int i = 0; i < vm->cached_names.entries.length; i++) {
  537. CachedNames_KV* kv = c11_chunkedvector__at(&vm->cached_names.entries, i);
  538. pk__mark_value(&kv->val);
  539. }
  540. // mark compile time functions
  541. for(int i = 0; i < vm->compile_time_funcs.capacity; i++) {
  542. NameDict_KV* kv = &vm->compile_time_funcs.items[i];
  543. if(kv->key == NULL) continue;
  544. pk__mark_value(&kv->value);
  545. }
  546. // mark types
  547. int types_length = vm->types.length;
  548. // 0-th type is placeholder
  549. for(py_Type i = 1; i < types_length; i++) {
  550. py_TypeInfo* ti = c11__getitem(TypePointer, &vm->types, i).ti;
  551. pk__mark_value(&ti->self);
  552. pk__mark_value(&ti->annotations);
  553. }
  554. // mark frame
  555. for(py_Frame* frame = vm->top_frame; frame; frame = frame->f_back) {
  556. Frame__gc_mark(frame, p_stack);
  557. }
  558. // mark vm's registers
  559. pk__mark_value(&vm->last_retval);
  560. pk__mark_value(&vm->curr_exception);
  561. for(int i = 0; i < c11__count_array(vm->reg); i++) {
  562. pk__mark_value(&vm->reg[i]);
  563. }
  564. // mark user func
  565. if(vm->callbacks.gc_mark) vm->callbacks.gc_mark(pk__mark_value_func, p_stack);
  566. /*****************************/
  567. while(p_stack->length > 0) {
  568. PyObject* obj = c11_vector__back(PyObject*, p_stack);
  569. c11_vector__pop(p_stack);
  570. assert(obj->gc_marked);
  571. if(obj->slots > 0) {
  572. py_TValue* p = PyObject__slots(obj);
  573. for(int i = 0; i < obj->slots; i++)
  574. pk__mark_value(p + i);
  575. } else if(obj->slots == -1) {
  576. NameDict* dict = PyObject__dict(obj);
  577. for(int i = 0; i < dict->capacity; i++) {
  578. NameDict_KV* kv = &dict->items[i];
  579. if(kv->key == NULL) continue;
  580. pk__mark_value(&kv->value);
  581. }
  582. }
  583. void* ud = PyObject__userdata(obj);
  584. switch(obj->type) {
  585. case tp_list: {
  586. List* self = ud;
  587. for(int i = 0; i < self->length; i++) {
  588. py_TValue* val = c11__at(py_TValue, self, i);
  589. pk__mark_value(val);
  590. }
  591. break;
  592. }
  593. case tp_dict: {
  594. Dict* self = ud;
  595. for(int i = 0; i < self->entries.length; i++) {
  596. DictEntry* entry = c11__at(DictEntry, &self->entries, i);
  597. if(py_isnil(&entry->key)) continue;
  598. pk__mark_value(&entry->key);
  599. pk__mark_value(&entry->val);
  600. }
  601. break;
  602. }
  603. case tp_generator: {
  604. Generator* self = ud;
  605. if(self->frame) Frame__gc_mark(self->frame, p_stack);
  606. break;
  607. }
  608. case tp_function: {
  609. function__gc_mark(ud, p_stack);
  610. break;
  611. }
  612. case tp_code: {
  613. CodeObject* self = ud;
  614. CodeObject__gc_mark(self, p_stack);
  615. break;
  616. }
  617. case tp_chunked_array2d: {
  618. c11_chunked_array2d__mark(ud, p_stack);
  619. break;
  620. }
  621. }
  622. }
  623. }