ceval.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. #include "pocketpy/interpreter/vm.h"
  2. #include "pocketpy/common/memorypool.h"
  3. #include "pocketpy/common/sstream.h"
  4. #include "pocketpy/objects/codeobject.h"
  5. #include "pocketpy/pocketpy.h"
  6. int UnboundLocalError(py_Name name) { return -1; }
  7. int NameError(py_Name name) { return -1; }
  8. #define AttributeError(obj, name) false
  9. #define BinaryOptError(op) false
  10. static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop);
  11. #define DISPATCH() \
  12. do { \
  13. frame->ip++; \
  14. goto __NEXT_STEP; \
  15. } while(0)
  16. #define DISPATCH_JUMP(__offset) \
  17. do { \
  18. frame->ip += __offset; \
  19. goto __NEXT_STEP; \
  20. } while(0)
  21. #define DISPATCH_JUMP_ABSOLUTE(__target) \
  22. do { \
  23. frame->ip = c11__at(Bytecode, &frame->co->codes, __target); \
  24. goto __NEXT_STEP; \
  25. } while(0)
  26. /* Stack manipulation macros */
  27. // https://github.com/python/cpython/blob/3.9/Python/ceval.c#L1123
  28. #define TOP() (self->stack.sp - 1)
  29. #define SECOND() (self->stack.sp - 2)
  30. #define THIRD() (self->stack.sp - 3)
  31. #define FOURTH() (self->stack.sp - 4)
  32. #define STACK_SHRINK(n) (self->stack.sp -= n)
  33. #define PUSH(v) (*self->stack.sp++ = *v)
  34. #define POP() (--self->stack.sp)
  35. #define POPX() (*--self->stack.sp)
  36. #define SP() (self->stack.sp)
  37. // [a, b] -> [?, a, b]
  38. #define INSERT_THIRD() \
  39. do { \
  40. PUSH(TOP()); \
  41. *SECOND() = *THIRD(); \
  42. } while(0)
  43. #define vectorcall_opcall(n) \
  44. do { \
  45. pk_FrameResult res = pk_vectorcall(n, 0, true); \
  46. switch(res) { \
  47. case RES_RETURN: PUSH(&self->last_retval); break; \
  48. case RES_CALL: \
  49. frame = self->top_frame; \
  50. PUSH(&self->last_retval); \
  51. goto __NEXT_FRAME; \
  52. case RES_ERROR: goto __ERROR; \
  53. default: PK_UNREACHABLE(); \
  54. } \
  55. } while(0)
  56. pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
  57. Frame* frame = self->top_frame;
  58. const Frame* base_frame = frame;
  59. while(true) {
  60. Bytecode byte;
  61. __NEXT_FRAME:
  62. // if(__internal_exception.type == InternalExceptionType::Null) {
  63. // // None
  64. // frame->_ip++;
  65. // } else if(__internal_exception.type == InternalExceptionType::Handled) {
  66. // // HandledException + continue
  67. // frame->_ip = c11__at(Bytecode, &frame->co->codes, __internal_exception.arg);
  68. // __internal_exception = {};
  69. // } else {
  70. // // UnhandledException + continue (need_raise = true)
  71. // // ToBeRaisedException + continue (need_raise = true)
  72. // __internal_exception = {};
  73. // __raise_exc(); // no return
  74. // }
  75. frame->ip++;
  76. __NEXT_STEP:
  77. byte = *frame->ip;
  78. switch((Opcode)byte.op) {
  79. case OP_NO_OP: DISPATCH();
  80. /*****************************************/
  81. case OP_POP_TOP: POP(); DISPATCH();
  82. case OP_DUP_TOP: PUSH(TOP()); DISPATCH();
  83. case OP_DUP_TOP_TWO:
  84. // [a, b]
  85. PUSH(SECOND()); // [a, b, a]
  86. PUSH(SECOND()); // [a, b, a, b]
  87. DISPATCH();
  88. case OP_ROT_TWO: {
  89. py_TValue tmp = *TOP();
  90. *TOP() = *SECOND();
  91. *SECOND() = tmp;
  92. DISPATCH();
  93. }
  94. case OP_ROT_THREE: {
  95. // [a, b, c] -> [c, a, b]
  96. py_TValue tmp = *TOP();
  97. *TOP() = *SECOND();
  98. *SECOND() = *THIRD();
  99. *THIRD() = tmp;
  100. DISPATCH();
  101. }
  102. case OP_PRINT_EXPR:
  103. if(TOP()->type != tp_none_type) {
  104. bool ok = py_repr(TOP());
  105. if(!ok) goto __ERROR;
  106. self->_stdout("%s\n", py_tostr(&self->last_retval));
  107. }
  108. POP();
  109. DISPATCH();
  110. /*****************************************/
  111. case OP_LOAD_CONST: PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg)); DISPATCH();
  112. case OP_LOAD_NONE: PUSH(&self->None); DISPATCH();
  113. case OP_LOAD_TRUE: PUSH(&self->True); DISPATCH();
  114. case OP_LOAD_FALSE: PUSH(&self->False); DISPATCH();
  115. /*****************************************/
  116. case OP_LOAD_SMALL_INT: py_newint(SP()++, (int64_t)(int16_t)byte.arg); DISPATCH();
  117. /*****************************************/
  118. case OP_LOAD_ELLIPSIS: PUSH(&self->Ellipsis); DISPATCH();
  119. case OP_LOAD_FUNCTION: {
  120. // FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
  121. // py_TValue obj;
  122. // if(decl->nested) {
  123. // NameDict* captured = frame->_locals.to_namedict();
  124. // obj =
  125. // new_object<Function>(tp_function, decl, frame->_module, nullptr,
  126. // captured);
  127. // uint16_t name = py_Name__map2(py_Str__sv(&decl->code->name));
  128. // captured->set(name, obj);
  129. // } else {
  130. // obj = new_object<Function>(tp_function, decl, frame->_module, nullptr,
  131. // nullptr);
  132. // }
  133. // PUSH(obj);DISPATCH();
  134. }
  135. case OP_LOAD_NULL:
  136. py_newnull(SP()++);
  137. DISPATCH();
  138. /*****************************************/
  139. case OP_LOAD_FAST: {
  140. PUSH(&frame->locals[byte.arg]);
  141. if(py_isnull(TOP())) {
  142. py_Name name = c11__getitem(uint16_t, &frame->co->varnames, byte.arg);
  143. UnboundLocalError(name);
  144. goto __ERROR;
  145. }
  146. DISPATCH();
  147. }
  148. case OP_LOAD_NAME: {
  149. py_Name name = byte.arg;
  150. py_Ref tmp = Frame__f_locals_try_get(frame, name);
  151. if(tmp != NULL) {
  152. if(py_isnull(tmp)) {
  153. UnboundLocalError(name);
  154. goto __ERROR;
  155. }
  156. PUSH(tmp);
  157. DISPATCH();
  158. }
  159. tmp = Frame__f_closure_try_get(frame, name);
  160. if(tmp != NULL) {
  161. PUSH(tmp);
  162. DISPATCH();
  163. }
  164. tmp = Frame__f_globals_try_get(frame, name);
  165. if(tmp != NULL) {
  166. PUSH(tmp);
  167. DISPATCH();
  168. }
  169. tmp = py_getdict(&self->builtins, name);
  170. if(tmp != NULL) {
  171. PUSH(tmp);
  172. DISPATCH();
  173. }
  174. NameError(name);
  175. goto __ERROR;
  176. }
  177. case OP_LOAD_NONLOCAL: {
  178. py_Name name = byte.arg;
  179. py_Ref tmp = Frame__f_closure_try_get(frame, name);
  180. if(tmp != NULL) {
  181. PUSH(tmp);
  182. DISPATCH();
  183. }
  184. tmp = Frame__f_globals_try_get(frame, name);
  185. if(tmp != NULL) {
  186. PUSH(tmp);
  187. DISPATCH();
  188. }
  189. tmp = py_getdict(&self->builtins, name);
  190. if(tmp != NULL) {
  191. PUSH(tmp);
  192. DISPATCH();
  193. }
  194. NameError(name);
  195. goto __ERROR;
  196. }
  197. case OP_LOAD_GLOBAL: {
  198. py_Name name = byte.arg;
  199. py_Ref tmp = Frame__f_globals_try_get(frame, name);
  200. if(tmp != NULL) {
  201. PUSH(tmp);
  202. DISPATCH();
  203. }
  204. tmp = py_getdict(&self->builtins, name);
  205. if(tmp != NULL) {
  206. PUSH(tmp);
  207. DISPATCH();
  208. }
  209. NameError(name);
  210. goto __ERROR;
  211. }
  212. case OP_LOAD_ATTR: {
  213. if(!py_getattr(TOP(), byte.arg, TOP())) {
  214. AttributeError(TOP(), byte.arg);
  215. goto __ERROR;
  216. }
  217. DISPATCH();
  218. }
  219. case OP_LOAD_CLASS_GLOBAL: {
  220. assert(self->__curr_class.type);
  221. py_Name name = byte.arg;
  222. if(py_getattr(&self->__curr_class, name, SP())) {
  223. SP()++;
  224. DISPATCH();
  225. }
  226. // load global if attribute not found
  227. py_Ref tmp = Frame__f_globals_try_get(frame, name);
  228. if(tmp) {
  229. PUSH(tmp);
  230. DISPATCH();
  231. }
  232. tmp = py_getdict(&self->builtins, name);
  233. if(tmp) {
  234. PUSH(tmp);
  235. DISPATCH();
  236. }
  237. NameError(name);
  238. goto __ERROR;
  239. }
  240. case OP_LOAD_METHOD: {
  241. // `py_getunboundmethod` never fails on `fallback=true`
  242. py_getunboundmethod(TOP(), byte.arg, true, TOP(), SP());
  243. SP()++;
  244. DISPATCH();
  245. }
  246. case OP_LOAD_SUBSCR: {
  247. // [a, b] -> a[b]
  248. py_Ref magic = py_tpfindmagic(SECOND()->type, __getitem__);
  249. if(magic) {
  250. if(magic->type == tp_nativefunc) {
  251. bool ok = magic->_cfunc(2, SECOND());
  252. if(!ok) goto __ERROR;
  253. POP();
  254. *TOP() = self->last_retval;
  255. } else {
  256. INSERT_THIRD(); // [?, a, b]
  257. *THIRD() = *magic; // [__getitem__, a, b]
  258. vectorcall_opcall(2);
  259. }
  260. DISPATCH();
  261. }
  262. TypeError();
  263. goto __ERROR;
  264. }
  265. case OP_STORE_FAST: frame->locals[byte.arg] = POPX(); DISPATCH();
  266. case OP_STORE_NAME: {
  267. py_Name _name = byte.arg;
  268. py_TValue _0 = POPX();
  269. if(frame->function) {
  270. py_Ref slot = Frame__f_locals_try_get(frame, _name);
  271. if(slot != NULL) {
  272. *slot = _0; // store in locals if possible
  273. } else {
  274. // Function& func = frame->_callable->as<Function>();
  275. // if(func.decl == __dynamic_func_decl) {
  276. // assert(func._closure != nullptr);
  277. // func._closure->set(_name, _0);
  278. // } else {
  279. // NameError(_name);
  280. // goto __ERROR;
  281. // }
  282. }
  283. } else {
  284. pk_NameDict__set(Frame__f_globals(frame), _name, _0);
  285. }
  286. DISPATCH();
  287. }
  288. case OP_STORE_GLOBAL:
  289. pk_NameDict__set(Frame__f_globals(frame), byte.arg, POPX());
  290. DISPATCH();
  291. case OP_STORE_ATTR: {
  292. int err = py_setattr(TOP(), byte.arg, SECOND());
  293. if(err) goto __ERROR;
  294. STACK_SHRINK(2);
  295. DISPATCH();
  296. }
  297. case OP_STORE_SUBSCR: {
  298. // [val, a, b] -> a[b] = val
  299. PUSH(THIRD()); // [val, a, b, val]
  300. py_Ref magic = py_tpfindmagic(SECOND()->type, __setitem__);
  301. if(magic) {
  302. if(magic->type == tp_nativefunc) {
  303. bool ok = magic->_cfunc(3, THIRD());
  304. if(!ok) goto __ERROR;
  305. STACK_SHRINK(3);
  306. *TOP() = self->last_retval;
  307. } else {
  308. INSERT_THIRD(); // [?, a, b]
  309. *FOURTH() = *magic; // [__selitem__, a, b, val]
  310. vectorcall_opcall(3);
  311. POP(); // discard retval
  312. }
  313. DISPATCH();
  314. }
  315. TypeError();
  316. goto __ERROR;
  317. }
  318. case OP_DELETE_FAST: {
  319. py_Ref tmp = &frame->locals[byte.arg];
  320. if(py_isnull(tmp)) {
  321. UnboundLocalError(c11__getitem(uint16_t, &frame->co->varnames, byte.arg));
  322. goto __ERROR;
  323. }
  324. py_newnull(tmp);
  325. DISPATCH();
  326. }
  327. case OP_DELETE_NAME: {
  328. py_Name name = byte.arg;
  329. if(frame->function) {
  330. py_TValue* slot = Frame__f_locals_try_get(frame, name);
  331. if(slot) {
  332. py_newnull(slot);
  333. } else {
  334. // Function& func = frame->_callable->as<Function>();
  335. // if(func.decl == __dynamic_func_decl) {
  336. // assert(func._closure != nullptr);
  337. // bool ok = func._closure->del(_name);
  338. // if(!ok) vm->NameError(_name);
  339. // } else {
  340. // vm->NameError(_name);
  341. // }
  342. }
  343. } else {
  344. // if(!frame->f_globals().del(_name)) vm->NameError(_name);
  345. bool ok = pk_NameDict__del(Frame__f_globals(frame), name);
  346. if(!ok) {
  347. NameError(name);
  348. goto __ERROR;
  349. }
  350. }
  351. DISPATCH();
  352. }
  353. case OP_DELETE_GLOBAL: {
  354. py_Name name = byte.arg;
  355. bool ok = pk_NameDict__del(Frame__f_globals(frame), name);
  356. if(!ok) {
  357. NameError(name);
  358. goto __ERROR;
  359. }
  360. DISPATCH();
  361. }
  362. case OP_DELETE_ATTR: {
  363. if(!py_delattr(TOP(), byte.arg)) goto __ERROR;
  364. DISPATCH();
  365. }
  366. case OP_DELETE_SUBSCR: {
  367. // [a, b] -> del a[b]
  368. py_Ref magic = py_tpfindmagic(SECOND()->type, __delitem__);
  369. if(magic) {
  370. if(magic->type == tp_nativefunc) {
  371. bool ok = magic->_cfunc(2, SECOND());
  372. if(!ok) goto __ERROR;
  373. POP();
  374. *TOP() = self->last_retval;
  375. } else {
  376. INSERT_THIRD(); // [?, a, b]
  377. *THIRD() = *magic; // [__delitem__, a, b]
  378. vectorcall_opcall(2);
  379. POP(); // discard retval
  380. }
  381. DISPATCH();
  382. }
  383. TypeError();
  384. goto __ERROR;
  385. }
  386. /*****************************************/
  387. case OP_BUILD_LONG: {
  388. // [x]
  389. py_Ref f = py_getdict(&self->builtins, py_name("long"));
  390. assert(f != NULL);
  391. if(!py_call(f, 1, TOP())) goto __ERROR;
  392. *TOP() = self->last_retval;
  393. DISPATCH();
  394. }
  395. case OP_BUILD_IMAG: {
  396. // [x]
  397. py_Ref f = py_getdict(&self->builtins, py_name("complex"));
  398. assert(f != NULL);
  399. py_TValue tmp = *TOP();
  400. *TOP() = *f; // [complex]
  401. py_newnull(SP()++); // [complex, NULL]
  402. py_newint(SP()++, 0); // [complex, NULL, 0]
  403. *SP()++ = tmp; // [complex, NULL, 0, x]
  404. vectorcall_opcall(2); // [complex(x)]
  405. DISPATCH();
  406. }
  407. case OP_BUILD_BYTES: {
  408. int size;
  409. const char* data = py_tostrn(TOP(), &size);
  410. unsigned char* p = py_newbytes(TOP(), size);
  411. memcpy(p, data, size);
  412. DISPATCH();
  413. }
  414. case OP_BUILD_TUPLE: {
  415. py_TValue tmp;
  416. py_newtuple(&tmp, byte.arg);
  417. py_TValue* begin = SP() - byte.arg;
  418. for(int i = 0; i < byte.arg; i++) {
  419. py_tuple__setitem(&tmp, i, begin + i);
  420. }
  421. SP() = begin;
  422. PUSH(&tmp);
  423. DISPATCH();
  424. }
  425. case OP_BUILD_LIST: {
  426. py_TValue tmp;
  427. py_newlistn(&tmp, byte.arg);
  428. py_TValue* begin = SP() - byte.arg;
  429. for(int i = 0; i < byte.arg; i++) {
  430. py_list__setitem(&tmp, i, begin + i);
  431. }
  432. SP() = begin;
  433. PUSH(&tmp);
  434. DISPATCH();
  435. }
  436. case OP_BUILD_DICT: {
  437. py_TValue* begin = SP() - byte.arg;
  438. py_Ref tmp = py_pushtmp();
  439. py_newdict(tmp);
  440. for(int i = 0; i < byte.arg; i += 2) {
  441. if(!py_setitem(tmp, begin + i, begin + i + 1)) goto __ERROR;
  442. }
  443. SP() = begin;
  444. PUSH(tmp);
  445. DISPATCH();
  446. }
  447. case OP_BUILD_SET: {
  448. py_TValue* begin = SP() - byte.arg;
  449. py_Ref tmp = py_pushtmp();
  450. py_newset(tmp);
  451. py_Name id_add = py_name("add");
  452. for(int i = 0; i < byte.arg; i++) {
  453. if(!py_callmethod(tmp, id_add, 1, begin + i)) goto __ERROR;
  454. }
  455. SP() = begin;
  456. PUSH(tmp);
  457. DISPATCH();
  458. }
  459. case OP_BUILD_SLICE: {
  460. // [start, stop, step]
  461. py_TValue tmp;
  462. py_newslice(&tmp, THIRD(), SECOND(), TOP());
  463. STACK_SHRINK(3);
  464. PUSH(&tmp);
  465. DISPATCH();
  466. }
  467. case OP_BUILD_STRING: {
  468. py_TValue* begin = SP() - byte.arg;
  469. c11_sbuf ss;
  470. c11_sbuf__ctor(&ss);
  471. for(int i = 0; i < byte.arg; i++) {
  472. if(!py_str(begin + i)) goto __ERROR;
  473. int size;
  474. const char* data = py_tostrn(&self->last_retval, &size);
  475. c11_sbuf__write_cstrn(&ss, data, size);
  476. }
  477. SP() = begin;
  478. c11_string* res = c11_sbuf__submit(&ss);
  479. py_newstrn(SP()++, res->data, res->size);
  480. c11_string__delete(res);
  481. DISPATCH();
  482. }
  483. /*****************************/
  484. case OP_BINARY_OP: {
  485. py_Name op = byte.arg & 0xFF;
  486. py_Name rop = byte.arg >> 8;
  487. if(!stack_binaryop(self, op, rop)) goto __ERROR;
  488. POP();
  489. *TOP() = self->last_retval;
  490. DISPATCH();
  491. }
  492. case OP_IS_OP: {
  493. bool res = py_isidentical(SECOND(), TOP());
  494. POP();
  495. if(byte.arg) res = !res;
  496. *TOP() = res ? self->True : self->False;
  497. DISPATCH();
  498. }
  499. case OP_CONTAINS_OP: {
  500. // [b, a] -> b __contains__ a (a in b)
  501. py_Ref magic = py_tpfindmagic(SECOND()->type, __contains__);
  502. if(magic) {
  503. if(magic->type == tp_nativefunc) {
  504. bool ok = magic->_cfunc(2, SECOND());
  505. if(!ok) goto __ERROR;
  506. POP();
  507. *TOP() = self->last_retval;
  508. } else {
  509. INSERT_THIRD(); // [?, b, a]
  510. *THIRD() = *magic; // [__contains__, a, b]
  511. vectorcall_opcall(2);
  512. }
  513. bool res = py_tobool(TOP());
  514. if(byte.arg) py_newbool(TOP(), !res);
  515. DISPATCH();
  516. }
  517. TypeError();
  518. goto __ERROR;
  519. }
  520. /*****************************************/
  521. case OP_JUMP_FORWARD: DISPATCH_JUMP((int16_t)byte.arg);
  522. case OP_POP_JUMP_IF_FALSE: {
  523. int res = py_bool(TOP());
  524. if(res < 0) goto __ERROR;
  525. POP();
  526. if(!res) DISPATCH_JUMP((int16_t)byte.arg);
  527. DISPATCH();
  528. }
  529. case OP_POP_JUMP_IF_TRUE: {
  530. int res = py_bool(TOP());
  531. if(res < 0) goto __ERROR;
  532. POP();
  533. if(res) DISPATCH_JUMP((int16_t)byte.arg);
  534. DISPATCH();
  535. }
  536. case OP_JUMP_IF_TRUE_OR_POP: {
  537. int res = py_bool(TOP());
  538. if(res < 0) goto __ERROR;
  539. if(res) {
  540. DISPATCH_JUMP((int16_t)byte.arg);
  541. } else {
  542. POP();
  543. DISPATCH();
  544. }
  545. }
  546. case OP_JUMP_IF_FALSE_OR_POP: {
  547. int res = py_bool(TOP());
  548. if(res < 0) goto __ERROR;
  549. if(!res) {
  550. DISPATCH_JUMP((int16_t)byte.arg);
  551. } else {
  552. POP();
  553. DISPATCH();
  554. }
  555. }
  556. case OP_SHORTCUT_IF_FALSE_OR_POP: {
  557. int res = py_bool(TOP());
  558. if(res < 0) goto __ERROR;
  559. if(!res) { // [b, False]
  560. STACK_SHRINK(2); // []
  561. PUSH(&self->False); // [False]
  562. DISPATCH_JUMP((int16_t)byte.arg);
  563. } else {
  564. POP(); // [b]
  565. DISPATCH();
  566. }
  567. }
  568. case OP_LOOP_CONTINUE:
  569. // just an alias of OP_JUMP_FORWARD
  570. DISPATCH_JUMP((int16_t)byte.arg);
  571. case OP_LOOP_BREAK: {
  572. int target = Frame__ip(frame) + byte.arg;
  573. Frame__prepare_jump_break(frame, &self->stack, target);
  574. DISPATCH_JUMP((int16_t)byte.arg);
  575. }
  576. case OP_JUMP_ABSOLUTE_TOP: {
  577. int target = py_toint(TOP());
  578. POP();
  579. DISPATCH_JUMP_ABSOLUTE(target);
  580. }
  581. // case OP_GOTO: {
  582. // py_Name _name(byte.arg);
  583. // int target = c11_smallmap_n2i__get(&frame->co->labels, byte.arg, -1);
  584. // if(target < 0) RuntimeError(_S("label ", _name.escape(), " not found"));
  585. // frame->prepare_jump_break(&s_data, target);
  586. // DISPATCH_JUMP_ABSOLUTE(target)
  587. // }
  588. /*****************************************/
  589. case OP_RETURN_VALUE: {
  590. self->last_retval = byte.arg == BC_NOARG ? POPX() : self->None;
  591. pk_VM__pop_frame(self);
  592. if(frame == base_frame) { // [ frameBase<- ]
  593. return RES_RETURN;
  594. } else {
  595. frame = self->top_frame;
  596. PUSH(&self->last_retval);
  597. goto __NEXT_FRAME;
  598. }
  599. DISPATCH();
  600. }
  601. default: PK_UNREACHABLE();
  602. }
  603. assert(false); // should never reach here
  604. __ERROR:
  605. // 1. Exception can be handled inside the current frame
  606. // 2. Exception need to be propagated to the upper frame
  607. assert(false);
  608. return RES_ERROR;
  609. }
  610. return RES_RETURN;
  611. }
  612. /// Assumes [a, b] are on the stack, performs a binary op.
  613. /// The result is stored in `self->last_retval`.
  614. /// The stack remains unchanged.
  615. static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop) {
  616. // [a, b]
  617. py_Ref magic = py_tpfindmagic(SECOND()->type, op);
  618. if(magic) {
  619. if(magic->type == tp_nativefunc) {
  620. bool ok = magic->_cfunc(2, SECOND());
  621. if(!ok) return false;
  622. if(self->last_retval.type != tp_not_implemented_type) return true;
  623. } else {
  624. // standard call
  625. bool ok = py_call(magic, 2, SECOND());
  626. if(!ok) return false;
  627. if(self->last_retval.type != tp_not_implemented_type) return true;
  628. }
  629. }
  630. // try reverse operation
  631. if(rop) {
  632. // [a, b] -> [b, a]
  633. py_TValue tmp = *TOP();
  634. *TOP() = *SECOND();
  635. *SECOND() = tmp;
  636. magic = py_tpfindmagic(SECOND()->type, rop);
  637. if(magic) {
  638. if(magic->type == tp_nativefunc) {
  639. bool ok = magic->_cfunc(2, SECOND());
  640. if(!ok) return false;
  641. if(self->last_retval.type != tp_not_implemented_type) return true;
  642. } else {
  643. // standard call
  644. bool ok = py_call(magic, 2, SECOND());
  645. if(!ok) return false;
  646. if(self->last_retval.type != tp_not_implemented_type) return true;
  647. }
  648. }
  649. }
  650. // eq/ne op never fails due to object.__eq__
  651. return BinaryOptError(byte.arg);
  652. }
  653. bool py_binaryop(const py_Ref lhs, const py_Ref rhs, py_Name op, py_Name rop) {
  654. pk_VM* self = pk_current_vm;
  655. PUSH(lhs);
  656. PUSH(rhs);
  657. return stack_binaryop(self, op, rop);
  658. }