vm.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  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 = PY_NIL;
  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_newtype("dict", tp_object, NULL, NULL, false, false));
  94. validate(tp_property, pk_newtype("property", tp_object, NULL, NULL, false, true));
  95. validate(tp_star_wrapper, pk_newtype("star_wrapper", tp_object, NULL, NULL, false, true));
  96. validate(tp_staticmethod, pk_newtype("staticmethod", tp_object, NULL, NULL, false, true));
  97. validate(tp_classmethod, pk_newtype("classmethod", tp_object, NULL, NULL, false, true));
  98. validate(tp_NoneType, pk_newtype("NoneType", tp_object, NULL, NULL, false, true));
  99. validate(tp_NotImplementedType,
  100. pk_newtype("NotImplementedType", tp_object, NULL, NULL, false, true));
  101. validate(tp_ellipsis, pk_newtype("ellipsis", tp_object, NULL, NULL, false, true));
  102. validate(tp_SyntaxError, pk_newtype("SyntaxError", tp_Exception, NULL, NULL, false, true));
  103. validate(tp_StopIteration, pk_newtype("StopIteration", tp_Exception, NULL, NULL, false, true));
  104. #undef validate
  105. self->builtins = pk_builtins__register();
  106. /* Setup Public Builtin Types */
  107. py_Type public_types[] = {tp_object,
  108. tp_type,
  109. tp_int,
  110. tp_float,
  111. tp_bool,
  112. tp_str,
  113. tp_list,
  114. tp_tuple,
  115. tp_slice,
  116. tp_range,
  117. tp_bytes,
  118. tp_dict,
  119. tp_property,
  120. tp_BaseException,
  121. tp_Exception,
  122. tp_StopIteration,
  123. tp_SyntaxError};
  124. for(int i = 0; i < c11__count_array(public_types); i++) {
  125. py_Type t = public_types[i];
  126. pk_TypeInfo* ti = c11__at(pk_TypeInfo, &self->types, t);
  127. py_setdict(&self->builtins, ti->name, py_tpobject(t));
  128. }
  129. py_TValue tmp;
  130. py_newnotimplemented(&tmp);
  131. py_setdict(&self->builtins, py_name("NotImplemented"), &tmp);
  132. self->main = *py_newmodule("__main__", NULL);
  133. }
  134. void pk_VM__dtor(pk_VM* self) {
  135. if(self->__dynamic_func_decl) { PK_DECREF(self->__dynamic_func_decl); }
  136. // destroy all objects
  137. pk_ManagedHeap__dtor(&self->heap);
  138. // clear frames
  139. // ...
  140. pk_NameDict__dtor(&self->modules);
  141. c11__foreach(pk_TypeInfo, &self->types, ti) pk_TypeInfo__dtor(ti);
  142. c11_vector__dtor(&self->types);
  143. ValueStack__clear(&self->stack);
  144. }
  145. void pk_VM__push_frame(pk_VM* self, Frame* frame) {
  146. frame->f_back = self->top_frame;
  147. self->top_frame = frame;
  148. }
  149. void pk_VM__pop_frame(pk_VM* self) {
  150. assert(self->top_frame);
  151. Frame* frame = self->top_frame;
  152. // reset stack pointer
  153. self->stack.sp = frame->p0;
  154. // pop frame and delete
  155. self->top_frame = frame->f_back;
  156. Frame__delete(frame);
  157. }
  158. static void _clip_int(int* value, int min, int max) {
  159. if(*value < min) *value = min;
  160. if(*value > max) *value = max;
  161. }
  162. bool pk__parse_int_slice(const py_Ref slice, int length, int* start, int* stop, int* step) {
  163. py_Ref s_start = py_getslot(slice, 0);
  164. py_Ref s_stop = py_getslot(slice, 1);
  165. py_Ref s_step = py_getslot(slice, 2);
  166. if(py_isnone(s_step))
  167. *step = 1;
  168. else {
  169. if(!py_checkint(s_step)) return false;
  170. *step = py_toint(s_step);
  171. }
  172. if(*step == 0) return ValueError("slice step cannot be zero");
  173. if(*step > 0) {
  174. if(py_isnone(s_start))
  175. *start = 0;
  176. else {
  177. if(!py_checkint(s_start)) return false;
  178. *start = py_toint(s_start);
  179. if(*start < 0) *start += length;
  180. _clip_int(start, 0, length);
  181. }
  182. if(py_isnone(s_stop))
  183. *stop = length;
  184. else {
  185. if(!py_checkint(s_stop)) return false;
  186. *stop = py_toint(s_stop);
  187. if(*stop < 0) *stop += length;
  188. _clip_int(stop, 0, length);
  189. }
  190. } else {
  191. if(py_isnone(s_start))
  192. *start = length - 1;
  193. else {
  194. if(!py_checkint(s_start)) return false;
  195. *start = py_toint(s_start);
  196. if(*start < 0) *start += length;
  197. _clip_int(start, -1, length - 1);
  198. }
  199. if(py_isnone(s_stop))
  200. *stop = -1;
  201. else {
  202. if(!py_checkint(s_stop)) return false;
  203. *stop = py_toint(s_stop);
  204. if(*stop < 0) *stop += length;
  205. _clip_int(stop, -1, length - 1);
  206. }
  207. }
  208. return true;
  209. }
  210. bool pk__normalize_index(int* index, int length) {
  211. if(*index < 0) *index += length;
  212. if(*index < 0 || *index >= length) { return IndexError("index out of range"); }
  213. return true;
  214. }
  215. py_Type pk_newtype(const char* name,
  216. py_Type base,
  217. const py_GlobalRef module,
  218. void (*dtor)(void*),
  219. bool is_python,
  220. bool is_sealed) {
  221. c11_vector* types = &pk_current_vm->types;
  222. py_Type index = types->count;
  223. pk_TypeInfo* ti = c11_vector__emplace(types);
  224. pk_TypeInfo__ctor(ti, py_name(name), index, base, module);
  225. ti->dtor = dtor;
  226. ti->is_python = is_python;
  227. ti->is_sealed = is_sealed;
  228. return index;
  229. }
  230. py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) {
  231. return pk_newtype(name, base, module, dtor, false, false);
  232. }
  233. static bool
  234. __prepare_py_call(py_TValue* buffer, py_Ref argv, py_Ref p1, int kwargc, const FuncDecl* decl) {
  235. const CodeObject* co = &decl->code;
  236. int decl_argc = decl->args.count;
  237. if(p1 - argv < decl_argc) {
  238. return TypeError("%s() takes %d positional arguments but %d were given",
  239. co->name->data,
  240. decl_argc,
  241. p1 - argv);
  242. }
  243. py_TValue* t = argv;
  244. // prepare args
  245. memset(buffer, 0, co->nlocals * sizeof(py_TValue));
  246. c11__foreach(int, &decl->args, index) buffer[*index] = *t++;
  247. // prepare kwdefaults
  248. c11__foreach(FuncDeclKwArg, &decl->kwargs, kv) buffer[kv->index] = kv->value;
  249. // handle *args
  250. if(decl->starred_arg != -1) {
  251. int exceed_argc = p1 - t;
  252. py_Ref vargs = &buffer[decl->starred_arg];
  253. py_newtuple(vargs, exceed_argc);
  254. for(int j = 0; j < exceed_argc; j++) {
  255. py_tuple__setitem(vargs, j, t++);
  256. }
  257. } else {
  258. // kwdefaults override
  259. // def f(a, b, c=None)
  260. // f(1, 2, 3) -> c=3
  261. c11__foreach(FuncDeclKwArg, &decl->kwargs, kv) {
  262. if(t >= p1) break;
  263. buffer[kv->index] = *t++;
  264. }
  265. // not able to consume all args
  266. if(t < p1) return TypeError("too many arguments (%s)", co->name->data);
  267. }
  268. if(decl->starred_kwarg != -1) py_newdict(&buffer[decl->starred_kwarg]);
  269. for(int j = 0; j < kwargc; j++) {
  270. py_Name key = py_toint(&p1[2 * j]);
  271. int index = c11_smallmap_n2i__get(&decl->kw_to_index, key, -1);
  272. // if key is an explicit key, set as local variable
  273. if(index >= 0) {
  274. buffer[index] = p1[2 * j + 1];
  275. } else {
  276. // otherwise, set as **kwargs if possible
  277. if(decl->starred_kwarg == -1) {
  278. return TypeError("'%n' is an invalid keyword argument for %s()",
  279. key,
  280. co->name->data);
  281. } else {
  282. // add to **kwargs
  283. // Dict& dict = _CAST(Dict&, vkwargs);
  284. // dict.set(this, VAR(key.sv()), kwargs[j + 1]);
  285. assert(false);
  286. }
  287. }
  288. }
  289. return true;
  290. }
  291. pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bool opcall) {
  292. pk_print_stack(self, self->top_frame, (Bytecode){});
  293. py_Ref p1 = self->stack.sp - kwargc * 2;
  294. py_Ref p0 = p1 - argc - 2;
  295. // [callable, <self>, args..., kwargs...]
  296. // ^p0 ^p1 ^_sp
  297. #if 0
  298. // handle boundmethod, do a patch
  299. if(p0->type == tp_boundmethod) {
  300. assert(false);
  301. assert(py_isnil(p0 + 1)); // self must be NULL
  302. // BoundMethod& bm = PK_OBJ_GET(BoundMethod, callable);
  303. // callable = bm.func; // get unbound method
  304. // callable_t = _tp(callable);
  305. // p1[-(ARGC + 2)] = bm.func;
  306. // p1[-(ARGC + 1)] = bm.self;
  307. // [unbound, self, args..., kwargs...]
  308. }
  309. #endif
  310. py_Ref argv = py_isnil(p0 + 1) ? p0 + 2 : p0 + 1;
  311. if(p0->type == tp_function) {
  312. /*****************_py_call*****************/
  313. // check stack overflow
  314. if(self->stack.sp > self->stack.end) {
  315. py_exception("StackOverflowError", "");
  316. return RES_ERROR;
  317. }
  318. Function* fn = py_touserdata(p0);
  319. const CodeObject* co = &fn->decl->code;
  320. switch(fn->decl->type) {
  321. case FuncType_NORMAL: {
  322. bool ok = __prepare_py_call(self->__vectorcall_buffer, argv, p1, kwargc, fn->decl);
  323. if(!ok) return RES_ERROR;
  324. // copy buffer back to stack
  325. self->stack.sp = argv + co->nlocals;
  326. memcpy(argv, self->__vectorcall_buffer, co->nlocals * sizeof(py_TValue));
  327. // submit the call
  328. if(!fn->cfunc) {
  329. pk_VM__push_frame(self, Frame__new(co, fn->module, p0, p0, argv, co));
  330. return opcall ? RES_CALL : pk_VM__run_top_frame(self);
  331. } else {
  332. bool ok = fn->cfunc(co->nlocals, argv);
  333. self->stack.sp = p0;
  334. return ok ? RES_RETURN : RES_ERROR;
  335. }
  336. }
  337. case FuncType_SIMPLE:
  338. if(p1 - argv != fn->decl->args.count) {
  339. const char* fmt = "%s() takes %d positional arguments but %d were given";
  340. TypeError(fmt, co->name->data, fn->decl->args.count, p1 - argv);
  341. return RES_ERROR;
  342. }
  343. if(kwargc) {
  344. TypeError("%s() takes no keyword arguments", co->name->data);
  345. return RES_ERROR;
  346. }
  347. // [callable, <self>, args..., local_vars...]
  348. // ^p0 ^p1 ^_sp
  349. self->stack.sp = argv + co->nlocals;
  350. // initialize local variables to PY_NIL
  351. memset(p1, 0, (char*)self->stack.sp - (char*)p1);
  352. // submit the call
  353. pk_VM__push_frame(self, Frame__new(co, fn->module, p0, p0, argv, co));
  354. return opcall ? RES_CALL : pk_VM__run_top_frame(self);
  355. case FuncType_GENERATOR:
  356. assert(false);
  357. break;
  358. // __prepare_py_call(__vectorcall_buffer, args, kwargs, fn.decl);
  359. // s_data.reset(p0);
  360. // callstack.emplace(nullptr, co, fn._module, callable.get(), nullptr);
  361. // return __py_generator(
  362. // callstack.popx(),
  363. // ArgsView(__vectorcall_buffer, __vectorcall_buffer + co->nlocals));
  364. default: c11__unreachedable();
  365. };
  366. c11__unreachedable();
  367. /*****************_py_call*****************/
  368. }
  369. if(p0->type == tp_nativefunc) {
  370. // const auto& f = PK_OBJ_GET(NativeFunc, callable);
  371. // PyVar ret;
  372. // if(f.decl != nullptr) {
  373. // int co_nlocals = f.decl->code->nlocals;
  374. // __prepare_py_call(__vectorcall_buffer, args, kwargs, f.decl);
  375. // // copy buffer back to stack
  376. // s_data.reset(_base + co_nlocals);
  377. // for(int j = 0; j < co_nlocals; j++)
  378. // _base[j] = __vectorcall_buffer[j];
  379. // ret = f.call(vm, ArgsView(s_data._sp - co_nlocals, s_data._sp));
  380. // } else {
  381. // if(f.argc != -1) {
  382. // if(KWARGC != 0)
  383. // TypeError(
  384. // "old-style native_func does not accept keyword arguments. If you want to
  385. // skip this check, specify `argc` to -1");
  386. // if(args.size() != f.argc) {
  387. // vm->TypeError(_S("expected ", f.argc, " arguments, got ", args.size()));
  388. // }
  389. // }
  390. // ret = f.call(this, args);
  391. // }
  392. // `argc` passed to _cfunc must include self if exists
  393. if(!p0->_cfunc(p1 - argv, argv)) return RES_ERROR;
  394. self->stack.sp = p0;
  395. return RES_RETURN;
  396. }
  397. if(p0->type == tp_type) {
  398. // [cls, NULL, args..., kwargs...]
  399. py_Ref new_f = py_tpfindmagic(py_totype(p0), __new__);
  400. assert(new_f && py_isnil(p0 + 1));
  401. // prepare a copy of args and kwargs
  402. int span = self->stack.sp - argv;
  403. *self->stack.sp++ = *new_f; // push __new__
  404. *self->stack.sp++ = *p0; // push cls
  405. memcpy(self->stack.sp, argv, span * sizeof(py_TValue));
  406. self->stack.sp += span;
  407. // [new_f, cls, args..., kwargs...]
  408. pk_FrameResult res = pk_VM__vectorcall(self, argc, kwargc, false);
  409. if(res == RES_ERROR) return RES_ERROR;
  410. assert(res == RES_RETURN);
  411. // by recursively using vectorcall, args and kwargs are consumed
  412. // [cls, NULL, args..., kwargs...]
  413. // try __init__
  414. // NOTE: previous we use `get_unbound_method` but here we just use `tpfindmagic`
  415. py_Ref init_f = py_tpfindmagic(py_totype(p0), __init__);
  416. if(init_f) {
  417. // do an inplace patch
  418. *p0 = *init_f; // __init__
  419. p0[1] = self->last_retval; // self
  420. // [__init__, self, args..., kwargs...]
  421. pk_FrameResult res = pk_VM__vectorcall(self, argc, kwargc, false);
  422. if(res == RES_ERROR) return RES_ERROR;
  423. assert(res == RES_RETURN);
  424. } else {
  425. // manually reset the stack
  426. self->stack.sp = p0;
  427. }
  428. return RES_RETURN;
  429. }
  430. // handle `__call__` overload
  431. if(py_getunboundmethod(p0, __call__, p0, p0 + 1)) {
  432. // [__call__, self, args..., kwargs...]
  433. pk_FrameResult res = pk_VM__vectorcall(self, argc, kwargc, false);
  434. if(res == RES_ERROR) return RES_ERROR;
  435. assert(res == RES_RETURN);
  436. }
  437. TypeError("'%t' object is not callable", p0->type);
  438. c11__unreachedable();
  439. }
  440. /****************************************/
  441. void PyObject__delete(PyObject* self) {
  442. pk_TypeInfo* ti = c11__at(pk_TypeInfo, &pk_current_vm->types, self->type);
  443. if(ti->dtor) ti->dtor(PyObject__userdata(self));
  444. if(self->slots == -1) pk_NameDict__dtor(PyObject__dict(self));
  445. if(self->gc_is_large) {
  446. free(self);
  447. } else {
  448. PoolObject_dealloc(self);
  449. }
  450. }
  451. static void mark_object(PyObject* obj);
  452. static void mark_value(py_TValue* val) {
  453. if(val->is_ptr) mark_object(val->_obj);
  454. }
  455. static void mark_object(PyObject* obj) {
  456. if(obj->gc_marked) return;
  457. obj->gc_marked = true;
  458. // list is a special case
  459. if(obj->type == tp_list) {
  460. c11_vector* vec = PyObject__userdata(obj);
  461. c11__foreach(py_TValue, vec, p) mark_value(p);
  462. return;
  463. }
  464. if(obj->slots > 0) {
  465. py_TValue* p = PyObject__slots(obj);
  466. for(int i = 0; i < obj->slots; i++)
  467. mark_value(p + i);
  468. return;
  469. }
  470. if(obj->slots == -1) {
  471. pk_NameDict* dict = PyObject__dict(obj);
  472. for(int j = 0; j < dict->count; j++) {
  473. pk_NameDict_KV* kv = c11__at(pk_NameDict_KV, dict, j);
  474. mark_value(&kv->value);
  475. }
  476. return;
  477. }
  478. }
  479. void pk_ManagedHeap__mark(pk_ManagedHeap* self) {
  480. pk_VM* vm = self->vm;
  481. // mark heap objects
  482. for(int i = 0; i < self->no_gc.count; i++) {
  483. PyObject* obj = c11__getitem(PyObject*, &self->no_gc, i);
  484. mark_object(obj);
  485. }
  486. // mark value stack
  487. for(py_TValue* p = vm->stack.begin; p != vm->stack.end; p++) {
  488. mark_value(p);
  489. }
  490. // mark vm's registers
  491. mark_value(&vm->last_retval);
  492. mark_value(&vm->last_exception);
  493. for(int i = 0; i < c11__count_array(vm->reg); i++) {
  494. mark_value(&vm->reg[i]);
  495. }
  496. mark_value(&vm->__curr_class);
  497. }
  498. void pk_print_stack(pk_VM* self, Frame* frame, Bytecode byte) {
  499. return;
  500. py_TValue* sp = self->stack.sp;
  501. c11_sbuf buf;
  502. c11_sbuf__ctor(&buf);
  503. for(py_Ref p = self->stack.begin; p != sp; p++) {
  504. switch(p->type) {
  505. case 0: c11_sbuf__write_cstr(&buf, "nil"); break;
  506. case tp_int: c11_sbuf__write_i64(&buf, p->_i64); break;
  507. case tp_float: c11_sbuf__write_f64(&buf, p->_f64, -1); break;
  508. case tp_bool: c11_sbuf__write_cstr(&buf, p->_bool ? "True" : "False"); break;
  509. case tp_NoneType: c11_sbuf__write_cstr(&buf, "None"); break;
  510. case tp_list: {
  511. pk_sprintf(&buf, "list(%d)", py_list__len(p));
  512. break;
  513. }
  514. case tp_tuple: {
  515. pk_sprintf(&buf, "tuple(%d)", py_tuple__len(p));
  516. break;
  517. }
  518. case tp_function: {
  519. Function* ud = py_touserdata(p);
  520. c11_sbuf__write_cstr(&buf, ud->decl->code.name->data);
  521. c11_sbuf__write_cstr(&buf, "()");
  522. break;
  523. }
  524. case tp_type: {
  525. pk_sprintf(&buf, "<class '%t'>", py_totype(p));
  526. break;
  527. }
  528. case tp_str: {
  529. pk_sprintf(&buf, "%q", py_tosv(p));
  530. break;
  531. }
  532. default: {
  533. pk_sprintf(&buf, "(%t)", p->type);
  534. break;
  535. }
  536. }
  537. if(p != &sp[-1]) c11_sbuf__write_cstr(&buf, ", ");
  538. }
  539. c11_string* stack_str = c11_sbuf__submit(&buf);
  540. printf("L%-3d: %-25s %-6d [%s]\n",
  541. Frame__lineno(frame),
  542. pk_opname(byte.op),
  543. byte.arg,
  544. stack_str->data);
  545. c11_string__delete(stack_str);
  546. }