ceval.h 19 KB

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