ceval.h 19 KB

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