vm.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. #include "pocketpy/interpreter/vm.h"
  2. #include "pocketpy/common/memorypool.h"
  3. #include "pocketpy/common/sstream.h"
  4. #include "pocketpy/common/utils.h"
  5. #include "pocketpy/objects/base.h"
  6. #include "pocketpy/pocketpy.h"
  7. #include <assert.h>
  8. #include <stdarg.h>
  9. #include <stdbool.h>
  10. static unsigned char* pk_default_import_file(const char* path) { return NULL; }
  11. static void pk_default_stdout(const char* fmt, ...) {
  12. va_list args;
  13. va_start(args, fmt);
  14. vfprintf(stdout, fmt, args);
  15. va_end(args);
  16. fflush(stdout);
  17. }
  18. static void pk_default_stderr(const char* fmt, ...) {
  19. va_list args;
  20. va_start(args, fmt);
  21. vfprintf(stderr, fmt, args);
  22. va_end(args);
  23. fflush(stderr);
  24. }
  25. static void pk_TypeInfo__ctor(pk_TypeInfo* self,
  26. py_Name name,
  27. py_Type index,
  28. py_Type base,
  29. const py_TValue* module) {
  30. memset(self, 0, sizeof(pk_TypeInfo));
  31. self->name = name;
  32. self->base = base;
  33. // create type object with __dict__
  34. pk_ManagedHeap* heap = &pk_current_vm->heap;
  35. PyObject* typeobj = pk_ManagedHeap__new(heap, tp_type, -1, sizeof(py_Type));
  36. *(py_Type*)PyObject__userdata(typeobj) = index;
  37. self->self = (py_TValue){
  38. .type = typeobj->type,
  39. .is_ptr = true,
  40. ._obj = typeobj,
  41. };
  42. self->module = module ? *module : *py_NIL;
  43. c11_vector__ctor(&self->annotated_fields, sizeof(py_Name));
  44. }
  45. static void pk_TypeInfo__dtor(pk_TypeInfo* self) { c11_vector__dtor(&self->annotated_fields); }
  46. void pk_VM__ctor(pk_VM* self) {
  47. self->top_frame = NULL;
  48. pk_NameDict__ctor(&self->modules);
  49. c11_vector__ctor(&self->types, sizeof(pk_TypeInfo));
  50. self->builtins = *py_NIL;
  51. self->main = *py_NIL;
  52. self->_ceval_on_step = NULL;
  53. self->_import_file = pk_default_import_file;
  54. self->_stdout = pk_default_stdout;
  55. self->_stderr = pk_default_stderr;
  56. self->last_retval = *py_NIL;
  57. self->last_exception = *py_NIL;
  58. self->is_stopiteration = false;
  59. self->__curr_class = NULL;
  60. self->__dynamic_func_decl = NULL;
  61. pk_ManagedHeap__ctor(&self->heap, self);
  62. ValueStack__ctor(&self->stack);
  63. /* Init Builtin Types */
  64. // 0: unused
  65. void* placeholder = c11_vector__emplace(&self->types);
  66. memset(placeholder, 0, sizeof(pk_TypeInfo));
  67. #define validate(t, expr) \
  68. if(t != (expr)) abort()
  69. validate(tp_object, pk_newtype("object", 0, NULL, NULL, true, false));
  70. validate(tp_type, pk_newtype("type", 1, NULL, NULL, false, true));
  71. pk_object__register();
  72. validate(tp_int, pk_newtype("int", tp_object, NULL, NULL, false, true));
  73. validate(tp_float, pk_newtype("float", tp_object, NULL, NULL, false, true));
  74. validate(tp_bool, pk_newtype("bool", tp_object, NULL, NULL, false, true));
  75. pk_number__register();
  76. validate(tp_str, pk_str__register());
  77. validate(tp_str_iterator, pk_str_iterator__register());
  78. validate(tp_list, pk_list__register());
  79. validate(tp_tuple, pk_tuple__register());
  80. validate(tp_array_iterator, pk_array_iterator__register());
  81. validate(tp_slice, pk_slice__register());
  82. validate(tp_range, pk_range__register());
  83. validate(tp_range_iterator, pk_range_iterator__register());
  84. validate(tp_module, pk_newtype("module", tp_object, NULL, NULL, false, true));
  85. validate(tp_function, pk_function__register());
  86. validate(tp_nativefunc, pk_nativefunc__register());
  87. validate(tp_boundmethod, pk_newtype("boundmethod", tp_object, NULL, NULL, false, true));
  88. validate(tp_super, pk_newtype("super", tp_object, NULL, NULL, false, true));
  89. validate(tp_BaseException, pk_BaseException__register());
  90. validate(tp_Exception, pk_Exception__register());
  91. validate(tp_bytes, pk_bytes__register());
  92. validate(tp_mappingproxy, pk_newtype("mappingproxy", tp_object, NULL, NULL, false, true));
  93. validate(tp_dict, pk_dict__register());
  94. validate(tp_dict_items, pk_dict_items__register());
  95. validate(tp_property, pk_newtype("property", tp_object, NULL, NULL, false, true));
  96. validate(tp_star_wrapper, pk_newtype("star_wrapper", tp_object, NULL, NULL, false, true));
  97. validate(tp_staticmethod, pk_newtype("staticmethod", tp_object, NULL, NULL, false, true));
  98. validate(tp_classmethod, pk_newtype("classmethod", tp_object, NULL, NULL, false, true));
  99. validate(tp_NoneType, pk_newtype("NoneType", tp_object, NULL, NULL, false, true));
  100. validate(tp_NotImplementedType,
  101. pk_newtype("NotImplementedType", tp_object, NULL, NULL, false, true));
  102. validate(tp_ellipsis, pk_newtype("ellipsis", tp_object, NULL, NULL, false, true));
  103. validate(tp_SyntaxError, pk_newtype("SyntaxError", tp_Exception, NULL, NULL, false, true));
  104. validate(tp_StopIteration, pk_newtype("StopIteration", tp_Exception, NULL, NULL, false, true));
  105. #undef validate
  106. self->builtins = pk_builtins__register();
  107. /* Setup Public Builtin Types */
  108. py_Type public_types[] = {tp_object,
  109. tp_type,
  110. tp_int,
  111. tp_float,
  112. tp_bool,
  113. tp_str,
  114. tp_list,
  115. tp_tuple,
  116. tp_slice,
  117. tp_range,
  118. tp_bytes,
  119. tp_dict,
  120. tp_property,
  121. tp_BaseException,
  122. tp_Exception,
  123. tp_StopIteration,
  124. tp_SyntaxError};
  125. for(int i = 0; i < c11__count_array(public_types); i++) {
  126. py_Type t = public_types[i];
  127. pk_TypeInfo* ti = c11__at(pk_TypeInfo, &self->types, t);
  128. py_setdict(&self->builtins, ti->name, py_tpobject(t));
  129. }
  130. py_TValue tmp;
  131. py_newnotimplemented(&tmp);
  132. py_setdict(&self->builtins, py_name("NotImplemented"), &tmp);
  133. self->main = *py_newmodule("__main__", NULL);
  134. }
  135. void pk_VM__dtor(pk_VM* self) {
  136. if(self->__dynamic_func_decl) { PK_DECREF(self->__dynamic_func_decl); }
  137. // destroy all objects
  138. pk_ManagedHeap__dtor(&self->heap);
  139. // clear frames
  140. // ...
  141. pk_NameDict__dtor(&self->modules);
  142. c11__foreach(pk_TypeInfo, &self->types, ti) pk_TypeInfo__dtor(ti);
  143. c11_vector__dtor(&self->types);
  144. ValueStack__clear(&self->stack);
  145. }
  146. void pk_VM__push_frame(pk_VM* self, Frame* frame) {
  147. frame->f_back = self->top_frame;
  148. self->top_frame = frame;
  149. }
  150. void pk_VM__pop_frame(pk_VM* self) {
  151. assert(self->top_frame);
  152. Frame* frame = self->top_frame;
  153. // reset stack pointer
  154. self->stack.sp = frame->p0;
  155. // pop frame and delete
  156. self->top_frame = frame->f_back;
  157. Frame__delete(frame);
  158. }
  159. static void _clip_int(int* value, int min, int max) {
  160. if(*value < min) *value = min;
  161. if(*value > max) *value = max;
  162. }
  163. bool pk__parse_int_slice(const py_Ref slice, int length, int* start, int* stop, int* step) {
  164. py_Ref s_start = py_getslot(slice, 0);
  165. py_Ref s_stop = py_getslot(slice, 1);
  166. py_Ref s_step = py_getslot(slice, 2);
  167. if(py_isnone(s_step))
  168. *step = 1;
  169. else {
  170. if(!py_checkint(s_step)) return false;
  171. *step = py_toint(s_step);
  172. }
  173. if(*step == 0) return ValueError("slice step cannot be zero");
  174. if(*step > 0) {
  175. if(py_isnone(s_start))
  176. *start = 0;
  177. else {
  178. if(!py_checkint(s_start)) return false;
  179. *start = py_toint(s_start);
  180. if(*start < 0) *start += length;
  181. _clip_int(start, 0, length);
  182. }
  183. if(py_isnone(s_stop))
  184. *stop = length;
  185. else {
  186. if(!py_checkint(s_stop)) return false;
  187. *stop = py_toint(s_stop);
  188. if(*stop < 0) *stop += length;
  189. _clip_int(stop, 0, length);
  190. }
  191. } else {
  192. if(py_isnone(s_start))
  193. *start = length - 1;
  194. else {
  195. if(!py_checkint(s_start)) return false;
  196. *start = py_toint(s_start);
  197. if(*start < 0) *start += length;
  198. _clip_int(start, -1, length - 1);
  199. }
  200. if(py_isnone(s_stop))
  201. *stop = -1;
  202. else {
  203. if(!py_checkint(s_stop)) return false;
  204. *stop = py_toint(s_stop);
  205. if(*stop < 0) *stop += length;
  206. _clip_int(stop, -1, length - 1);
  207. }
  208. }
  209. return true;
  210. }
  211. bool pk__normalize_index(int* index, int length) {
  212. if(*index < 0) *index += length;
  213. if(*index < 0 || *index >= length) { return IndexError("index out of range"); }
  214. return true;
  215. }
  216. py_Type pk_newtype(const char* name,
  217. py_Type base,
  218. const py_GlobalRef module,
  219. void (*dtor)(void*),
  220. bool is_python,
  221. bool is_sealed) {
  222. c11_vector* types = &pk_current_vm->types;
  223. py_Type index = types->count;
  224. pk_TypeInfo* ti = c11_vector__emplace(types);
  225. pk_TypeInfo__ctor(ti, py_name(name), index, base, module);
  226. ti->dtor = dtor;
  227. ti->is_python = is_python;
  228. ti->is_sealed = is_sealed;
  229. return index;
  230. }
  231. py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) {
  232. return pk_newtype(name, base, module, dtor, false, false);
  233. }
  234. static bool
  235. prepare_py_call(py_TValue* buffer, py_Ref argv, py_Ref p1, int kwargc, const FuncDecl* decl) {
  236. const CodeObject* co = &decl->code;
  237. int decl_argc = decl->args.count;
  238. if(p1 - argv < decl_argc) {
  239. return TypeError("%s() takes %d positional arguments but %d were given",
  240. co->name->data,
  241. decl_argc,
  242. p1 - argv);
  243. }
  244. py_TValue* t = argv;
  245. // prepare args
  246. memset(buffer, 0, co->nlocals * sizeof(py_TValue));
  247. c11__foreach(int, &decl->args, index) buffer[*index] = *t++;
  248. // prepare kwdefaults
  249. c11__foreach(FuncDeclKwArg, &decl->kwargs, kv) buffer[kv->index] = kv->value;
  250. // handle *args
  251. if(decl->starred_arg != -1) {
  252. int exceed_argc = p1 - t;
  253. py_Ref vargs = &buffer[decl->starred_arg];
  254. py_newtuple(vargs, exceed_argc);
  255. for(int j = 0; j < exceed_argc; j++) {
  256. py_tuple__setitem(vargs, j, t++);
  257. }
  258. } else {
  259. // kwdefaults override
  260. // def f(a, b, c=None)
  261. // f(1, 2, 3) -> c=3
  262. c11__foreach(FuncDeclKwArg, &decl->kwargs, kv) {
  263. if(t >= p1) break;
  264. buffer[kv->index] = *t++;
  265. }
  266. // not able to consume all args
  267. if(t < p1) return TypeError("too many arguments (%s)", co->name->data);
  268. }
  269. if(decl->starred_kwarg != -1) py_newdict(&buffer[decl->starred_kwarg]);
  270. for(int j = 0; j < kwargc; j++) {
  271. py_Name key = py_toint(&p1[2 * j]);
  272. int index = c11_smallmap_n2i__get(&decl->kw_to_index, key, -1);
  273. // if key is an explicit key, set as local variable
  274. if(index >= 0) {
  275. buffer[index] = p1[2 * j + 1];
  276. } else {
  277. // otherwise, set as **kwargs if possible
  278. if(decl->starred_kwarg == -1) {
  279. return TypeError("'%n' is an invalid keyword argument for %s()",
  280. key,
  281. co->name->data);
  282. } else {
  283. // add to **kwargs
  284. py_Ref tmp = py_pushtmp();
  285. c11_sv key_sv = py_name2sv(key);
  286. py_newstrn(tmp, key_sv.data, key_sv.size);
  287. py_dict__setitem(&buffer[decl->starred_kwarg], tmp, &p1[2 * j + 1]);
  288. if(py_checkexc()) return false;
  289. py_pop();
  290. }
  291. }
  292. }
  293. return true;
  294. }
  295. pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bool opcall) {
  296. pk_print_stack(self, self->top_frame, (Bytecode){});
  297. py_Ref p1 = self->stack.sp - kwargc * 2;
  298. py_Ref p0 = p1 - argc - 2;
  299. // [callable, <self>, args..., kwargs...]
  300. // ^p0 ^p1 ^_sp
  301. #if 0
  302. // handle boundmethod, do a patch
  303. if(p0->type == tp_boundmethod) {
  304. assert(false);
  305. assert(py_isnil(p0 + 1)); // self must be NULL
  306. // BoundMethod& bm = PK_OBJ_GET(BoundMethod, callable);
  307. // callable = bm.func; // get unbound method
  308. // callable_t = _tp(callable);
  309. // p1[-(ARGC + 2)] = bm.func;
  310. // p1[-(ARGC + 1)] = bm.self;
  311. // [unbound, self, args..., kwargs...]
  312. }
  313. #endif
  314. py_Ref argv = py_isnil(p0 + 1) ? p0 + 2 : p0 + 1;
  315. if(p0->type == tp_function) {
  316. /*****************_py_call*****************/
  317. // check stack overflow
  318. if(self->stack.sp > self->stack.end) {
  319. py_exception("StackOverflowError", "");
  320. return RES_ERROR;
  321. }
  322. Function* fn = py_touserdata(p0);
  323. const CodeObject* co = &fn->decl->code;
  324. switch(fn->decl->type) {
  325. case FuncType_NORMAL: {
  326. bool ok = prepare_py_call(self->__vectorcall_buffer, argv, p1, kwargc, fn->decl);
  327. if(!ok) return RES_ERROR;
  328. // copy buffer back to stack
  329. self->stack.sp = argv + co->nlocals;
  330. memcpy(argv, self->__vectorcall_buffer, co->nlocals * sizeof(py_TValue));
  331. // submit the call
  332. if(!fn->cfunc) {
  333. pk_VM__push_frame(self, Frame__new(co, &fn->module, p0, p0, argv, co));
  334. return opcall ? RES_CALL : pk_VM__run_top_frame(self);
  335. } else {
  336. bool ok = py_callcfunc(p0, fn->cfunc, co->nlocals, argv);
  337. return ok ? RES_RETURN : RES_ERROR;
  338. }
  339. }
  340. case FuncType_SIMPLE:
  341. if(p1 - argv != fn->decl->args.count) {
  342. const char* fmt = "%s() takes %d positional arguments but %d were given";
  343. TypeError(fmt, co->name->data, fn->decl->args.count, p1 - argv);
  344. return RES_ERROR;
  345. }
  346. if(kwargc) {
  347. TypeError("%s() takes no keyword arguments", co->name->data);
  348. return RES_ERROR;
  349. }
  350. // [callable, <self>, args..., local_vars...]
  351. // ^p0 ^p1 ^_sp
  352. self->stack.sp = argv + co->nlocals;
  353. // initialize local variables to py_NIL
  354. memset(p1, 0, (char*)self->stack.sp - (char*)p1);
  355. // submit the call
  356. pk_VM__push_frame(self, Frame__new(co, &fn->module, p0, p0, argv, co));
  357. return opcall ? RES_CALL : pk_VM__run_top_frame(self);
  358. case FuncType_GENERATOR:
  359. assert(false);
  360. break;
  361. // prepare_py_call(__vectorcall_buffer, args, kwargs, fn.decl);
  362. // s_data.reset(p0);
  363. // callstack.emplace(nullptr, co, fn._module, callable.get(), nullptr);
  364. // return __py_generator(
  365. // callstack.popx(),
  366. // ArgsView(__vectorcall_buffer, __vectorcall_buffer + co->nlocals));
  367. default: c11__unreachedable();
  368. };
  369. c11__unreachedable();
  370. /*****************_py_call*****************/
  371. }
  372. if(p0->type == tp_nativefunc) {
  373. if(!py_callcfunc(p0, p0->_cfunc, p1 - argv, argv)) return RES_ERROR;
  374. return RES_RETURN;
  375. }
  376. if(p0->type == tp_type) {
  377. // [cls, NULL, args..., kwargs...]
  378. py_Ref new_f = py_tpfindmagic(py_totype(p0), __new__);
  379. assert(new_f && py_isnil(p0 + 1));
  380. // prepare a copy of args and kwargs
  381. int span = self->stack.sp - argv;
  382. *self->stack.sp++ = *new_f; // push __new__
  383. *self->stack.sp++ = *p0; // push cls
  384. memcpy(self->stack.sp, argv, span * sizeof(py_TValue));
  385. self->stack.sp += span;
  386. // [new_f, cls, args..., kwargs...]
  387. if(pk_VM__vectorcall(self, argc, kwargc, false) == RES_ERROR) return RES_ERROR;
  388. // by recursively using vectorcall, args and kwargs are consumed
  389. // try __init__
  390. // NOTE: previously we use `get_unbound_method` but here we just use `tpfindmagic`
  391. // >> [cls, NULL, args..., kwargs...]
  392. // >> py_retval() is the new instance
  393. py_Ref init_f = py_tpfindmagic(py_totype(p0), __init__);
  394. if(init_f) {
  395. // do an inplace patch
  396. *p0 = *init_f; // __init__
  397. p0[1] = self->last_retval; // self
  398. // [__init__, self, args..., kwargs...]
  399. if(pk_VM__vectorcall(self, argc, kwargc, false) == RES_ERROR) return RES_ERROR;
  400. *py_retval() = p0[1]; // restore the new instance
  401. }
  402. // reset the stack
  403. self->stack.sp = p0;
  404. return RES_RETURN;
  405. }
  406. // handle `__call__` overload
  407. if(py_getunboundmethod(p0, __call__, p0, p0 + 1)) {
  408. // [__call__, self, args..., kwargs...]
  409. return pk_VM__vectorcall(self, argc, kwargc, opcall);
  410. }
  411. TypeError("'%t' object is not callable", p0->type);
  412. c11__unreachedable();
  413. }
  414. /****************************************/
  415. void PyObject__delete(PyObject* self) {
  416. pk_TypeInfo* ti = c11__at(pk_TypeInfo, &pk_current_vm->types, self->type);
  417. if(ti->dtor) ti->dtor(PyObject__userdata(self));
  418. if(self->slots == -1) pk_NameDict__dtor(PyObject__dict(self));
  419. if(self->gc_is_large) {
  420. free(self);
  421. } else {
  422. PoolObject_dealloc(self);
  423. }
  424. }
  425. static void mark_object(PyObject* obj);
  426. static void mark_value(py_TValue* val) {
  427. if(val->is_ptr) mark_object(val->_obj);
  428. }
  429. static void mark_object(PyObject* obj) {
  430. if(obj->gc_marked) return;
  431. obj->gc_marked = true;
  432. if(obj->slots > 0) {
  433. py_TValue* p = PyObject__slots(obj);
  434. for(int i = 0; i < obj->slots; i++)
  435. mark_value(p + i);
  436. return;
  437. }
  438. if(obj->slots == -1) {
  439. pk_NameDict* dict = PyObject__dict(obj);
  440. for(int j = 0; j < dict->count; j++) {
  441. pk_NameDict_KV* kv = c11__at(pk_NameDict_KV, dict, j);
  442. mark_value(&kv->value);
  443. }
  444. return;
  445. }
  446. if(obj->type == tp_list) {
  447. pk_list__mark(PyObject__userdata(obj), mark_value);
  448. return;
  449. }
  450. if(obj->type == tp_dict) {
  451. pk_dict__mark(PyObject__userdata(obj), mark_value);
  452. return;
  453. }
  454. }
  455. void pk_ManagedHeap__mark(pk_ManagedHeap* self) {
  456. pk_VM* vm = self->vm;
  457. // mark heap objects
  458. for(int i = 0; i < self->no_gc.count; i++) {
  459. PyObject* obj = c11__getitem(PyObject*, &self->no_gc, i);
  460. mark_object(obj);
  461. }
  462. // mark value stack
  463. for(py_TValue* p = vm->stack.begin; p != vm->stack.end; p++) {
  464. mark_value(p);
  465. }
  466. // mark frame
  467. for(Frame* frame = vm->top_frame; frame; frame = frame->f_back) {
  468. mark_value(&frame->module);
  469. if(frame->function) mark_object(frame->function);
  470. }
  471. // mark vm's registers
  472. mark_value(&vm->last_retval);
  473. mark_value(&vm->last_exception);
  474. for(int i = 0; i < c11__count_array(vm->reg); i++) {
  475. mark_value(&vm->reg[i]);
  476. }
  477. }
  478. void pk_print_stack(pk_VM* self, Frame* frame, Bytecode byte) {
  479. return;
  480. py_TValue* sp = self->stack.sp;
  481. c11_sbuf buf;
  482. c11_sbuf__ctor(&buf);
  483. for(py_Ref p = self->stack.begin; p != sp; p++) {
  484. switch(p->type) {
  485. case 0: c11_sbuf__write_cstr(&buf, "nil"); break;
  486. case tp_int: c11_sbuf__write_i64(&buf, p->_i64); break;
  487. case tp_float: c11_sbuf__write_f64(&buf, p->_f64, -1); break;
  488. case tp_bool: c11_sbuf__write_cstr(&buf, p->_bool ? "True" : "False"); break;
  489. case tp_NoneType: c11_sbuf__write_cstr(&buf, "None"); break;
  490. case tp_list: {
  491. pk_sprintf(&buf, "list(%d)", py_list__len(p));
  492. break;
  493. }
  494. case tp_tuple: {
  495. pk_sprintf(&buf, "tuple(%d)", py_tuple__len(p));
  496. break;
  497. }
  498. case tp_function: {
  499. Function* ud = py_touserdata(p);
  500. c11_sbuf__write_cstr(&buf, ud->decl->code.name->data);
  501. c11_sbuf__write_cstr(&buf, "()");
  502. break;
  503. }
  504. case tp_type: {
  505. pk_sprintf(&buf, "<class '%t'>", py_totype(p));
  506. break;
  507. }
  508. case tp_str: {
  509. pk_sprintf(&buf, "%q", py_tosv(p));
  510. break;
  511. }
  512. default: {
  513. pk_sprintf(&buf, "(%t)", p->type);
  514. break;
  515. }
  516. }
  517. if(p != &sp[-1]) c11_sbuf__write_cstr(&buf, ", ");
  518. }
  519. c11_string* stack_str = c11_sbuf__submit(&buf);
  520. printf("L%-3d: %-25s %-6d [%s]\n",
  521. Frame__lineno(frame),
  522. pk_opname(byte.op),
  523. byte.arg,
  524. stack_str->data);
  525. c11_string__delete(stack_str);
  526. }