ceval.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. #pragma once
  2. #include "common.h"
  3. #include "namedict.h"
  4. #include "vm.h"
  5. namespace pkpy{
  6. inline PyObject* VM::_run_top_frame(){
  7. FrameId frame = top_frame();
  8. const int base_id = frame.index;
  9. bool need_raise = false;
  10. // shared registers
  11. PyObject *_0, *_1, *_2;
  12. StrName _name;
  13. while(true){
  14. #if DEBUG_EXTRA_CHECK
  15. if(frame.index < base_id) FATAL_ERROR();
  16. #endif
  17. try{
  18. if(need_raise){ need_raise = false; _raise(); }
  19. /**********************************************************************/
  20. /* NOTE:
  21. * Be aware of accidental gc!
  22. * DO NOT leave any strong reference of PyObject* in the C stack
  23. */
  24. {
  25. #define DISPATCH_OP_CALL() { frame = top_frame(); goto __NEXT_FRAME; }
  26. __NEXT_FRAME:
  27. Bytecode byte = frame->next_bytecode();
  28. // cache
  29. const CodeObject* co = frame->co;
  30. const auto& co_consts = co->consts;
  31. const auto& co_blocks = co->blocks;
  32. #if PK_ENABLE_COMPUTED_GOTO
  33. static void* OP_LABELS[] = {
  34. #define OPCODE(name) &&CASE_OP_##name,
  35. #include "opcodes.h"
  36. #undef OPCODE
  37. };
  38. #define DISPATCH() { byte = frame->next_bytecode(); goto *OP_LABELS[byte.op];}
  39. #define TARGET(op) CASE_OP_##op:
  40. goto *OP_LABELS[byte.op];
  41. #else
  42. #define TARGET(op) case OP_##op:
  43. #define DISPATCH() { byte = frame->next_bytecode(); goto __NEXT_STEP;}
  44. __NEXT_STEP:;
  45. #if DEBUG_CEVAL_STEP
  46. _log_s_data();
  47. #endif
  48. #if DEBUG_CEVAL_STEP_MIN
  49. std::cout << OP_NAMES[byte.op] << std::endl;
  50. #endif
  51. switch (byte.op)
  52. {
  53. #endif
  54. TARGET(NO_OP) DISPATCH();
  55. /*****************************************/
  56. TARGET(POP_TOP) POP(); DISPATCH();
  57. TARGET(DUP_TOP) PUSH(TOP()); DISPATCH();
  58. TARGET(ROT_TWO) std::swap(TOP(), SECOND()); DISPATCH();
  59. TARGET(PRINT_EXPR)
  60. if(TOP() != None){
  61. _stdout(this, CAST(Str&, asRepr(TOP())));
  62. _stdout(this, "\n");
  63. }
  64. POP();
  65. DISPATCH();
  66. /*****************************************/
  67. TARGET(LOAD_CONST)
  68. heap._auto_collect();
  69. PUSH(co_consts[byte.arg]);
  70. DISPATCH();
  71. TARGET(LOAD_NONE) PUSH(None); DISPATCH();
  72. TARGET(LOAD_TRUE) PUSH(True); DISPATCH();
  73. TARGET(LOAD_FALSE) PUSH(False); DISPATCH();
  74. TARGET(LOAD_INTEGER) PUSH(VAR(byte.arg)); DISPATCH();
  75. TARGET(LOAD_ELLIPSIS) PUSH(Ellipsis); DISPATCH();
  76. TARGET(LOAD_FUNCTION) {
  77. FuncDecl_ decl = co->func_decls[byte.arg];
  78. bool is_simple = decl->starred_arg==-1 && decl->kwargs.size()==0 && !decl->code->is_generator;
  79. int argc = decl->args.size();
  80. PyObject* obj;
  81. if(decl->nested){
  82. obj = VAR(Function({decl, is_simple, argc, frame->_module, frame->_locals.to_namedict()}));
  83. }else{
  84. obj = VAR(Function({decl, is_simple, argc, frame->_module}));
  85. }
  86. PUSH(obj);
  87. } DISPATCH();
  88. TARGET(LOAD_NULL) PUSH(PY_NULL); DISPATCH();
  89. /*****************************************/
  90. TARGET(LOAD_FAST) {
  91. heap._auto_collect();
  92. _0 = frame->_locals[byte.arg];
  93. if(_0 == nullptr) vm->NameError(co->varnames[byte.arg]);
  94. PUSH(_0);
  95. } DISPATCH();
  96. TARGET(LOAD_NAME)
  97. heap._auto_collect();
  98. _name = StrName(byte.arg);
  99. _0 = frame->_locals.try_get(_name);
  100. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  101. _0 = frame->f_closure_try_get(_name);
  102. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  103. _0 = frame->f_globals().try_get(_name);
  104. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  105. _0 = vm->builtins->attr().try_get(_name);
  106. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  107. vm->NameError(_name);
  108. DISPATCH();
  109. TARGET(LOAD_NONLOCAL) {
  110. heap._auto_collect();
  111. _name = StrName(byte.arg);
  112. _0 = frame->f_closure_try_get(_name);
  113. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  114. _0 = frame->f_globals().try_get(_name);
  115. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  116. _0 = vm->builtins->attr().try_get(_name);
  117. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  118. vm->NameError(_name);
  119. DISPATCH();
  120. } DISPATCH();
  121. TARGET(LOAD_GLOBAL)
  122. heap._auto_collect();
  123. _name = StrName(byte.arg);
  124. _0 = frame->f_globals().try_get(_name);
  125. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  126. _0 = vm->builtins->attr().try_get(_name);
  127. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  128. vm->NameError(_name);
  129. DISPATCH();
  130. TARGET(LOAD_ATTR)
  131. TOP() = getattr(TOP(), StrName(byte.arg));
  132. DISPATCH();
  133. TARGET(LOAD_METHOD)
  134. TOP() = get_unbound_method(TOP(), StrName(byte.arg), &_0, true, true);
  135. PUSH(_0);
  136. DISPATCH();
  137. TARGET(LOAD_SUBSCR)
  138. _1 = POPX(); // b
  139. _0 = TOP(); // a
  140. TOP() = call_method(_0, __getitem__, _1);
  141. DISPATCH();
  142. TARGET(STORE_FAST)
  143. frame->_locals[byte.arg] = POPX();
  144. DISPATCH();
  145. TARGET(STORE_NAME)
  146. _name = StrName(byte.arg);
  147. _0 = POPX();
  148. if(frame->_callable != nullptr){
  149. bool ok = frame->_locals.try_set(_name, _0);
  150. if(!ok) vm->NameError(_name);
  151. }else{
  152. frame->f_globals().set(_name, _0);
  153. }
  154. DISPATCH();
  155. TARGET(STORE_GLOBAL)
  156. frame->f_globals().set(StrName(byte.arg), POPX());
  157. DISPATCH();
  158. TARGET(STORE_ATTR) {
  159. _0 = TOP(); // a
  160. _1 = SECOND(); // val
  161. setattr(_0, StrName(byte.arg), _1);
  162. STACK_SHRINK(2);
  163. } DISPATCH();
  164. TARGET(STORE_SUBSCR)
  165. _2 = POPX(); // b
  166. _1 = POPX(); // a
  167. _0 = POPX(); // val
  168. call_method(_1, __setitem__, _2, _0);
  169. DISPATCH();
  170. TARGET(DELETE_FAST)
  171. _0 = frame->_locals[byte.arg];
  172. if(_0 == nullptr) vm->NameError(co->varnames[byte.arg]);
  173. frame->_locals[byte.arg] = nullptr;
  174. DISPATCH();
  175. TARGET(DELETE_NAME)
  176. _name = StrName(byte.arg);
  177. if(frame->_callable != nullptr){
  178. if(!frame->_locals.contains(_name)) vm->NameError(_name);
  179. frame->_locals.erase(_name);
  180. }else{
  181. if(!frame->f_globals().contains(_name)) vm->NameError(_name);
  182. frame->f_globals().erase(_name);
  183. }
  184. DISPATCH();
  185. TARGET(DELETE_GLOBAL)
  186. _name = StrName(byte.arg);
  187. if(frame->f_globals().contains(_name)){
  188. frame->f_globals().erase(_name);
  189. }else{
  190. NameError(_name);
  191. }
  192. DISPATCH();
  193. TARGET(DELETE_ATTR)
  194. _0 = POPX();
  195. _name = StrName(byte.arg);
  196. if(is_tagged(_0) || !_0->is_attr_valid()) TypeError("cannot delete attribute");
  197. if(!_0->attr().contains(_name)) AttributeError(_0, _name);
  198. _0->attr().erase(_name);
  199. DISPATCH();
  200. TARGET(DELETE_SUBSCR)
  201. _1 = POPX();
  202. _0 = POPX();
  203. call_method(_0, __delitem__, _1);
  204. DISPATCH();
  205. /*****************************************/
  206. TARGET(BUILD_LIST)
  207. _0 = VAR(STACK_VIEW(byte.arg).to_list());
  208. STACK_SHRINK(byte.arg);
  209. PUSH(_0);
  210. DISPATCH();
  211. TARGET(BUILD_DICT)
  212. _0 = VAR(STACK_VIEW(byte.arg).to_tuple());
  213. _0 = call(builtins->attr(m_dict), _0);
  214. STACK_SHRINK(byte.arg);
  215. PUSH(_0);
  216. DISPATCH();
  217. TARGET(BUILD_SET)
  218. _0 = VAR(STACK_VIEW(byte.arg).to_tuple());
  219. _0 = call(builtins->attr(m_set), _0);
  220. STACK_SHRINK(byte.arg);
  221. PUSH(_0);
  222. DISPATCH();
  223. TARGET(BUILD_SLICE)
  224. _2 = POPX(); // step
  225. _1 = POPX(); // stop
  226. _0 = POPX(); // start
  227. PUSH(VAR(Slice(_0, _1, _2)));
  228. DISPATCH();
  229. TARGET(BUILD_TUPLE)
  230. _0 = VAR(STACK_VIEW(byte.arg).to_tuple());
  231. STACK_SHRINK(byte.arg);
  232. PUSH(_0);
  233. DISPATCH();
  234. TARGET(BUILD_STRING) {
  235. std::stringstream ss;
  236. ArgsView view = STACK_VIEW(byte.arg);
  237. for(PyObject* obj : view) ss << CAST(Str&, asStr(obj));
  238. STACK_SHRINK(byte.arg);
  239. PUSH(VAR(ss.str()));
  240. } DISPATCH();
  241. /*****************************************/
  242. TARGET(BINARY_TRUEDIV)
  243. _1 = POPX();
  244. _0 = TOP();
  245. if(is_float(_0)){
  246. TOP() = VAR(_CAST(f64, _0) / num_to_float(_1));
  247. }else{
  248. TOP() = call_method(_0, __truediv__, _1);
  249. }
  250. DISPATCH();
  251. TARGET(BINARY_POW)
  252. _1 = POPX();
  253. _0 = TOP();
  254. TOP() = call_method(_0, __pow__, _1);
  255. DISPATCH();
  256. #define INT_BINARY_OP(op, func) \
  257. if(is_both_int(TOP(), SECOND())){ \
  258. i64 b = _CAST(i64, TOP()); \
  259. i64 a = _CAST(i64, SECOND()); \
  260. POP(); \
  261. TOP() = VAR(a op b); \
  262. }else{ \
  263. _1 = POPX(); \
  264. _0 = TOP(); \
  265. TOP() = call_method(_0, func, _1); \
  266. }
  267. TARGET(BINARY_ADD)
  268. INT_BINARY_OP(+, __add__)
  269. DISPATCH()
  270. TARGET(BINARY_SUB)
  271. INT_BINARY_OP(-, __sub__)
  272. DISPATCH()
  273. TARGET(BINARY_MUL)
  274. INT_BINARY_OP(*, __mul__)
  275. DISPATCH()
  276. TARGET(BINARY_FLOORDIV)
  277. INT_BINARY_OP(/, __floordiv__)
  278. DISPATCH()
  279. TARGET(BINARY_MOD)
  280. INT_BINARY_OP(%, __mod__)
  281. DISPATCH()
  282. TARGET(COMPARE_LT)
  283. INT_BINARY_OP(<, __lt__)
  284. DISPATCH()
  285. TARGET(COMPARE_LE)
  286. INT_BINARY_OP(<=, __le__)
  287. DISPATCH()
  288. TARGET(COMPARE_EQ)
  289. INT_BINARY_OP(==, __eq__)
  290. DISPATCH()
  291. TARGET(COMPARE_NE)
  292. INT_BINARY_OP(!=, __ne__)
  293. DISPATCH()
  294. TARGET(COMPARE_GT)
  295. INT_BINARY_OP(>, __gt__)
  296. DISPATCH()
  297. TARGET(COMPARE_GE)
  298. INT_BINARY_OP(>=, __ge__)
  299. DISPATCH()
  300. TARGET(BITWISE_LSHIFT)
  301. INT_BINARY_OP(<<, __lshift__)
  302. DISPATCH()
  303. TARGET(BITWISE_RSHIFT)
  304. INT_BINARY_OP(>>, __rshift__)
  305. DISPATCH()
  306. TARGET(BITWISE_AND)
  307. INT_BINARY_OP(&, __and__)
  308. DISPATCH()
  309. TARGET(BITWISE_OR)
  310. INT_BINARY_OP(|, __or__)
  311. DISPATCH()
  312. TARGET(BITWISE_XOR)
  313. INT_BINARY_OP(^, __xor__)
  314. DISPATCH()
  315. #undef INT_BINARY_OP
  316. TARGET(BINARY_MATMUL)
  317. _1 = POPX();
  318. _0 = TOP();
  319. TOP() = call_method(_0, __matmul__, _1);
  320. DISPATCH();
  321. TARGET(IS_OP)
  322. _1 = POPX(); // rhs
  323. _0 = TOP(); // lhs
  324. if(byte.arg == 1){
  325. TOP() = VAR(_0 != _1);
  326. }else{
  327. TOP() = VAR(_0 == _1);
  328. }
  329. DISPATCH();
  330. TARGET(CONTAINS_OP)
  331. // a in b -> b __contains__ a
  332. _0 = call_method(TOP(), __contains__, SECOND());
  333. POP();
  334. if(byte.arg == 1){
  335. TOP() = VAR(!CAST(bool, _0));
  336. }else{
  337. TOP() = VAR(CAST(bool, _0));
  338. }
  339. DISPATCH();
  340. /*****************************************/
  341. TARGET(JUMP_ABSOLUTE)
  342. frame->jump_abs(byte.arg);
  343. DISPATCH();
  344. TARGET(POP_JUMP_IF_FALSE)
  345. if(!asBool(POPX())) frame->jump_abs(byte.arg);
  346. DISPATCH();
  347. TARGET(JUMP_IF_TRUE_OR_POP)
  348. if(asBool(TOP()) == true) frame->jump_abs(byte.arg);
  349. else POP();
  350. DISPATCH();
  351. TARGET(JUMP_IF_FALSE_OR_POP)
  352. if(asBool(TOP()) == false) frame->jump_abs(byte.arg);
  353. else POP();
  354. DISPATCH();
  355. TARGET(LOOP_CONTINUE)
  356. frame->jump_abs(co_blocks[byte.block].start);
  357. DISPATCH();
  358. TARGET(LOOP_BREAK)
  359. frame->jump_abs_break(co_blocks[byte.block].end);
  360. DISPATCH();
  361. TARGET(GOTO) {
  362. _name = StrName(byte.arg);
  363. int index = co->labels.try_get(_name);
  364. if(index < 0) _error("KeyError", fmt("label ", _name.escape(), " not found"));
  365. frame->jump_abs_break(index);
  366. } DISPATCH();
  367. /*****************************************/
  368. TARGET(BEGIN_CALL)
  369. PUSH(PY_BEGIN_CALL);
  370. DISPATCH();
  371. TARGET(CALL)
  372. _0 = vectorcall(
  373. byte.arg & 0xFFFF, // ARGC
  374. (byte.arg>>16) & 0xFFFF, // KWARGC
  375. true
  376. );
  377. if(_0 == PY_OP_CALL) DISPATCH_OP_CALL();
  378. PUSH(_0);
  379. DISPATCH();
  380. TARGET(RETURN_VALUE)
  381. _0 = POPX();
  382. _pop_frame();
  383. if(frame.index == base_id){ // [ frameBase<- ]
  384. return _0;
  385. }else{
  386. frame = top_frame();
  387. PUSH(_0);
  388. goto __NEXT_FRAME;
  389. }
  390. TARGET(YIELD_VALUE)
  391. return PY_OP_YIELD;
  392. /*****************************************/
  393. TARGET(LIST_APPEND)
  394. _0 = POPX();
  395. CAST(List&, SECOND()).push_back(_0);
  396. DISPATCH();
  397. TARGET(DICT_ADD) {
  398. _0 = POPX();
  399. Tuple& t = CAST(Tuple&, _0);
  400. call_method(SECOND(), __setitem__, t[0], t[1]);
  401. } DISPATCH();
  402. TARGET(SET_ADD)
  403. _0 = POPX();
  404. call_method(SECOND(), m_add, _0);
  405. DISPATCH();
  406. /*****************************************/
  407. TARGET(UNARY_NEGATIVE)
  408. TOP() = num_negated(TOP());
  409. DISPATCH();
  410. TARGET(UNARY_NOT)
  411. TOP() = VAR(!asBool(TOP()));
  412. DISPATCH();
  413. /*****************************************/
  414. TARGET(GET_ITER)
  415. TOP() = asIter(TOP());
  416. DISPATCH();
  417. TARGET(FOR_ITER)
  418. _0 = PyIterNext(TOP());
  419. if(_0 != StopIteration){
  420. PUSH(_0);
  421. }else{
  422. frame->jump_abs_break(co_blocks[byte.block].end);
  423. }
  424. DISPATCH();
  425. /*****************************************/
  426. TARGET(IMPORT_NAME) {
  427. StrName name(byte.arg);
  428. PyObject* ext_mod = _modules.try_get(name);
  429. if(ext_mod == nullptr){
  430. Str source;
  431. auto it = _lazy_modules.find(name);
  432. if(it == _lazy_modules.end()){
  433. Bytes b = _read_file_cwd(fmt(name, ".py"));
  434. if(!b) _error("ImportError", fmt("module ", name.escape(), " not found"));
  435. source = Str(b.str());
  436. }else{
  437. source = it->second;
  438. _lazy_modules.erase(it);
  439. }
  440. CodeObject_ code = compile(source, Str(name.sv())+".py", EXEC_MODE);
  441. PyObject* new_mod = new_module(name);
  442. _exec(code, new_mod);
  443. new_mod->attr()._try_perfect_rehash();
  444. PUSH(new_mod);
  445. }else{
  446. PUSH(ext_mod);
  447. }
  448. } DISPATCH();
  449. TARGET(IMPORT_STAR)
  450. _0 = POPX();
  451. for(auto& [name, value]: _0->attr().items()){
  452. std::string_view s = name.sv();
  453. if(s.empty() || s[0] == '_') continue;
  454. frame->f_globals().set(name, value);
  455. }
  456. DISPATCH();
  457. /*****************************************/
  458. TARGET(UNPACK_SEQUENCE)
  459. TARGET(UNPACK_EX) {
  460. auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
  461. _0 = asIter(POPX());
  462. for(int i=0; i<byte.arg; i++){
  463. _1 = PyIterNext(_0);
  464. if(_1 == StopIteration) ValueError("not enough values to unpack");
  465. PUSH(_1);
  466. }
  467. // handle extra items
  468. if(byte.op == OP_UNPACK_EX){
  469. List extras;
  470. while(true){
  471. _1 = PyIterNext(_0);
  472. if(_1 == StopIteration) break;
  473. extras.push_back(_1);
  474. }
  475. PUSH(VAR(extras));
  476. }else{
  477. if(PyIterNext(_0) != StopIteration) ValueError("too many values to unpack");
  478. }
  479. } DISPATCH();
  480. TARGET(UNPACK_UNLIMITED) {
  481. auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
  482. _0 = asIter(POPX());
  483. _1 = PyIterNext(_0);
  484. while(_1 != StopIteration){
  485. PUSH(_1);
  486. _1 = PyIterNext(_0);
  487. }
  488. } DISPATCH();
  489. /*****************************************/
  490. TARGET(BEGIN_CLASS)
  491. _name = StrName(byte.arg);
  492. _0 = POPX(); // super
  493. if(_0 == None) _0 = _t(tp_object);
  494. check_non_tagged_type(_0, tp_type);
  495. _1 = new_type_object(frame->_module, _name, OBJ_GET(Type, _0));
  496. PUSH(_1);
  497. DISPATCH();
  498. TARGET(END_CLASS)
  499. _0 = POPX();
  500. _0->attr()._try_perfect_rehash();
  501. DISPATCH();
  502. TARGET(STORE_CLASS_ATTR)
  503. _name = StrName(byte.arg);
  504. _0 = POPX();
  505. TOP()->attr().set(_name, _0);
  506. DISPATCH();
  507. /*****************************************/
  508. // TODO: using "goto" inside with block may cause __exit__ not called
  509. TARGET(WITH_ENTER)
  510. call_method(POPX(), __enter__);
  511. DISPATCH();
  512. TARGET(WITH_EXIT)
  513. call_method(POPX(), __exit__);
  514. DISPATCH();
  515. /*****************************************/
  516. TARGET(ASSERT) {
  517. _0 = TOP();
  518. Str msg;
  519. if(is_type(_0, tp_tuple)){
  520. auto& t = CAST(Tuple&, _0);
  521. if(t.size() != 2) ValueError("assert tuple must have 2 elements");
  522. _0 = t[0];
  523. msg = CAST(Str&, asStr(t[1]));
  524. }
  525. bool ok = asBool(_0);
  526. POP();
  527. if(!ok) _error("AssertionError", msg);
  528. } DISPATCH();
  529. TARGET(EXCEPTION_MATCH) {
  530. const auto& e = CAST(Exception&, TOP());
  531. _name = StrName(byte.arg);
  532. PUSH(VAR(e.match_type(_name)));
  533. } DISPATCH();
  534. TARGET(RAISE) {
  535. _0 = POPX();
  536. Str msg = _0 == None ? "" : CAST(Str, asStr(_0));
  537. _error(StrName(byte.arg), msg);
  538. } DISPATCH();
  539. TARGET(RE_RAISE) _raise(); DISPATCH();
  540. /*****************************************/
  541. TARGET(SETUP_DOCSTRING)
  542. TOP()->attr().set(__doc__, co_consts[byte.arg]);
  543. DISPATCH();
  544. TARGET(FORMAT_STRING) {
  545. _0 = POPX();
  546. const Str& spec = CAST(Str&, co_consts[byte.arg]);
  547. PUSH(format(spec, _0));
  548. } DISPATCH();
  549. #if !PK_ENABLE_COMPUTED_GOTO
  550. #if DEBUG_EXTRA_CHECK
  551. default: throw std::runtime_error(fmt(OP_NAMES[byte.op], " is not implemented"));
  552. #else
  553. default: UNREACHABLE();
  554. #endif
  555. }
  556. #endif
  557. }
  558. #undef DISPATCH
  559. #undef TARGET
  560. #undef DISPATCH_OP_CALL
  561. /**********************************************************************/
  562. UNREACHABLE();
  563. }catch(HandledException& e){
  564. continue;
  565. }catch(UnhandledException& e){
  566. PyObject* obj = POPX();
  567. Exception& _e = CAST(Exception&, obj);
  568. _e.st_push(frame->snapshot());
  569. _pop_frame();
  570. if(callstack.empty()){
  571. #if DEBUG_FULL_EXCEPTION
  572. std::cerr << _e.summary() << std::endl;
  573. #endif
  574. throw _e;
  575. }
  576. frame = top_frame();
  577. PUSH(obj);
  578. if(frame.index < base_id) throw ToBeRaisedException();
  579. need_raise = true;
  580. }catch(ToBeRaisedException& e){
  581. need_raise = true;
  582. }
  583. }
  584. }
  585. #undef TOP
  586. #undef SECOND
  587. #undef THIRD
  588. #undef PEEK
  589. #undef STACK_SHRINK
  590. #undef PUSH
  591. #undef POP
  592. #undef POPX
  593. #undef STACK_VIEW
  594. } // namespace pkpy