ceval.c 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247
  1. #include "pocketpy/common/str.h"
  2. #include "pocketpy/common/utils.h"
  3. #include "pocketpy/interpreter/frame.h"
  4. #include "pocketpy/interpreter/vm.h"
  5. #include "pocketpy/common/memorypool.h"
  6. #include "pocketpy/common/sstream.h"
  7. #include "pocketpy/objects/codeobject.h"
  8. #include "pocketpy/pocketpy.h"
  9. #include "pocketpy/objects/error.h"
  10. #include <stdbool.h>
  11. static bool stack_unpack_sequence(VM* self, uint16_t arg);
  12. static bool stack_format_object(VM* self, c11_sv spec);
  13. #define DISPATCH() \
  14. do { \
  15. frame->ip++; \
  16. goto __NEXT_STEP; \
  17. } while(0)
  18. #define DISPATCH_JUMP(__offset) \
  19. do { \
  20. frame->ip += __offset; \
  21. goto __NEXT_STEP; \
  22. } while(0)
  23. #define DISPATCH_JUMP_ABSOLUTE(__target) \
  24. do { \
  25. frame->ip = c11__at(Bytecode, &frame->co->codes, __target); \
  26. goto __NEXT_STEP; \
  27. } while(0)
  28. /* Stack manipulation macros */
  29. // https://github.com/python/cpython/blob/3.9/Python/ceval.c#L1123
  30. #define TOP() (self->stack.sp - 1)
  31. #define SECOND() (self->stack.sp - 2)
  32. #define THIRD() (self->stack.sp - 3)
  33. #define FOURTH() (self->stack.sp - 4)
  34. #define STACK_SHRINK(n) (self->stack.sp -= n)
  35. #define STACK_GROW(n) (self->stack.sp += n)
  36. #define PUSH(v) \
  37. do { \
  38. *self->stack.sp = *(v); \
  39. self->stack.sp++; \
  40. } while(0)
  41. #define POP() (--self->stack.sp)
  42. #define POPX() (*--self->stack.sp)
  43. #define SP() (self->stack.sp)
  44. // [a, b] -> [?, a, b]
  45. #define INSERT_THIRD() \
  46. do { \
  47. PUSH(TOP()); \
  48. *SECOND() = *THIRD(); \
  49. } while(0)
  50. #define vectorcall_opcall(argc, kwargc) \
  51. do { \
  52. FrameResult res = VM__vectorcall(self, (argc), (kwargc), true); \
  53. switch(res) { \
  54. case RES_RETURN: PUSH(&self->last_retval); break; \
  55. case RES_CALL: frame = self->top_frame; goto __NEXT_FRAME; \
  56. case RES_ERROR: goto __ERROR; \
  57. default: c11__unreachedable(); \
  58. } \
  59. } while(0)
  60. static bool unpack_dict_to_buffer(py_Ref key, py_Ref val, void* ctx) {
  61. py_TValue** p = ctx;
  62. if(py_isstr(key)) {
  63. py_Name name = py_namev(py_tosv(key));
  64. py_newint(*p, name);
  65. py_assign(*p + 1, val);
  66. (*p) += 2;
  67. return true;
  68. }
  69. return TypeError("keywords must be strings, not '%t'", key->type);
  70. }
  71. FrameResult VM__run_top_frame(VM* self) {
  72. Frame* frame = self->top_frame;
  73. const Frame* base_frame = frame;
  74. while(true) {
  75. Bytecode byte;
  76. __NEXT_FRAME:
  77. frame->ip++;
  78. __NEXT_STEP:
  79. byte = *frame->ip;
  80. #if PK_DEBUG
  81. pk_print_stack(self, frame, byte);
  82. // assert(!py_checkexc(true));
  83. #endif
  84. switch((Opcode)byte.op) {
  85. case OP_NO_OP: DISPATCH();
  86. /*****************************************/
  87. case OP_POP_TOP: POP(); DISPATCH();
  88. case OP_DUP_TOP: PUSH(TOP()); DISPATCH();
  89. case OP_DUP_TOP_TWO:
  90. // [a, b]
  91. PUSH(SECOND()); // [a, b, a]
  92. PUSH(SECOND()); // [a, b, a, b]
  93. DISPATCH();
  94. case OP_ROT_TWO: {
  95. py_TValue tmp = *TOP();
  96. *TOP() = *SECOND();
  97. *SECOND() = tmp;
  98. DISPATCH();
  99. }
  100. case OP_ROT_THREE: {
  101. // [a, b, c] -> [c, a, b]
  102. py_TValue tmp = *TOP();
  103. *TOP() = *SECOND();
  104. *SECOND() = *THIRD();
  105. *THIRD() = tmp;
  106. DISPATCH();
  107. }
  108. case OP_PRINT_EXPR:
  109. if(TOP()->type != tp_NoneType) {
  110. bool ok = py_repr(TOP());
  111. if(!ok) goto __ERROR;
  112. self->callbacks.print(py_tostr(&self->last_retval));
  113. self->callbacks.print("\n");
  114. }
  115. POP();
  116. DISPATCH();
  117. /*****************************************/
  118. case OP_LOAD_CONST: PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg)); DISPATCH();
  119. case OP_LOAD_NONE: py_newnone(SP()++); DISPATCH();
  120. case OP_LOAD_TRUE: py_newbool(SP()++, true); DISPATCH();
  121. case OP_LOAD_FALSE: py_newbool(SP()++, false); DISPATCH();
  122. /*****************************************/
  123. case OP_LOAD_SMALL_INT: py_newint(SP()++, (int16_t)byte.arg); DISPATCH();
  124. /*****************************************/
  125. case OP_LOAD_ELLIPSIS: py_newellipsis(SP()++); DISPATCH();
  126. case OP_LOAD_FUNCTION: {
  127. FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
  128. Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
  129. Function__ctor(ud, decl, frame->module);
  130. if(decl->nested) {
  131. ud->closure = FastLocals__to_namedict(frame->locals, frame->co);
  132. py_Name name = py_name(decl->code.name->data);
  133. // capture itself to allow recursion
  134. NameDict__set(ud->closure, name, *SP());
  135. }
  136. SP()++;
  137. DISPATCH();
  138. }
  139. case OP_LOAD_NULL:
  140. py_newnil(SP()++);
  141. DISPATCH();
  142. /*****************************************/
  143. case OP_LOAD_FAST: {
  144. PUSH(&frame->locals[byte.arg]);
  145. if(py_isnil(TOP())) {
  146. py_Name name = c11__getitem(uint16_t, &frame->co->varnames, byte.arg);
  147. UnboundLocalError(name);
  148. goto __ERROR;
  149. }
  150. DISPATCH();
  151. }
  152. case OP_LOAD_NAME: {
  153. assert(frame->is_dynamic);
  154. py_Name name = byte.arg;
  155. py_TValue* tmp;
  156. py_newstr(SP()++, py_name2str(name));
  157. // locals
  158. if(!py_isnone(&frame->p0[1])) {
  159. if(py_getitem(&frame->p0[1], TOP())) {
  160. py_assign(TOP(), py_retval());
  161. DISPATCH();
  162. } else {
  163. if(py_matchexc(tp_KeyError)) {
  164. py_clearexc(NULL);
  165. } else {
  166. goto __ERROR;
  167. }
  168. }
  169. }
  170. // globals
  171. if(py_getitem(&frame->p0[0], TOP())) {
  172. py_assign(TOP(), py_retval());
  173. DISPATCH();
  174. } else {
  175. if(py_matchexc(tp_KeyError)) {
  176. py_clearexc(NULL);
  177. } else {
  178. goto __ERROR;
  179. }
  180. }
  181. // builtins
  182. tmp = py_getdict(&self->builtins, name);
  183. if(tmp != NULL) {
  184. py_assign(TOP(), tmp);
  185. DISPATCH();
  186. }
  187. NameError(name);
  188. goto __ERROR;
  189. }
  190. case OP_LOAD_NONLOCAL: {
  191. py_Name name = byte.arg;
  192. py_Ref tmp = Frame__f_closure_try_get(frame, name);
  193. if(tmp != NULL) {
  194. PUSH(tmp);
  195. DISPATCH();
  196. }
  197. tmp = py_getdict(frame->module, name);
  198. if(tmp != NULL) {
  199. PUSH(tmp);
  200. DISPATCH();
  201. }
  202. tmp = py_getdict(&self->builtins, name);
  203. if(tmp != NULL) {
  204. PUSH(tmp);
  205. DISPATCH();
  206. }
  207. NameError(name);
  208. goto __ERROR;
  209. }
  210. case OP_LOAD_GLOBAL: {
  211. py_Name name = byte.arg;
  212. py_Ref tmp = py_getdict(frame->module, name);
  213. if(tmp != NULL) {
  214. PUSH(tmp);
  215. DISPATCH();
  216. }
  217. tmp = py_getdict(&self->builtins, name);
  218. if(tmp != NULL) {
  219. PUSH(tmp);
  220. DISPATCH();
  221. }
  222. NameError(name);
  223. goto __ERROR;
  224. }
  225. case OP_LOAD_ATTR: {
  226. if(py_getattr(TOP(), byte.arg)) {
  227. py_assign(TOP(), py_retval());
  228. } else {
  229. goto __ERROR;
  230. }
  231. DISPATCH();
  232. }
  233. case OP_LOAD_CLASS_GLOBAL: {
  234. py_Name name = byte.arg;
  235. py_Ref tmp = py_getdict(self->__curr_class, name);
  236. if(tmp) {
  237. PUSH(tmp);
  238. DISPATCH();
  239. }
  240. // load global if attribute not found
  241. tmp = py_getdict(frame->module, name);
  242. if(tmp) {
  243. PUSH(tmp);
  244. DISPATCH();
  245. }
  246. tmp = py_getdict(&self->builtins, name);
  247. if(tmp) {
  248. PUSH(tmp);
  249. DISPATCH();
  250. }
  251. NameError(name);
  252. goto __ERROR;
  253. }
  254. case OP_LOAD_METHOD: {
  255. // [self] -> [unbound, self]
  256. bool ok = py_pushmethod(byte.arg);
  257. if(!ok) {
  258. // fallback to getattr
  259. if(py_getattr(TOP(), byte.arg)) {
  260. py_assign(TOP(), py_retval());
  261. py_newnil(SP()++);
  262. } else {
  263. goto __ERROR;
  264. }
  265. }
  266. DISPATCH();
  267. }
  268. case OP_LOAD_SUBSCR: {
  269. // [a, b] -> a[b]
  270. py_Ref magic = py_tpfindmagic(SECOND()->type, __getitem__);
  271. if(magic) {
  272. if(magic->type == tp_nativefunc) {
  273. if(!py_callcfunc(magic->_cfunc, 2, SECOND())) goto __ERROR;
  274. POP();
  275. } else {
  276. INSERT_THIRD(); // [?, a, b]
  277. *THIRD() = *magic; // [__getitem__, a, b]
  278. if(!py_vectorcall(1, 0)) goto __ERROR;
  279. }
  280. *TOP() = self->last_retval;
  281. DISPATCH();
  282. }
  283. TypeError("'%t' object is not subscriptable", SECOND()->type);
  284. goto __ERROR;
  285. }
  286. case OP_STORE_FAST: frame->locals[byte.arg] = POPX(); DISPATCH();
  287. case OP_STORE_NAME: {
  288. assert(frame->is_dynamic);
  289. py_Name name = byte.arg;
  290. py_newstr(SP()++, py_name2str(name));
  291. // [value, name]
  292. if(!py_isnone(&frame->p0[1])) {
  293. // locals
  294. if(py_setitem(&frame->p0[1], TOP(), SECOND())) {
  295. STACK_SHRINK(2);
  296. DISPATCH();
  297. } else {
  298. if(py_matchexc(tp_KeyError)) {
  299. py_clearexc(NULL);
  300. NameError(name);
  301. }
  302. goto __ERROR;
  303. }
  304. } else {
  305. // globals
  306. if(py_setitem(&frame->p0[0], TOP(), SECOND())) {
  307. STACK_SHRINK(2);
  308. DISPATCH();
  309. } else {
  310. if(py_matchexc(tp_KeyError)) {
  311. py_clearexc(NULL);
  312. NameError(name);
  313. }
  314. goto __ERROR;
  315. }
  316. }
  317. DISPATCH();
  318. }
  319. case OP_STORE_GLOBAL: {
  320. py_setdict(frame->module, byte.arg, TOP());
  321. POP();
  322. DISPATCH();
  323. }
  324. case OP_STORE_ATTR: {
  325. // [val, a] -> a.b = val
  326. if(!py_setattr(TOP(), byte.arg, SECOND())) goto __ERROR;
  327. STACK_SHRINK(2);
  328. DISPATCH();
  329. }
  330. case OP_STORE_SUBSCR: {
  331. // [val, a, b] -> a[b] = val
  332. py_Ref magic = py_tpfindmagic(SECOND()->type, __setitem__);
  333. if(magic) {
  334. PUSH(THIRD()); // [val, a, b, val]
  335. if(magic->type == tp_nativefunc) {
  336. if(!py_callcfunc(magic->_cfunc, 3, THIRD())) goto __ERROR;
  337. STACK_SHRINK(4);
  338. } else {
  339. *FOURTH() = *magic; // [__selitem__, a, b, val]
  340. if(!py_vectorcall(2, 0)) goto __ERROR;
  341. POP(); // discard retval
  342. }
  343. DISPATCH();
  344. }
  345. TypeError("'%t' object does not support item assignment", SECOND()->type);
  346. goto __ERROR;
  347. }
  348. case OP_DELETE_FAST: {
  349. py_Ref tmp = &frame->locals[byte.arg];
  350. if(py_isnil(tmp)) {
  351. py_Name name = c11__getitem(py_Name, &frame->co->varnames, byte.arg);
  352. UnboundLocalError(name);
  353. goto __ERROR;
  354. }
  355. py_newnil(tmp);
  356. DISPATCH();
  357. }
  358. case OP_DELETE_NAME: {
  359. assert(frame->is_dynamic);
  360. py_Name name = byte.arg;
  361. py_newstr(SP()++, py_name2str(name));
  362. if(!py_isnone(&frame->p0[1])) {
  363. // locals
  364. if(py_delitem(&frame->p0[1], TOP())) {
  365. POP();
  366. DISPATCH();
  367. } else {
  368. if(py_matchexc(tp_KeyError)) {
  369. py_clearexc(NULL);
  370. NameError(name);
  371. }
  372. goto __ERROR;
  373. }
  374. } else {
  375. // globals
  376. if(py_delitem(&frame->p0[0], TOP())) {
  377. POP();
  378. DISPATCH();
  379. } else {
  380. if(py_matchexc(tp_KeyError)) {
  381. py_clearexc(NULL);
  382. NameError(name);
  383. }
  384. goto __ERROR;
  385. }
  386. }
  387. DISPATCH();
  388. }
  389. case OP_DELETE_GLOBAL: {
  390. py_Name name = byte.arg;
  391. bool ok = py_deldict(frame->module, name);
  392. if(!ok) {
  393. NameError(name);
  394. goto __ERROR;
  395. }
  396. DISPATCH();
  397. }
  398. case OP_DELETE_ATTR: {
  399. if(!py_delattr(TOP(), byte.arg)) goto __ERROR;
  400. DISPATCH();
  401. }
  402. case OP_DELETE_SUBSCR: {
  403. // [a, b] -> del a[b]
  404. py_Ref magic = py_tpfindmagic(SECOND()->type, __delitem__);
  405. if(magic) {
  406. if(magic->type == tp_nativefunc) {
  407. if(!py_callcfunc(magic->_cfunc, 2, SECOND())) goto __ERROR;
  408. STACK_SHRINK(2);
  409. } else {
  410. INSERT_THIRD(); // [?, a, b]
  411. *THIRD() = *magic; // [__delitem__, a, b]
  412. if(!py_vectorcall(1, 0)) goto __ERROR;
  413. POP(); // discard retval
  414. }
  415. DISPATCH();
  416. }
  417. TypeError("'%t' object does not support item deletion", SECOND()->type);
  418. goto __ERROR;
  419. }
  420. /*****************************************/
  421. case OP_BUILD_IMAG: {
  422. // [x]
  423. py_Ref f = py_getdict(&self->builtins, py_name("complex"));
  424. assert(f != NULL);
  425. py_TValue tmp = *TOP();
  426. *TOP() = *f; // [complex]
  427. py_newnil(SP()++); // [complex, NULL]
  428. py_newint(SP()++, 0); // [complex, NULL, 0]
  429. *SP()++ = tmp; // [complex, NULL, 0, x]
  430. if(!py_vectorcall(2, 0)) goto __ERROR;
  431. PUSH(py_retval());
  432. DISPATCH();
  433. }
  434. case OP_BUILD_BYTES: {
  435. int size;
  436. py_Ref string = c11__at(py_TValue, &frame->co->consts, byte.arg);
  437. const char* data = py_tostrn(string, &size);
  438. unsigned char* p = py_newbytes(SP()++, size);
  439. memcpy(p, data, size);
  440. DISPATCH();
  441. }
  442. case OP_BUILD_TUPLE: {
  443. py_TValue tmp;
  444. py_newtuple(&tmp, byte.arg);
  445. py_TValue* begin = SP() - byte.arg;
  446. for(int i = 0; i < byte.arg; i++) {
  447. py_tuple_setitem(&tmp, i, begin + i);
  448. }
  449. SP() = begin;
  450. PUSH(&tmp);
  451. DISPATCH();
  452. }
  453. case OP_BUILD_LIST: {
  454. py_TValue tmp;
  455. py_newlistn(&tmp, byte.arg);
  456. py_TValue* begin = SP() - byte.arg;
  457. for(int i = 0; i < byte.arg; i++) {
  458. py_list_setitem(&tmp, i, begin + i);
  459. }
  460. SP() = begin;
  461. PUSH(&tmp);
  462. DISPATCH();
  463. }
  464. case OP_BUILD_DICT: {
  465. py_TValue* begin = SP() - byte.arg * 2;
  466. py_Ref tmp = py_pushtmp();
  467. py_newdict(tmp);
  468. for(int i = 0; i < byte.arg * 2; i += 2) {
  469. bool ok = py_dict_setitem(tmp, begin + i, begin + i + 1);
  470. if(!ok) goto __ERROR;
  471. }
  472. SP() = begin;
  473. PUSH(tmp);
  474. DISPATCH();
  475. }
  476. case OP_BUILD_SET: {
  477. py_TValue* begin = SP() - byte.arg;
  478. py_Ref typeobject_set = py_getdict(&self->builtins, py_name("set"));
  479. assert(typeobject_set != NULL);
  480. py_push(typeobject_set);
  481. py_pushnil();
  482. if(!py_vectorcall(0, 0)) goto __ERROR;
  483. py_push(py_retval()); // empty set
  484. py_Name id_add = py_name("add");
  485. for(int i = 0; i < byte.arg; i++) {
  486. py_push(TOP());
  487. if(!py_pushmethod(id_add)) {
  488. c11__abort("OP_BUILD_SET: failed to load method 'add'");
  489. }
  490. py_push(begin + i);
  491. if(!py_vectorcall(1, 0)) goto __ERROR;
  492. }
  493. py_TValue tmp = *TOP();
  494. SP() = begin;
  495. PUSH(&tmp);
  496. DISPATCH();
  497. }
  498. case OP_BUILD_SLICE: {
  499. // [start, stop, step]
  500. py_TValue tmp;
  501. py_newslice(&tmp);
  502. py_setslot(&tmp, 0, THIRD());
  503. py_setslot(&tmp, 1, SECOND());
  504. py_setslot(&tmp, 2, TOP());
  505. STACK_SHRINK(3);
  506. PUSH(&tmp);
  507. DISPATCH();
  508. }
  509. case OP_BUILD_STRING: {
  510. py_TValue* begin = SP() - byte.arg;
  511. c11_sbuf ss;
  512. c11_sbuf__ctor(&ss);
  513. for(int i = 0; i < byte.arg; i++) {
  514. if(!py_str(begin + i)) goto __ERROR;
  515. c11_sbuf__write_sv(&ss, py_tosv(&self->last_retval));
  516. }
  517. SP() = begin;
  518. c11_sbuf__py_submit(&ss, SP()++);
  519. DISPATCH();
  520. }
  521. /*****************************/
  522. case OP_BINARY_OP: {
  523. py_Name op = byte.arg & 0xFF;
  524. py_Name rop = byte.arg >> 8;
  525. if(!pk_stack_binaryop(self, op, rop)) goto __ERROR;
  526. POP();
  527. *TOP() = self->last_retval;
  528. DISPATCH();
  529. }
  530. case OP_IS_OP: {
  531. bool res = py_isidentical(SECOND(), TOP());
  532. POP();
  533. if(byte.arg) res = !res;
  534. py_newbool(TOP(), res);
  535. DISPATCH();
  536. }
  537. case OP_CONTAINS_OP: {
  538. // [b, a] -> b __contains__ a (a in b) -> [retval]
  539. py_Ref magic = py_tpfindmagic(SECOND()->type, __contains__);
  540. if(magic) {
  541. if(magic->type == tp_nativefunc) {
  542. if(!py_callcfunc(magic->_cfunc, 2, SECOND())) goto __ERROR;
  543. STACK_SHRINK(2);
  544. } else {
  545. INSERT_THIRD(); // [?, b, a]
  546. *THIRD() = *magic; // [__contains__, a, b]
  547. if(!py_vectorcall(1, 0)) goto __ERROR;
  548. }
  549. bool res = py_tobool(py_retval());
  550. if(byte.arg) res = !res;
  551. py_newbool(SP()++, res);
  552. DISPATCH();
  553. }
  554. TypeError("'%t' type does not support '__contains__'", SECOND()->type);
  555. goto __ERROR;
  556. }
  557. /*****************************************/
  558. case OP_JUMP_FORWARD: DISPATCH_JUMP((int16_t)byte.arg);
  559. case OP_POP_JUMP_IF_FALSE: {
  560. int res = py_bool(TOP());
  561. if(res < 0) goto __ERROR;
  562. POP();
  563. if(!res) DISPATCH_JUMP((int16_t)byte.arg);
  564. DISPATCH();
  565. }
  566. case OP_POP_JUMP_IF_TRUE: {
  567. int res = py_bool(TOP());
  568. if(res < 0) goto __ERROR;
  569. POP();
  570. if(res) DISPATCH_JUMP((int16_t)byte.arg);
  571. DISPATCH();
  572. }
  573. case OP_JUMP_IF_TRUE_OR_POP: {
  574. int res = py_bool(TOP());
  575. if(res < 0) goto __ERROR;
  576. if(res) {
  577. DISPATCH_JUMP((int16_t)byte.arg);
  578. } else {
  579. POP();
  580. DISPATCH();
  581. }
  582. }
  583. case OP_JUMP_IF_FALSE_OR_POP: {
  584. int res = py_bool(TOP());
  585. if(res < 0) goto __ERROR;
  586. if(!res) {
  587. DISPATCH_JUMP((int16_t)byte.arg);
  588. } else {
  589. POP();
  590. DISPATCH();
  591. }
  592. }
  593. case OP_SHORTCUT_IF_FALSE_OR_POP: {
  594. int res = py_bool(TOP());
  595. if(res < 0) goto __ERROR;
  596. if(!res) { // [b, False]
  597. STACK_SHRINK(2); // []
  598. py_newbool(SP()++, false); // [False]
  599. DISPATCH_JUMP((int16_t)byte.arg);
  600. } else {
  601. POP(); // [b]
  602. DISPATCH();
  603. }
  604. }
  605. case OP_LOOP_CONTINUE:
  606. // just an alias of OP_JUMP_FORWARD
  607. DISPATCH_JUMP((int16_t)byte.arg);
  608. case OP_LOOP_BREAK: {
  609. int target = Frame__ip(frame) + byte.arg;
  610. Frame__prepare_jump_break(frame, &self->stack, target);
  611. DISPATCH_JUMP((int16_t)byte.arg);
  612. }
  613. case OP_JUMP_ABSOLUTE_TOP: {
  614. int target = py_toint(TOP());
  615. POP();
  616. DISPATCH_JUMP_ABSOLUTE(target);
  617. }
  618. case OP_GOTO: {
  619. int target = c11_smallmap_n2i__get(&frame->co->labels, byte.arg, -1);
  620. if(target < 0) {
  621. RuntimeError("label '%n' not found", byte.arg);
  622. goto __ERROR;
  623. }
  624. Frame__prepare_jump_break(frame, &self->stack, target);
  625. DISPATCH_JUMP_ABSOLUTE(target);
  626. }
  627. /*****************************************/
  628. case OP_CALL: {
  629. ManagedHeap__collect_if_needed(&self->heap);
  630. vectorcall_opcall(byte.arg & 0xFF, byte.arg >> 8);
  631. DISPATCH();
  632. }
  633. case OP_CALL_VARGS: {
  634. // [_0, _1, _2 | k1, v1, k2, v2]
  635. uint16_t argc = byte.arg & 0xFF;
  636. uint16_t kwargc = byte.arg >> 8;
  637. int n = 0;
  638. py_TValue* sp = SP();
  639. py_TValue* p1 = sp - kwargc * 2;
  640. py_TValue* base = p1 - argc;
  641. py_TValue* buf = self->__vectorcall_buffer;
  642. for(py_TValue* curr = base; curr != p1; curr++) {
  643. if(curr->type != tp_star_wrapper) {
  644. buf[n++] = *curr;
  645. } else {
  646. py_TValue* args = py_getslot(curr, 0);
  647. py_TValue* p;
  648. int length = pk_arrayview(args, &p);
  649. if(length != -1) {
  650. for(int j = 0; j < length; j++) {
  651. buf[n++] = p[j];
  652. }
  653. argc += length - 1;
  654. } else {
  655. TypeError("*args must be a list or tuple, got '%t'", args->type);
  656. goto __ERROR;
  657. }
  658. }
  659. }
  660. for(py_TValue* curr = p1; curr != sp; curr += 2) {
  661. if(curr[1].type != tp_star_wrapper) {
  662. buf[n++] = curr[0];
  663. buf[n++] = curr[1];
  664. } else {
  665. assert(py_toint(&curr[0]) == 0);
  666. py_TValue* kwargs = py_getslot(&curr[1], 0);
  667. if(kwargs->type == tp_dict) {
  668. py_TValue* p = buf + n;
  669. if(!py_dict_apply(kwargs, unpack_dict_to_buffer, &p)) goto __ERROR;
  670. n = p - buf;
  671. kwargc += py_dict_len(kwargs) - 1;
  672. } else {
  673. TypeError("**kwargs must be a dict, got '%t'", kwargs->type);
  674. goto __ERROR;
  675. }
  676. }
  677. }
  678. memcpy(base, buf, n * sizeof(py_TValue));
  679. SP() = base + n;
  680. vectorcall_opcall(argc, kwargc);
  681. DISPATCH();
  682. }
  683. case OP_RETURN_VALUE: {
  684. if(byte.arg == BC_NOARG) {
  685. self->last_retval = POPX();
  686. } else {
  687. py_newnone(&self->last_retval);
  688. }
  689. VM__pop_frame(self);
  690. if(frame == base_frame) { // [ frameBase<- ]
  691. return RES_RETURN;
  692. } else {
  693. frame = self->top_frame;
  694. PUSH(&self->last_retval);
  695. goto __NEXT_FRAME;
  696. }
  697. DISPATCH();
  698. }
  699. case OP_YIELD_VALUE: {
  700. py_assign(py_retval(), TOP());
  701. POP();
  702. return RES_YIELD;
  703. }
  704. /////////
  705. case OP_LIST_APPEND: {
  706. // [list, iter, value]
  707. py_list_append(THIRD(), TOP());
  708. POP();
  709. DISPATCH();
  710. }
  711. case OP_DICT_ADD: {
  712. // [dict, iter, key, value]
  713. bool ok = py_dict_setitem(FOURTH(), SECOND(), TOP());
  714. if(!ok) goto __ERROR;
  715. STACK_SHRINK(2);
  716. DISPATCH();
  717. }
  718. case OP_SET_ADD: {
  719. // [set, iter, value]
  720. py_push(THIRD()); // [| set]
  721. if(!py_pushmethod(py_name("add"))) {
  722. c11__abort("OP_SET_ADD: failed to load method 'add'");
  723. } // [|add() set]
  724. py_push(THIRD());
  725. if(!py_vectorcall(1, 0)) goto __ERROR;
  726. POP();
  727. DISPATCH();
  728. }
  729. /////////
  730. case OP_UNARY_NEGATIVE: {
  731. if(!pk_callmagic(__neg__, 1, TOP())) goto __ERROR;
  732. *TOP() = self->last_retval;
  733. DISPATCH();
  734. }
  735. case OP_UNARY_NOT: {
  736. int res = py_bool(TOP());
  737. if(res < 0) goto __ERROR;
  738. py_newbool(TOP(), !res);
  739. DISPATCH();
  740. }
  741. case OP_UNARY_STAR: {
  742. py_TValue value = POPX();
  743. int* level = py_newobject(SP()++, tp_star_wrapper, 1, sizeof(int));
  744. *level = byte.arg;
  745. py_setslot(TOP(), 0, &value);
  746. DISPATCH();
  747. }
  748. case OP_UNARY_INVERT: {
  749. if(!pk_callmagic(__invert__, 1, TOP())) goto __ERROR;
  750. *TOP() = self->last_retval;
  751. DISPATCH();
  752. }
  753. ////////////////
  754. case OP_GET_ITER: {
  755. if(!py_iter(TOP())) goto __ERROR;
  756. *TOP() = *py_retval();
  757. DISPATCH();
  758. }
  759. case OP_FOR_ITER: {
  760. int res = py_next(TOP());
  761. if(res == -1) goto __ERROR;
  762. if(res) {
  763. PUSH(py_retval());
  764. DISPATCH();
  765. } else {
  766. int target = Frame__prepare_loop_break(frame, &self->stack);
  767. DISPATCH_JUMP_ABSOLUTE(target);
  768. }
  769. }
  770. ////////
  771. case OP_IMPORT_PATH: {
  772. py_Ref path_object = c11__at(py_TValue, &frame->co->consts, byte.arg);
  773. const char* path = py_tostr(path_object);
  774. int res = py_import(path);
  775. if(res == -1) goto __ERROR;
  776. if(res == 0) {
  777. ImportError("No module named '%s'", path);
  778. goto __ERROR;
  779. }
  780. PUSH(py_retval());
  781. DISPATCH();
  782. }
  783. case OP_POP_IMPORT_STAR: {
  784. // [module]
  785. NameDict* dict = PyObject__dict(TOP()->_obj);
  786. py_Ref all = NameDict__try_get(dict, __all__);
  787. if(all) {
  788. py_TValue* p;
  789. int length = pk_arrayview(all, &p);
  790. if(length == -1) {
  791. TypeError("'__all__' must be a list or tuple, got '%t'", all->type);
  792. goto __ERROR;
  793. }
  794. for(int i = 0; i < length; i++) {
  795. py_Name name = py_namev(py_tosv(p + i));
  796. py_Ref value = NameDict__try_get(dict, name);
  797. if(value == NULL) {
  798. ImportError("cannot import name '%n'", name);
  799. goto __ERROR;
  800. } else {
  801. py_setdict(frame->module, name, value);
  802. }
  803. }
  804. } else {
  805. for(int i = 0; i < dict->length; i++) {
  806. NameDict_KV* kv = c11__at(NameDict_KV, dict, i);
  807. if(!kv->key) continue;
  808. c11_sv name = py_name2sv(kv->key);
  809. if(name.size == 0 || name.data[0] == '_') continue;
  810. py_setdict(frame->module, kv->key, &kv->value);
  811. }
  812. }
  813. POP();
  814. DISPATCH();
  815. }
  816. ////////
  817. case OP_UNPACK_SEQUENCE: {
  818. if(!stack_unpack_sequence(self, byte.arg)) goto __ERROR;
  819. DISPATCH();
  820. }
  821. case OP_UNPACK_EX: {
  822. py_TValue* p;
  823. int length = pk_arrayview(TOP(), &p);
  824. if(length == -1) {
  825. TypeError("expected list or tuple to unpack, got %t", TOP()->type);
  826. goto __ERROR;
  827. }
  828. int exceed = length - byte.arg;
  829. if(exceed < 0) {
  830. ValueError("not enough values to unpack");
  831. goto __ERROR;
  832. }
  833. POP();
  834. for(int i = 0; i < byte.arg; i++) {
  835. PUSH(p + i);
  836. }
  837. py_newlistn(SP()++, exceed);
  838. for(int i = 0; i < exceed; i++) {
  839. py_list_setitem(TOP(), i, p + byte.arg + i);
  840. }
  841. DISPATCH();
  842. }
  843. ///////////
  844. case OP_BEGIN_CLASS: {
  845. // [base]
  846. py_Name name = byte.arg;
  847. py_Type base;
  848. if(py_isnone(TOP())) {
  849. base = tp_object;
  850. } else {
  851. if(!py_checktype(TOP(), tp_type)) goto __ERROR;
  852. base = py_totype(TOP());
  853. }
  854. POP();
  855. py_TypeInfo* base_ti = TypeList__get(&self->types, base);
  856. if(base_ti->is_sealed) {
  857. TypeError("type '%t' is not an acceptable base type", base);
  858. goto __ERROR;
  859. }
  860. py_Type type =
  861. pk_newtype(py_name2str(name), base, frame->module, NULL, true, false);
  862. PUSH(py_tpobject(type));
  863. self->__curr_class = TOP();
  864. DISPATCH();
  865. }
  866. case OP_END_CLASS: {
  867. // [cls or decorated]
  868. // TODO: if __eq__ is defined, check __ne__ and provide a default implementation
  869. py_Name name = byte.arg;
  870. // set into f_globals
  871. py_setdict(frame->module, name, TOP());
  872. if(py_istype(TOP(), tp_type)) {
  873. // call on_end_subclass
  874. py_TypeInfo* ti = TypeList__get(&self->types, py_totype(TOP()));
  875. if(ti->base != tp_object) {
  876. py_TypeInfo* base_ti = ti->base_ti;
  877. if(base_ti->on_end_subclass) base_ti->on_end_subclass(ti);
  878. }
  879. }
  880. POP();
  881. self->__curr_class = NULL;
  882. DISPATCH();
  883. }
  884. case OP_STORE_CLASS_ATTR: {
  885. py_Name name = byte.arg;
  886. if(py_istype(TOP(), tp_function)) {
  887. Function* ud = py_touserdata(TOP());
  888. ud->clazz = self->__curr_class->_obj;
  889. }
  890. py_setdict(self->__curr_class, name, TOP());
  891. POP();
  892. DISPATCH();
  893. }
  894. case OP_ADD_CLASS_ANNOTATION: {
  895. // [type_hint string]
  896. py_Type type = py_totype(self->__curr_class);
  897. py_TypeInfo* ti = TypeList__get(&self->types, type);
  898. if(py_isnil(&ti->annotations)) py_newdict(&ti->annotations);
  899. bool ok = py_dict_setitem_by_str(&ti->annotations, py_name2str(byte.arg), TOP());
  900. if(!ok) goto __ERROR;
  901. POP();
  902. DISPATCH();
  903. }
  904. ///////////
  905. case OP_WITH_ENTER: {
  906. // [expr]
  907. py_push(TOP());
  908. if(!py_pushmethod(__enter__)) {
  909. TypeError("'%t' object does not support the context manager protocol",
  910. TOP()->type);
  911. goto __ERROR;
  912. }
  913. if(!py_vectorcall(0, 0)) goto __ERROR;
  914. PUSH(py_retval());
  915. DISPATCH();
  916. }
  917. case OP_WITH_EXIT: {
  918. // [expr]
  919. py_push(TOP());
  920. if(!py_pushmethod(__exit__)) {
  921. TypeError("'%t' object does not support the context manager protocol",
  922. TOP()->type);
  923. goto __ERROR;
  924. }
  925. if(!py_vectorcall(0, 0)) goto __ERROR;
  926. DISPATCH();
  927. }
  928. ///////////
  929. case OP_TRY_ENTER: {
  930. Frame__set_unwind_target(frame, SP());
  931. DISPATCH();
  932. }
  933. case OP_EXCEPTION_MATCH: {
  934. if(!py_checktype(TOP(), tp_type)) goto __ERROR;
  935. bool ok = py_isinstance(&self->curr_exception, py_totype(TOP()));
  936. py_newbool(TOP(), ok);
  937. DISPATCH();
  938. }
  939. case OP_RAISE: {
  940. // [exception]
  941. if(py_istype(TOP(), tp_type)) {
  942. if(!py_tpcall(py_totype(TOP()), 0, NULL)) goto __ERROR;
  943. py_assign(TOP(), py_retval());
  944. }
  945. if(!py_isinstance(TOP(), tp_BaseException)) {
  946. TypeError("exceptions must derive from BaseException");
  947. goto __ERROR;
  948. }
  949. py_raise(TOP());
  950. goto __ERROR;
  951. }
  952. case OP_RAISE_ASSERT: {
  953. if(byte.arg) {
  954. if(!py_str(TOP())) goto __ERROR;
  955. POP();
  956. py_exception(tp_AssertionError, "%s", py_tostr(py_retval()));
  957. } else {
  958. py_exception(tp_AssertionError, "");
  959. }
  960. goto __ERROR;
  961. }
  962. case OP_RE_RAISE: {
  963. assert(self->curr_exception.type);
  964. goto __ERROR_RE_RAISE;
  965. }
  966. case OP_PUSH_EXCEPTION: {
  967. assert(self->curr_exception.type);
  968. PUSH(&self->curr_exception);
  969. DISPATCH();
  970. }
  971. case OP_BEGIN_EXC_HANDLING: {
  972. self->is_curr_exc_handled = true;
  973. DISPATCH();
  974. }
  975. case OP_END_EXC_HANDLING: {
  976. assert(self->curr_exception.type);
  977. py_clearexc(NULL);
  978. DISPATCH();
  979. }
  980. //////////////////
  981. case OP_FORMAT_STRING: {
  982. py_Ref spec = c11__at(py_TValue, &frame->co->consts, byte.arg);
  983. bool ok = stack_format_object(self, py_tosv(spec));
  984. if(!ok) goto __ERROR;
  985. DISPATCH();
  986. }
  987. default: c11__unreachedable();
  988. }
  989. c11__unreachedable();
  990. __ERROR:
  991. pk_print_stack(self, frame, (Bytecode){0});
  992. py_BaseException__set_lineno(&self->curr_exception, Frame__lineno(frame), frame->co);
  993. __ERROR_RE_RAISE:
  994. do {
  995. } while(0);
  996. // printf("error.op: %s, line: %d\n", pk_opname(byte.op), Frame__lineno(frame));
  997. int lineno = py_BaseException__get_lineno(&self->curr_exception, frame->co);
  998. py_BaseException__stpush(&self->curr_exception,
  999. frame->co->src,
  1000. lineno < 0 ? Frame__lineno(frame) : lineno,
  1001. frame->has_function ? frame->co->name->data : NULL);
  1002. int target = Frame__prepare_jump_exception_handler(frame, &self->stack);
  1003. if(target >= 0) {
  1004. // 1. Exception can be handled inside the current frame
  1005. DISPATCH_JUMP_ABSOLUTE(target);
  1006. } else {
  1007. // 2. Exception need to be propagated to the upper frame
  1008. bool is_base_frame_to_be_popped = frame == base_frame;
  1009. VM__pop_frame(self);
  1010. if(self->top_frame == NULL || is_base_frame_to_be_popped) {
  1011. // propagate to the top level
  1012. return RES_ERROR;
  1013. }
  1014. frame = self->top_frame;
  1015. goto __ERROR;
  1016. }
  1017. }
  1018. return RES_RETURN;
  1019. }
  1020. bool pk_stack_binaryop(VM* self, py_Name op, py_Name rop) {
  1021. // [a, b]
  1022. py_Ref magic = py_tpfindmagic(SECOND()->type, op);
  1023. if(magic) {
  1024. bool ok = py_call(magic, 2, SECOND());
  1025. if(!ok) return false;
  1026. if(self->last_retval.type != tp_NotImplementedType) return true;
  1027. }
  1028. // try reverse operation
  1029. if(rop) {
  1030. // [a, b] -> [b, a]
  1031. py_TValue tmp = *TOP();
  1032. *TOP() = *SECOND();
  1033. *SECOND() = tmp;
  1034. magic = py_tpfindmagic(SECOND()->type, rop);
  1035. if(magic) {
  1036. bool ok = py_call(magic, 2, SECOND());
  1037. if(!ok) return false;
  1038. if(self->last_retval.type != tp_NotImplementedType) return true;
  1039. }
  1040. }
  1041. // eq/ne op never fails
  1042. bool res = py_isidentical(SECOND(), TOP());
  1043. if(op == __eq__) {
  1044. py_newbool(py_retval(), res);
  1045. return true;
  1046. }
  1047. if(op == __ne__) {
  1048. py_newbool(py_retval(), !res);
  1049. return true;
  1050. }
  1051. return TypeError("unsupported operand type(s) for '%n'", op);
  1052. }
  1053. bool py_binaryop(py_Ref lhs, py_Ref rhs, py_Name op, py_Name rop) {
  1054. VM* self = pk_current_vm;
  1055. PUSH(lhs);
  1056. PUSH(rhs);
  1057. bool ok = pk_stack_binaryop(self, op, rop);
  1058. STACK_SHRINK(2);
  1059. return ok;
  1060. }
  1061. static bool stack_unpack_sequence(VM* self, uint16_t arg) {
  1062. py_TValue* p;
  1063. int length = pk_arrayview(TOP(), &p);
  1064. if(length == -1) return TypeError("expected list or tuple to unpack, got %t", TOP()->type);
  1065. if(length != arg) return ValueError("expected %d values to unpack, got %d", arg, length);
  1066. POP();
  1067. for(int i = 0; i < length; i++) {
  1068. PUSH(p + i);
  1069. }
  1070. return true;
  1071. }
  1072. static bool stack_format_object(VM* self, c11_sv spec) {
  1073. // format TOS via `spec` inplace
  1074. // spec: '!r:.2f', '.2f'
  1075. py_StackRef val = TOP();
  1076. if(spec.size == 0) return py_str(val);
  1077. if(spec.data[0] == '!') {
  1078. if(c11_sv__startswith(spec, (c11_sv){"!r", 2})) {
  1079. spec.data += 2;
  1080. spec.size -= 2;
  1081. if(!py_repr(val)) return false;
  1082. py_assign(val, py_retval());
  1083. if(spec.size == 0) return true;
  1084. } else {
  1085. return ValueError("invalid conversion specifier (only !r is supported)");
  1086. }
  1087. }
  1088. assert(spec.size > 0);
  1089. if(spec.data[0] == ':') {
  1090. spec.data++;
  1091. spec.size--;
  1092. }
  1093. char type;
  1094. switch(spec.data[spec.size - 1]) {
  1095. case 'f':
  1096. case 'd':
  1097. case 's':
  1098. type = spec.data[spec.size - 1];
  1099. spec.size--; // remove last char
  1100. break;
  1101. default: type = ' '; break;
  1102. }
  1103. char pad_c = ' ';
  1104. if(strchr("0-=*#@!~", spec.data[0])) {
  1105. pad_c = spec.data[0];
  1106. spec = c11_sv__slice(spec, 1);
  1107. }
  1108. char align;
  1109. if(spec.data[0] == '^') {
  1110. align = '^';
  1111. spec = c11_sv__slice(spec, 1);
  1112. } else if(spec.data[0] == '>') {
  1113. align = '>';
  1114. spec = c11_sv__slice(spec, 1);
  1115. } else if(spec.data[0] == '<') {
  1116. align = '<';
  1117. spec = c11_sv__slice(spec, 1);
  1118. } else {
  1119. align = (py_isint(val) || py_isfloat(val)) ? '>' : '<';
  1120. }
  1121. int dot = c11_sv__index(spec, '.');
  1122. py_i64 width, precision;
  1123. if(dot >= 0) {
  1124. if(dot == 0) {
  1125. // {.2f}
  1126. width = -1;
  1127. } else {
  1128. // {10.2f}
  1129. IntParsingResult res = c11__parse_uint(c11_sv__slice2(spec, 0, dot), &width, 10);
  1130. if(res != IntParsing_SUCCESS) return ValueError("invalid format specifer");
  1131. }
  1132. IntParsingResult res = c11__parse_uint(c11_sv__slice(spec, dot + 1), &precision, 10);
  1133. if(res != IntParsing_SUCCESS) return ValueError("invalid format specifer");
  1134. } else {
  1135. // {10s}
  1136. IntParsingResult res = c11__parse_uint(spec, &width, 10);
  1137. if(res != IntParsing_SUCCESS) return ValueError("invalid format specifer");
  1138. precision = -1;
  1139. }
  1140. if(type != 'f' && dot >= 0) {
  1141. return ValueError("precision not allowed in the format specifier");
  1142. }
  1143. c11_sbuf buf;
  1144. c11_sbuf__ctor(&buf);
  1145. if(type == 'f') {
  1146. py_f64 x;
  1147. if(!py_castfloat(val, &x)) {
  1148. c11_sbuf__dtor(&buf);
  1149. return false;
  1150. }
  1151. if(precision < 0) precision = 6;
  1152. c11_sbuf__write_f64(&buf, x, precision);
  1153. } else if(type == 'd') {
  1154. if(!py_checkint(val)) {
  1155. c11_sbuf__dtor(&buf);
  1156. return false;
  1157. }
  1158. c11_sbuf__write_i64(&buf, py_toint(val));
  1159. } else if(type == 's') {
  1160. if(!py_checkstr(val)) {
  1161. c11_sbuf__dtor(&buf);
  1162. return false;
  1163. }
  1164. c11_sbuf__write_sv(&buf, py_tosv(val));
  1165. } else {
  1166. if(!py_str(val)) {
  1167. c11_sbuf__dtor(&buf);
  1168. return false;
  1169. }
  1170. c11_sbuf__write_sv(&buf, py_tosv(py_retval()));
  1171. }
  1172. c11_string* body = c11_sbuf__submit(&buf);
  1173. int length = c11_sv__u8_length(c11_string__sv(body));
  1174. c11_sbuf__ctor(&buf); // reinit sbuf
  1175. if(width != -1 && width > length) {
  1176. switch(align) {
  1177. case '>': {
  1178. c11_sbuf__write_pad(&buf, width - length, pad_c);
  1179. c11_sbuf__write_sv(&buf, c11_string__sv(body));
  1180. break;
  1181. }
  1182. case '<': {
  1183. c11_sbuf__write_sv(&buf, c11_string__sv(body));
  1184. c11_sbuf__write_pad(&buf, width - length, pad_c);
  1185. break;
  1186. }
  1187. case '^': {
  1188. int pad_left = (width - length) / 2;
  1189. int pad_right = (width - length) - pad_left;
  1190. c11_sbuf__write_pad(&buf, pad_left, pad_c);
  1191. c11_sbuf__write_sv(&buf, c11_string__sv(body));
  1192. c11_sbuf__write_pad(&buf, pad_right, pad_c);
  1193. break;
  1194. }
  1195. default: c11__unreachedable();
  1196. }
  1197. } else {
  1198. c11_sbuf__write_sv(&buf, c11_string__sv(body));
  1199. }
  1200. c11_string__delete(body);
  1201. // inplace update
  1202. c11_sbuf__py_submit(&buf, val);
  1203. return true;
  1204. }