ceval.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  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_FUNCTION) {
  75. FuncDecl_ decl = co->func_decls[byte.arg];
  76. bool is_simple = decl->starred_arg==-1 && decl->kwargs.size()==0 && !decl->code->is_generator;
  77. PyObject* obj;
  78. if(decl->nested){
  79. obj = VAR(Function({decl, is_simple, frame->_module, frame->_locals.to_namedict()}));
  80. }else{
  81. obj = VAR(Function({decl, is_simple, 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->f_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->f_closure_try_get(_name);
  110. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  111. _0 = frame->f_globals().try_get(_name);
  112. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  113. _0 = vm->builtins->attr().try_get(_name);
  114. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  115. vm->NameError(_name);
  116. DISPATCH();
  117. } DISPATCH();
  118. TARGET(LOAD_GLOBAL)
  119. heap._auto_collect();
  120. _name = StrName(byte.arg);
  121. _0 = frame->f_globals().try_get(_name);
  122. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  123. _0 = vm->builtins->attr().try_get(_name);
  124. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  125. vm->NameError(_name);
  126. DISPATCH();
  127. TARGET(LOAD_ATTR)
  128. TOP() = getattr(TOP(), StrName(byte.arg));
  129. DISPATCH();
  130. TARGET(LOAD_METHOD)
  131. TOP() = get_unbound_method(TOP(), StrName(byte.arg), &_0, true, true);
  132. PUSH(_0);
  133. DISPATCH();
  134. TARGET(LOAD_SUBSCR)
  135. _1 = POPX();
  136. _0 = TOP();
  137. TOP() = call_method(_0, __getitem__, _1);
  138. DISPATCH();
  139. TARGET(STORE_FAST)
  140. frame->_locals[byte.arg] = POPX();
  141. DISPATCH();
  142. TARGET(STORE_NAME)
  143. _name = StrName(byte.arg);
  144. _0 = POPX();
  145. if(frame->_callable != nullptr){
  146. bool ok = frame->_locals.try_set(_name, _0);
  147. if(!ok) vm->NameError(_name);
  148. }else{
  149. frame->f_globals().set(_name, _0);
  150. }
  151. DISPATCH();
  152. TARGET(STORE_GLOBAL)
  153. frame->f_globals().set(StrName(byte.arg), POPX());
  154. DISPATCH();
  155. TARGET(STORE_ATTR) {
  156. _0 = TOP(); // a
  157. _1 = SECOND(); // val
  158. setattr(_0, StrName(byte.arg), _1);
  159. STACK_SHRINK(2);
  160. } DISPATCH();
  161. TARGET(STORE_SUBSCR)
  162. _2 = POPX(); // b
  163. _1 = POPX(); // a
  164. _0 = POPX(); // val
  165. call_method(_1, __setitem__, _2, _0);
  166. DISPATCH();
  167. TARGET(DELETE_FAST)
  168. _0 = frame->_locals[byte.arg];
  169. if(_0 == nullptr) vm->NameError(co->varnames[byte.arg]);
  170. frame->_locals[byte.arg] = nullptr;
  171. DISPATCH();
  172. TARGET(DELETE_NAME)
  173. _name = StrName(byte.arg);
  174. if(frame->_callable != nullptr){
  175. if(!frame->_locals.contains(_name)) vm->NameError(_name);
  176. frame->_locals.erase(_name);
  177. }else{
  178. if(!frame->f_globals().contains(_name)) vm->NameError(_name);
  179. frame->f_globals().erase(_name);
  180. }
  181. DISPATCH();
  182. TARGET(DELETE_GLOBAL)
  183. _name = StrName(byte.arg);
  184. if(frame->f_globals().contains(_name)){
  185. frame->f_globals().erase(_name);
  186. }else{
  187. NameError(_name);
  188. }
  189. DISPATCH();
  190. TARGET(DELETE_ATTR)
  191. _0 = POPX();
  192. _name = StrName(byte.arg);
  193. if(!_0->is_attr_valid()) TypeError("cannot delete attribute");
  194. if(!_0->attr().contains(_name)) AttributeError(_0, _name);
  195. _0->attr().erase(_name);
  196. DISPATCH();
  197. TARGET(DELETE_SUBSCR)
  198. _1 = POPX();
  199. _0 = POPX();
  200. call_method(_0, __delitem__, _1);
  201. DISPATCH();
  202. /*****************************************/
  203. TARGET(BUILD_LIST)
  204. _0 = VAR(STACK_VIEW(byte.arg).to_list());
  205. STACK_SHRINK(byte.arg);
  206. PUSH(_0);
  207. DISPATCH();
  208. TARGET(BUILD_DICT) {
  209. PyObject* t = VAR(STACK_VIEW(byte.arg).to_tuple());
  210. PyObject* obj = call(builtins->attr(m_dict), t);
  211. STACK_SHRINK(byte.arg);
  212. PUSH(obj);
  213. } DISPATCH();
  214. TARGET(BUILD_SET) {
  215. PyObject* t = VAR(STACK_VIEW(byte.arg).to_tuple());
  216. PyObject* obj = call(builtins->attr(m_set), t);
  217. STACK_SHRINK(byte.arg);
  218. PUSH(obj);
  219. } DISPATCH();
  220. TARGET(BUILD_SLICE)
  221. _2 = POPX(); // step
  222. _1 = POPX(); // stop
  223. _0 = POPX(); // start
  224. PUSH(VAR(Slice(_0, _1, _2)));
  225. DISPATCH();
  226. TARGET(BUILD_TUPLE)
  227. _0 = VAR(STACK_VIEW(byte.arg).to_tuple());
  228. STACK_SHRINK(byte.arg);
  229. PUSH(_0);
  230. DISPATCH();
  231. TARGET(BUILD_STRING) {
  232. std::stringstream ss;
  233. auto view = STACK_VIEW(byte.arg);
  234. for(PyObject* obj : view) ss << CAST(Str&, asStr(obj));
  235. STACK_SHRINK(byte.arg);
  236. PUSH(VAR(ss.str()));
  237. } DISPATCH();
  238. /*****************************************/
  239. TARGET(BINARY_OP)
  240. _1 = POPX(); // b
  241. _0 = TOP(); // a
  242. TOP() = call_method(_0, BINARY_SPECIAL_METHODS[byte.arg], _1);
  243. DISPATCH();
  244. #define INT_BINARY_OP(op, func) \
  245. if(is_both_int(TOP(), SECOND())){ \
  246. i64 b = _CAST(i64, TOP()); \
  247. i64 a = _CAST(i64, SECOND()); \
  248. POP(); \
  249. TOP() = VAR(a op b); \
  250. }else{ \
  251. _1 = POPX(); \
  252. _0 = TOP(); \
  253. TOP() = call_method(_0, func, _1); \
  254. }
  255. TARGET(BINARY_ADD)
  256. INT_BINARY_OP(+, __add__)
  257. DISPATCH()
  258. TARGET(BINARY_SUB)
  259. INT_BINARY_OP(-, __sub__)
  260. DISPATCH()
  261. TARGET(BINARY_MUL)
  262. INT_BINARY_OP(*, __mul__)
  263. DISPATCH()
  264. TARGET(BINARY_FLOORDIV)
  265. INT_BINARY_OP(/, __floordiv__)
  266. DISPATCH()
  267. TARGET(BINARY_MOD)
  268. INT_BINARY_OP(%, __mod__)
  269. DISPATCH()
  270. TARGET(COMPARE_LT)
  271. INT_BINARY_OP(<, __lt__)
  272. DISPATCH()
  273. TARGET(COMPARE_LE)
  274. INT_BINARY_OP(<=, __le__)
  275. DISPATCH()
  276. TARGET(COMPARE_EQ)
  277. INT_BINARY_OP(==, __eq__)
  278. DISPATCH()
  279. TARGET(COMPARE_NE)
  280. INT_BINARY_OP(!=, __ne__)
  281. DISPATCH()
  282. TARGET(COMPARE_GT)
  283. INT_BINARY_OP(>, __gt__)
  284. DISPATCH()
  285. TARGET(COMPARE_GE)
  286. INT_BINARY_OP(>=, __ge__)
  287. DISPATCH()
  288. TARGET(BITWISE_LSHIFT)
  289. INT_BINARY_OP(<<, __lshift__)
  290. DISPATCH()
  291. TARGET(BITWISE_RSHIFT)
  292. INT_BINARY_OP(>>, __rshift__)
  293. DISPATCH()
  294. TARGET(BITWISE_AND)
  295. INT_BINARY_OP(&, __and__)
  296. DISPATCH()
  297. TARGET(BITWISE_OR)
  298. INT_BINARY_OP(|, __or__)
  299. DISPATCH()
  300. TARGET(BITWISE_XOR)
  301. INT_BINARY_OP(^, __xor__)
  302. DISPATCH()
  303. #undef INT_BINARY_OP
  304. TARGET(IS_OP)
  305. _1 = POPX(); // rhs
  306. _0 = TOP(); // lhs
  307. if(byte.arg == 1){
  308. TOP() = VAR(_0 != _1);
  309. }else{
  310. TOP() = VAR(_0 == _1);
  311. }
  312. DISPATCH();
  313. TARGET(CONTAINS_OP)
  314. // a in b -> b __contains__ a
  315. _0 = call_method(TOP(), __contains__, SECOND());
  316. POP();
  317. if(byte.arg == 1){
  318. TOP() = VAR(!CAST(bool, _0));
  319. }else{
  320. TOP() = VAR(CAST(bool, _0));
  321. }
  322. DISPATCH();
  323. /*****************************************/
  324. TARGET(JUMP_ABSOLUTE)
  325. frame->jump_abs(byte.arg);
  326. DISPATCH();
  327. TARGET(POP_JUMP_IF_FALSE)
  328. if(!asBool(POPX())) frame->jump_abs(byte.arg);
  329. DISPATCH();
  330. TARGET(JUMP_IF_TRUE_OR_POP)
  331. if(asBool(TOP()) == true) frame->jump_abs(byte.arg);
  332. else POP();
  333. DISPATCH();
  334. TARGET(JUMP_IF_FALSE_OR_POP)
  335. if(asBool(TOP()) == false) frame->jump_abs(byte.arg);
  336. else POP();
  337. DISPATCH();
  338. TARGET(LOOP_CONTINUE)
  339. frame->jump_abs(co_blocks[byte.block].start);
  340. DISPATCH();
  341. TARGET(LOOP_BREAK)
  342. frame->jump_abs_break(co_blocks[byte.block].end);
  343. DISPATCH();
  344. TARGET(GOTO) {
  345. StrName name(byte.arg);
  346. int index = co->labels.try_get(name);
  347. if(index < 0) _error("KeyError", fmt("label ", name.escape(), " not found"));
  348. frame->jump_abs_break(index);
  349. } DISPATCH();
  350. /*****************************************/
  351. TARGET(BEGIN_CALL)
  352. PUSH(PY_BEGIN_CALL);
  353. DISPATCH();
  354. TARGET(CALL)
  355. _0 = vectorcall(
  356. byte.arg & 0xFFFF, // ARGC
  357. (byte.arg>>16) & 0xFFFF, // KWARGC
  358. true
  359. );
  360. if(_0 == PY_OP_CALL) DISPATCH_OP_CALL();
  361. PUSH(_0);
  362. DISPATCH();
  363. TARGET(RETURN_VALUE)
  364. _0 = POPX();
  365. _pop_frame();
  366. if(frame.index == base_id){ // [ frameBase<- ]
  367. return _0;
  368. }else{
  369. frame = top_frame();
  370. PUSH(_0);
  371. goto __NEXT_FRAME;
  372. }
  373. TARGET(YIELD_VALUE)
  374. return PY_OP_YIELD;
  375. /*****************************************/
  376. TARGET(LIST_APPEND)
  377. _0 = POPX();
  378. CAST(List&, SECOND()).push_back(_0);
  379. DISPATCH();
  380. TARGET(DICT_ADD) {
  381. _0 = POPX();
  382. Tuple& t = CAST(Tuple&, _0);
  383. call_method(SECOND(), __setitem__, t[0], t[1]);
  384. } DISPATCH();
  385. TARGET(SET_ADD)
  386. _0 = POPX();
  387. call_method(SECOND(), m_add, _0);
  388. DISPATCH();
  389. /*****************************************/
  390. TARGET(UNARY_NEGATIVE)
  391. TOP() = num_negated(TOP());
  392. DISPATCH();
  393. TARGET(UNARY_NOT)
  394. TOP() = VAR(!asBool(TOP()));
  395. DISPATCH();
  396. /*****************************************/
  397. TARGET(GET_ITER)
  398. TOP() = asIter(TOP());
  399. DISPATCH();
  400. TARGET(FOR_ITER)
  401. _0 = PyIterNext(TOP());
  402. if(_0 != StopIteration){
  403. PUSH(_0);
  404. }else{
  405. frame->jump_abs_break(co_blocks[byte.block].end);
  406. }
  407. DISPATCH();
  408. /*****************************************/
  409. TARGET(IMPORT_NAME) {
  410. StrName name(byte.arg);
  411. PyObject* ext_mod = _modules.try_get(name);
  412. if(ext_mod == nullptr){
  413. Str source;
  414. auto it = _lazy_modules.find(name);
  415. if(it == _lazy_modules.end()){
  416. Bytes b = _read_file_cwd(fmt(name, ".py"));
  417. if(!b) _error("ImportError", fmt("module ", name.escape(), " not found"));
  418. source = Str(b.str());
  419. }else{
  420. source = it->second;
  421. _lazy_modules.erase(it);
  422. }
  423. CodeObject_ code = compile(source, Str(name.sv())+".py", EXEC_MODE);
  424. PyObject* new_mod = new_module(name);
  425. _exec(code, new_mod);
  426. new_mod->attr()._try_perfect_rehash();
  427. PUSH(new_mod);
  428. }else{
  429. PUSH(ext_mod);
  430. }
  431. } DISPATCH();
  432. TARGET(IMPORT_STAR) {
  433. PyObject* obj = POPX();
  434. for(auto& [name, value]: obj->attr().items()){
  435. std::string_view s = name.sv();
  436. if(s.empty() || s[0] == '_') continue;
  437. frame->f_globals().set(name, value);
  438. }
  439. }; DISPATCH();
  440. /*****************************************/
  441. TARGET(UNPACK_SEQUENCE)
  442. TARGET(UNPACK_EX) {
  443. auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
  444. PyObject* iter = asIter(POPX());
  445. for(int i=0; i<byte.arg; i++){
  446. PyObject* item = PyIterNext(iter);
  447. if(item == StopIteration) ValueError("not enough values to unpack");
  448. PUSH(item);
  449. }
  450. // handle extra items
  451. if(byte.op == OP_UNPACK_EX){
  452. List extras;
  453. while(true){
  454. PyObject* item = PyIterNext(iter);
  455. if(item == StopIteration) break;
  456. extras.push_back(item);
  457. }
  458. PUSH(VAR(extras));
  459. }else{
  460. if(PyIterNext(iter) != StopIteration) ValueError("too many values to unpack");
  461. }
  462. } DISPATCH();
  463. TARGET(UNPACK_UNLIMITED) {
  464. auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
  465. PyObject* iter = asIter(POPX());
  466. _0 = PyIterNext(iter);
  467. while(_0 != StopIteration){
  468. PUSH(_0);
  469. _0 = PyIterNext(iter);
  470. }
  471. } DISPATCH();
  472. /*****************************************/
  473. TARGET(BEGIN_CLASS) {
  474. StrName name(byte.arg);
  475. PyObject* super_cls = POPX();
  476. if(super_cls == None) super_cls = _t(tp_object);
  477. check_type(super_cls, tp_type);
  478. PyObject* cls = new_type_object(frame->_module, name, OBJ_GET(Type, super_cls));
  479. PUSH(cls);
  480. } DISPATCH();
  481. TARGET(END_CLASS)
  482. _0 = POPX();
  483. _0->attr()._try_perfect_rehash();
  484. DISPATCH();
  485. TARGET(STORE_CLASS_ATTR)
  486. _name = StrName(byte.arg);
  487. _0 = POPX();
  488. TOP()->attr().set(_name, _0);
  489. DISPATCH();
  490. /*****************************************/
  491. // // TODO: using "goto" inside with block may cause __exit__ not called
  492. TARGET(WITH_ENTER)
  493. call_method(POPX(), __enter__);
  494. DISPATCH();
  495. TARGET(WITH_EXIT)
  496. call_method(POPX(), __exit__);
  497. DISPATCH();
  498. /*****************************************/
  499. TARGET(ASSERT) {
  500. PyObject* obj = TOP();
  501. Str msg;
  502. if(is_type(obj, tp_tuple)){
  503. auto& t = CAST(Tuple&, obj);
  504. if(t.size() != 2) ValueError("assert tuple must have 2 elements");
  505. obj = t[0];
  506. msg = CAST(Str&, asStr(t[1]));
  507. }
  508. bool ok = asBool(obj);
  509. POP();
  510. if(!ok) _error("AssertionError", msg);
  511. } DISPATCH();
  512. TARGET(EXCEPTION_MATCH) {
  513. const auto& e = CAST(Exception&, TOP());
  514. _name = StrName(byte.arg);
  515. PUSH(VAR(e.match_type(_name)));
  516. } DISPATCH();
  517. TARGET(RAISE) {
  518. PyObject* obj = POPX();
  519. Str msg = obj == None ? "" : CAST(Str, asStr(obj));
  520. _error(StrName(byte.arg), msg);
  521. } DISPATCH();
  522. TARGET(RE_RAISE) _raise(); DISPATCH();
  523. /*****************************************/
  524. TARGET(SETUP_DOCSTRING)
  525. TOP()->attr().set(__doc__, co_consts[byte.arg]);
  526. DISPATCH();
  527. TARGET(FORMAT_STRING) {
  528. _0 = POPX();
  529. const Str& spec = CAST(Str&, co_consts[byte.arg]);
  530. PUSH(format(spec, _0));
  531. } DISPATCH();
  532. #if !PK_ENABLE_COMPUTED_GOTO
  533. #if DEBUG_EXTRA_CHECK
  534. default: throw std::runtime_error(fmt(OP_NAMES[byte.op], " is not implemented"));
  535. #else
  536. default: UNREACHABLE();
  537. #endif
  538. }
  539. #endif
  540. }
  541. #undef DISPATCH
  542. #undef TARGET
  543. #undef DISPATCH_OP_CALL
  544. /**********************************************************************/
  545. UNREACHABLE();
  546. }catch(HandledException& e){
  547. continue;
  548. }catch(UnhandledException& e){
  549. PyObject* obj = POPX();
  550. Exception& _e = CAST(Exception&, obj);
  551. _e.st_push(frame->snapshot());
  552. _pop_frame();
  553. if(callstack.empty()){
  554. #if DEBUG_FULL_EXCEPTION
  555. std::cerr << _e.summary() << std::endl;
  556. #endif
  557. throw _e;
  558. }
  559. frame = top_frame();
  560. PUSH(obj);
  561. if(frame.index < base_id) throw ToBeRaisedException();
  562. need_raise = true;
  563. }catch(ToBeRaisedException& e){
  564. need_raise = true;
  565. }
  566. }
  567. }
  568. #undef TOP
  569. #undef SECOND
  570. #undef THIRD
  571. #undef PEEK
  572. #undef STACK_SHRINK
  573. #undef PUSH
  574. #undef POP
  575. #undef POPX
  576. #undef STACK_VIEW
  577. } // namespace pkpy