ceval.h 18 KB

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