ceval.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. #include "pocketpy/ceval.h"
  2. namespace pkpy{
  3. static i64 _py_sint(PyObject* obj) noexcept {
  4. return (i64)(PK_BITS(obj) >> 2);
  5. }
  6. 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. const PyTypeInfo* _ti;
  13. StrName _name;
  14. while(true){
  15. #if PK_DEBUG_EXTRA_CHECK
  16. if(frame.index < base_id) FATAL_ERROR();
  17. #endif
  18. try{
  19. if(need_raise){ need_raise = false; _raise(); }
  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. #if PK_ENABLE_CEVAL_CALLBACK
  27. #define CEVAL_STEP() byte = frame->next_bytecode(); if(_ceval_on_step) _ceval_on_step(this, frame.get(), byte)
  28. #else
  29. #define CEVAL_STEP() byte = frame->next_bytecode()
  30. #endif
  31. #define DISPATCH_OP_CALL() { frame = top_frame(); goto __NEXT_FRAME; }
  32. __NEXT_FRAME:
  33. Bytecode CEVAL_STEP();
  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 "pocketpy/opcodes.h"
  42. #undef OPCODE
  43. };
  44. #define DISPATCH() { CEVAL_STEP(); 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() { CEVAL_STEP(); goto __NEXT_STEP;}
  50. __NEXT_STEP:;
  51. #if PK_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(ROT_THREE)
  63. _0 = TOP();
  64. TOP() = SECOND();
  65. SECOND() = THIRD();
  66. THIRD() = _0;
  67. DISPATCH();
  68. TARGET(PRINT_EXPR)
  69. if(TOP() != None) stdout_write(CAST(Str&, py_repr(TOP())) + "\n");
  70. POP();
  71. DISPATCH();
  72. /*****************************************/
  73. TARGET(LOAD_CONST)
  74. if(heap._should_auto_collect()) heap._auto_collect();
  75. PUSH(co_consts[byte.arg]);
  76. DISPATCH();
  77. TARGET(LOAD_NONE) PUSH(None); DISPATCH();
  78. TARGET(LOAD_TRUE) PUSH(True); DISPATCH();
  79. TARGET(LOAD_FALSE) PUSH(False); DISPATCH();
  80. TARGET(LOAD_INTEGER) PUSH(VAR(byte.arg)); DISPATCH();
  81. TARGET(LOAD_ELLIPSIS) PUSH(Ellipsis); DISPATCH();
  82. TARGET(LOAD_FUNCTION) {
  83. FuncDecl_ decl = co->func_decls[byte.arg];
  84. PyObject* obj;
  85. if(decl->nested){
  86. NameDict_ captured = frame->_locals.to_namedict();
  87. obj = VAR(Function({decl, frame->_module, captured}));
  88. captured->set(decl->code->name, obj);
  89. }else{
  90. obj = VAR(Function({decl, frame->_module}));
  91. }
  92. PUSH(obj);
  93. } DISPATCH();
  94. TARGET(LOAD_NULL) PUSH(PY_NULL); DISPATCH();
  95. /*****************************************/
  96. TARGET(LOAD_FAST) {
  97. if(heap._should_auto_collect()) heap._auto_collect();
  98. _0 = frame->_locals[byte.arg];
  99. if(_0 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
  100. PUSH(_0);
  101. } DISPATCH();
  102. TARGET(LOAD_NAME) {
  103. if(heap._should_auto_collect()) heap._auto_collect();
  104. _name = StrName(byte.arg);
  105. PyObject** slot = frame->_locals.try_get_name(_name);
  106. if(slot != nullptr) {
  107. if(*slot == PY_NULL) vm->UnboundLocalError(_name);
  108. PUSH(*slot);
  109. DISPATCH();
  110. }
  111. _0 = frame->f_closure_try_get(_name);
  112. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  113. _0 = frame->f_globals().try_get_likely_found(_name);
  114. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  115. _0 = vm->builtins->attr().try_get_likely_found(_name);
  116. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  117. vm->NameError(_name);
  118. } DISPATCH();
  119. TARGET(LOAD_NONLOCAL) {
  120. if(heap._should_auto_collect()) heap._auto_collect();
  121. _name = StrName(byte.arg);
  122. _0 = frame->f_closure_try_get(_name);
  123. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  124. _0 = frame->f_globals().try_get_likely_found(_name);
  125. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  126. _0 = vm->builtins->attr().try_get_likely_found(_name);
  127. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  128. vm->NameError(_name);
  129. } DISPATCH();
  130. TARGET(LOAD_GLOBAL)
  131. if(heap._should_auto_collect()) heap._auto_collect();
  132. _name = StrName(byte.arg);
  133. _0 = frame->f_globals().try_get_likely_found(_name);
  134. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  135. _0 = vm->builtins->attr().try_get_likely_found(_name);
  136. if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
  137. vm->NameError(_name);
  138. DISPATCH();
  139. TARGET(LOAD_ATTR)
  140. TOP() = getattr(TOP(), StrName(byte.arg));
  141. DISPATCH();
  142. TARGET(LOAD_METHOD)
  143. TOP() = get_unbound_method(TOP(), StrName(byte.arg), &_0, true, true);
  144. PUSH(_0);
  145. DISPATCH();
  146. TARGET(LOAD_SUBSCR)
  147. _1 = POPX(); // b
  148. _0 = TOP(); // a
  149. _ti = _inst_type_info(_0);
  150. if(_ti->m__getitem__){
  151. TOP() = _ti->m__getitem__(this, _0, _1);
  152. }else{
  153. TOP() = call_method(_0, __getitem__, _1);
  154. }
  155. DISPATCH();
  156. TARGET(STORE_FAST)
  157. frame->_locals[byte.arg] = POPX();
  158. DISPATCH();
  159. TARGET(STORE_NAME){
  160. _name = StrName(byte.arg);
  161. _0 = POPX();
  162. if(frame->_callable != nullptr){
  163. PyObject** slot = frame->_locals.try_get_name(_name);
  164. if(slot == nullptr) vm->UnboundLocalError(_name);
  165. *slot = _0;
  166. }else{
  167. frame->f_globals().set(_name, _0);
  168. }
  169. } DISPATCH();
  170. TARGET(STORE_GLOBAL)
  171. frame->f_globals().set(StrName(byte.arg), POPX());
  172. DISPATCH();
  173. TARGET(STORE_ATTR) {
  174. _0 = TOP(); // a
  175. _1 = SECOND(); // val
  176. setattr(_0, StrName(byte.arg), _1);
  177. STACK_SHRINK(2);
  178. } DISPATCH();
  179. TARGET(STORE_SUBSCR)
  180. _2 = POPX(); // b
  181. _1 = POPX(); // a
  182. _0 = POPX(); // val
  183. _ti = _inst_type_info(_1);
  184. if(_ti->m__setitem__){
  185. _ti->m__setitem__(this, _1, _2, _0);
  186. }else{
  187. call_method(_1, __setitem__, _2, _0);
  188. }
  189. DISPATCH();
  190. TARGET(DELETE_FAST)
  191. _0 = frame->_locals[byte.arg];
  192. if(_0 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
  193. frame->_locals[byte.arg] = PY_NULL;
  194. DISPATCH();
  195. TARGET(DELETE_NAME)
  196. _name = StrName(byte.arg);
  197. if(frame->_callable != nullptr){
  198. PyObject** slot = frame->_locals.try_get_name(_name);
  199. if(slot == nullptr) vm->UnboundLocalError(_name);
  200. *slot = PY_NULL;
  201. }else{
  202. if(!frame->f_globals().del(_name)) vm->NameError(_name);
  203. }
  204. DISPATCH();
  205. TARGET(DELETE_GLOBAL)
  206. _name = StrName(byte.arg);
  207. if(!frame->f_globals().del(_name)) vm->NameError(_name);
  208. DISPATCH();
  209. TARGET(DELETE_ATTR)
  210. _0 = POPX();
  211. _name = StrName(byte.arg);
  212. delattr(_0, _name);
  213. DISPATCH();
  214. TARGET(DELETE_SUBSCR)
  215. _1 = POPX();
  216. _0 = POPX();
  217. _ti = _inst_type_info(_0);
  218. if(_ti->m__delitem__){
  219. _ti->m__delitem__(this, _0, _1);
  220. }else{
  221. call_method(_0, __delitem__, _1);
  222. }
  223. DISPATCH();
  224. /*****************************************/
  225. TARGET(BUILD_LONG) {
  226. PK_LOCAL_STATIC const StrName m_long("long");
  227. _0 = builtins->attr().try_get_likely_found(m_long);
  228. if(_0 == nullptr) AttributeError(builtins, m_long);
  229. TOP() = call(_0, TOP());
  230. } DISPATCH();
  231. TARGET(BUILD_BYTES) {
  232. const Str& s = CAST(Str&, TOP());
  233. unsigned char* p = new unsigned char[s.size];
  234. memcpy(p, s.data, s.size);
  235. TOP() = VAR(Bytes(p, s.size));
  236. } DISPATCH();
  237. TARGET(BUILD_TUPLE)
  238. _0 = VAR(STACK_VIEW(byte.arg).to_tuple());
  239. STACK_SHRINK(byte.arg);
  240. PUSH(_0);
  241. DISPATCH();
  242. TARGET(BUILD_LIST)
  243. _0 = VAR(STACK_VIEW(byte.arg).to_list());
  244. STACK_SHRINK(byte.arg);
  245. PUSH(_0);
  246. DISPATCH();
  247. TARGET(BUILD_DICT)
  248. if(byte.arg == 0){
  249. PUSH(VAR(Dict(this)));
  250. DISPATCH();
  251. }
  252. _0 = VAR(STACK_VIEW(byte.arg).to_list());
  253. _0 = call(_t(tp_dict), _0);
  254. STACK_SHRINK(byte.arg);
  255. PUSH(_0);
  256. DISPATCH();
  257. TARGET(BUILD_SET)
  258. _0 = VAR(STACK_VIEW(byte.arg).to_list());
  259. _0 = call(builtins->attr(pk_id_set), _0);
  260. STACK_SHRINK(byte.arg);
  261. PUSH(_0);
  262. DISPATCH();
  263. TARGET(BUILD_SLICE)
  264. _2 = POPX(); // step
  265. _1 = POPX(); // stop
  266. _0 = POPX(); // start
  267. PUSH(VAR(Slice(_0, _1, _2)));
  268. DISPATCH();
  269. TARGET(BUILD_STRING) {
  270. std::stringstream ss;
  271. ArgsView view = STACK_VIEW(byte.arg);
  272. for(PyObject* obj : view) ss << CAST(Str&, py_str(obj));
  273. STACK_SHRINK(byte.arg);
  274. PUSH(VAR(ss.str()));
  275. } DISPATCH();
  276. /*****************************************/
  277. TARGET(BUILD_TUPLE_UNPACK) {
  278. auto _lock = heap.gc_scope_lock();
  279. List list;
  280. _unpack_as_list(STACK_VIEW(byte.arg), list);
  281. STACK_SHRINK(byte.arg);
  282. _0 = VAR(Tuple(std::move(list)));
  283. PUSH(_0);
  284. } DISPATCH();
  285. TARGET(BUILD_LIST_UNPACK) {
  286. auto _lock = heap.gc_scope_lock();
  287. List list;
  288. _unpack_as_list(STACK_VIEW(byte.arg), list);
  289. STACK_SHRINK(byte.arg);
  290. _0 = VAR(std::move(list));
  291. PUSH(_0);
  292. } DISPATCH();
  293. TARGET(BUILD_DICT_UNPACK) {
  294. auto _lock = heap.gc_scope_lock();
  295. Dict dict(this);
  296. _unpack_as_dict(STACK_VIEW(byte.arg), dict);
  297. STACK_SHRINK(byte.arg);
  298. _0 = VAR(std::move(dict));
  299. PUSH(_0);
  300. } DISPATCH();
  301. TARGET(BUILD_SET_UNPACK) {
  302. auto _lock = heap.gc_scope_lock();
  303. List list;
  304. _unpack_as_list(STACK_VIEW(byte.arg), list);
  305. STACK_SHRINK(byte.arg);
  306. _0 = VAR(std::move(list));
  307. _0 = call(builtins->attr(pk_id_set), _0);
  308. PUSH(_0);
  309. } DISPATCH();
  310. /*****************************************/
  311. #define PREDICT_INT_OP(op) \
  312. if(is_small_int(TOP()) && is_small_int(SECOND())){ \
  313. _1 = POPX(); \
  314. _0 = TOP(); \
  315. if constexpr(#op[0] == '/' || #op[0] == '%'){ \
  316. if(_py_sint(_1) == 0) ZeroDivisionError(); \
  317. } \
  318. TOP() = VAR(_py_sint(_0) op _py_sint(_1)); \
  319. DISPATCH(); \
  320. }
  321. #define BINARY_OP_SPECIAL(func) \
  322. _1 = POPX(); \
  323. _0 = TOP(); \
  324. _ti = _inst_type_info(_0); \
  325. if(_ti->m##func){ \
  326. TOP() = _ti->m##func(this, _0, _1); \
  327. }else{ \
  328. PyObject* self; \
  329. _2 = get_unbound_method(_0, func, &self, false); \
  330. if(_2 != nullptr) TOP() = call_method(self, _2, _1); \
  331. else TOP() = NotImplemented; \
  332. }
  333. #define BINARY_OP_RSPECIAL(op, func) \
  334. if(TOP() == NotImplemented){ \
  335. PyObject* self; \
  336. _2 = get_unbound_method(_1, func, &self, false); \
  337. if(_2 != nullptr) TOP() = call_method(self, _2, _0); \
  338. else BinaryOptError(op); \
  339. if(TOP() == NotImplemented) BinaryOptError(op); \
  340. }
  341. TARGET(BINARY_TRUEDIV)
  342. BINARY_OP_SPECIAL(__truediv__);
  343. if(TOP() == NotImplemented) BinaryOptError("/");
  344. DISPATCH();
  345. TARGET(BINARY_POW)
  346. BINARY_OP_SPECIAL(__pow__);
  347. if(TOP() == NotImplemented) BinaryOptError("**");
  348. DISPATCH();
  349. TARGET(BINARY_ADD)
  350. PREDICT_INT_OP(+);
  351. BINARY_OP_SPECIAL(__add__);
  352. BINARY_OP_RSPECIAL("+", __radd__);
  353. DISPATCH()
  354. TARGET(BINARY_SUB)
  355. PREDICT_INT_OP(-);
  356. BINARY_OP_SPECIAL(__sub__);
  357. BINARY_OP_RSPECIAL("-", __rsub__);
  358. DISPATCH()
  359. TARGET(BINARY_MUL)
  360. BINARY_OP_SPECIAL(__mul__);
  361. BINARY_OP_RSPECIAL("*", __rmul__);
  362. DISPATCH()
  363. TARGET(BINARY_FLOORDIV)
  364. PREDICT_INT_OP(/);
  365. BINARY_OP_SPECIAL(__floordiv__);
  366. if(TOP() == NotImplemented) BinaryOptError("//");
  367. DISPATCH()
  368. TARGET(BINARY_MOD)
  369. PREDICT_INT_OP(%);
  370. BINARY_OP_SPECIAL(__mod__);
  371. if(TOP() == NotImplemented) BinaryOptError("%");
  372. DISPATCH()
  373. TARGET(COMPARE_LT)
  374. BINARY_OP_SPECIAL(__lt__);
  375. BINARY_OP_RSPECIAL("<", __gt__);
  376. DISPATCH()
  377. TARGET(COMPARE_LE)
  378. BINARY_OP_SPECIAL(__le__);
  379. BINARY_OP_RSPECIAL("<=", __ge__);
  380. DISPATCH()
  381. TARGET(COMPARE_EQ)
  382. _1 = POPX();
  383. _0 = TOP();
  384. TOP() = VAR(py_equals(_0, _1));
  385. DISPATCH()
  386. TARGET(COMPARE_NE)
  387. _1 = POPX();
  388. _0 = TOP();
  389. TOP() = VAR(!py_equals(_0, _1));
  390. DISPATCH()
  391. TARGET(COMPARE_GT)
  392. BINARY_OP_SPECIAL(__gt__);
  393. BINARY_OP_RSPECIAL(">", __lt__);
  394. DISPATCH()
  395. TARGET(COMPARE_GE)
  396. BINARY_OP_SPECIAL(__ge__);
  397. BINARY_OP_RSPECIAL(">=", __le__);
  398. DISPATCH()
  399. TARGET(BITWISE_LSHIFT)
  400. PREDICT_INT_OP(<<);
  401. BINARY_OP_SPECIAL(__lshift__);
  402. if(TOP() == NotImplemented) BinaryOptError("<<");
  403. DISPATCH()
  404. TARGET(BITWISE_RSHIFT)
  405. PREDICT_INT_OP(>>);
  406. BINARY_OP_SPECIAL(__rshift__);
  407. if(TOP() == NotImplemented) BinaryOptError(">>");
  408. DISPATCH()
  409. TARGET(BITWISE_AND)
  410. PREDICT_INT_OP(&);
  411. BINARY_OP_SPECIAL(__and__);
  412. if(TOP() == NotImplemented) BinaryOptError("&");
  413. DISPATCH()
  414. TARGET(BITWISE_OR)
  415. PREDICT_INT_OP(|);
  416. BINARY_OP_SPECIAL(__or__);
  417. if(TOP() == NotImplemented) BinaryOptError("|");
  418. DISPATCH()
  419. TARGET(BITWISE_XOR)
  420. PREDICT_INT_OP(^);
  421. BINARY_OP_SPECIAL(__xor__);
  422. if(TOP() == NotImplemented) BinaryOptError("^");
  423. DISPATCH()
  424. TARGET(BINARY_MATMUL)
  425. BINARY_OP_SPECIAL(__matmul__);
  426. if(TOP() == NotImplemented) BinaryOptError("@");
  427. DISPATCH();
  428. #undef BINARY_OP_SPECIAL
  429. #undef PREDICT_INT_OP
  430. TARGET(IS_OP)
  431. _1 = POPX(); // rhs
  432. _0 = TOP(); // lhs
  433. TOP() = VAR(static_cast<bool>((_0==_1) ^ byte.arg));
  434. DISPATCH();
  435. TARGET(CONTAINS_OP)
  436. // a in b -> b __contains__ a
  437. _ti = _inst_type_info(TOP());
  438. if(_ti->m__contains__){
  439. _0 = _ti->m__contains__(this, TOP(), SECOND());
  440. }else{
  441. _0 = call_method(TOP(), __contains__, SECOND());
  442. }
  443. POP();
  444. TOP() = VAR(static_cast<bool>((int)CAST(bool, _0) ^ byte.arg));
  445. DISPATCH();
  446. /*****************************************/
  447. TARGET(JUMP_ABSOLUTE)
  448. frame->jump_abs(byte.arg);
  449. DISPATCH();
  450. TARGET(POP_JUMP_IF_FALSE)
  451. if(!py_bool(POPX())) frame->jump_abs(byte.arg);
  452. DISPATCH();
  453. TARGET(POP_JUMP_IF_TRUE)
  454. if(py_bool(POPX())) frame->jump_abs(byte.arg);
  455. DISPATCH();
  456. TARGET(JUMP_IF_TRUE_OR_POP)
  457. if(py_bool(TOP()) == true) frame->jump_abs(byte.arg);
  458. else POP();
  459. DISPATCH();
  460. TARGET(JUMP_IF_FALSE_OR_POP)
  461. if(py_bool(TOP()) == false) frame->jump_abs(byte.arg);
  462. else POP();
  463. DISPATCH();
  464. TARGET(SHORTCUT_IF_FALSE_OR_POP)
  465. if(py_bool(TOP()) == false){ // [b, False]
  466. STACK_SHRINK(2); // []
  467. PUSH(vm->False); // [False]
  468. frame->jump_abs(byte.arg);
  469. } else POP(); // [b]
  470. DISPATCH();
  471. TARGET(LOOP_CONTINUE)
  472. frame->jump_abs(co_blocks[byte.arg].start);
  473. DISPATCH();
  474. TARGET(LOOP_BREAK)
  475. frame->jump_abs_break(co_blocks[byte.arg].get_break_end());
  476. DISPATCH();
  477. TARGET(GOTO) {
  478. _name = StrName(byte.arg);
  479. int index = co->labels.try_get_likely_found(_name);
  480. if(index < 0) _error("KeyError", fmt("label ", _name.escape(), " not found"));
  481. frame->jump_abs_break(index);
  482. } DISPATCH();
  483. /*****************************************/
  484. TARGET(EVAL)
  485. _0 = builtins->attr(pk_id_eval);
  486. TOP() = call(_0, TOP());
  487. DISPATCH();
  488. TARGET(REPR)
  489. TOP() = py_repr(TOP());
  490. DISPATCH();
  491. TARGET(CALL)
  492. _0 = vectorcall(
  493. byte.arg & 0xFFFF, // ARGC
  494. (byte.arg>>16) & 0xFFFF, // KWARGC
  495. true
  496. );
  497. if(_0 == PY_OP_CALL) DISPATCH_OP_CALL();
  498. PUSH(_0);
  499. DISPATCH();
  500. TARGET(CALL_TP)
  501. // [callable, <self>, args: tuple, kwargs: dict | NULL]
  502. if(byte.arg){
  503. _2 = POPX();
  504. _1 = POPX();
  505. for(PyObject* obj: _CAST(Tuple&, _1)) PUSH(obj);
  506. _CAST(Dict&, _2).apply([this](PyObject* k, PyObject* v){
  507. PUSH(VAR(StrName(CAST(Str&, k)).index));
  508. PUSH(v);
  509. });
  510. _0 = vectorcall(
  511. _CAST(Tuple&, _1).size(), // ARGC
  512. _CAST(Dict&, _2).size(), // KWARGC
  513. true
  514. );
  515. }else{
  516. // no **kwargs
  517. _1 = POPX();
  518. for(PyObject* obj: _CAST(Tuple&, _1)) PUSH(obj);
  519. _0 = vectorcall(
  520. _CAST(Tuple&, _1).size(), // ARGC
  521. 0, // KWARGC
  522. true
  523. );
  524. }
  525. if(_0 == PY_OP_CALL) DISPATCH_OP_CALL();
  526. PUSH(_0);
  527. DISPATCH();
  528. TARGET(RETURN_VALUE)
  529. _0 = POPX();
  530. _pop_frame();
  531. if(frame.index == base_id){ // [ frameBase<- ]
  532. return _0;
  533. }else{
  534. frame = top_frame();
  535. PUSH(_0);
  536. goto __NEXT_FRAME;
  537. }
  538. TARGET(YIELD_VALUE)
  539. return PY_OP_YIELD;
  540. /*****************************************/
  541. TARGET(LIST_APPEND)
  542. _0 = POPX();
  543. CAST(List&, SECOND()).push_back(_0);
  544. DISPATCH();
  545. TARGET(DICT_ADD) {
  546. _0 = POPX();
  547. Tuple& t = CAST(Tuple&, _0);
  548. call_method(SECOND(), __setitem__, t[0], t[1]);
  549. } DISPATCH();
  550. TARGET(SET_ADD)
  551. _0 = POPX();
  552. call_method(SECOND(), pk_id_add, _0);
  553. DISPATCH();
  554. /*****************************************/
  555. TARGET(UNARY_NEGATIVE)
  556. TOP() = py_negate(TOP());
  557. DISPATCH();
  558. TARGET(UNARY_NOT)
  559. TOP() = VAR(!py_bool(TOP()));
  560. DISPATCH();
  561. TARGET(UNARY_STAR)
  562. TOP() = VAR(StarWrapper(byte.arg, TOP()));
  563. DISPATCH();
  564. TARGET(UNARY_INVERT)
  565. _ti = _inst_type_info(TOP());
  566. if(_ti->m__invert__) _0 = _ti->m__invert__(this, TOP());
  567. else _0 = call_method(TOP(), __invert__);
  568. TOP() = _0;
  569. DISPATCH();
  570. /*****************************************/
  571. TARGET(GET_ITER)
  572. TOP() = py_iter(TOP());
  573. DISPATCH();
  574. TARGET(FOR_ITER)
  575. _0 = py_next(TOP());
  576. if(_0 != StopIteration){
  577. PUSH(_0);
  578. }else{
  579. frame->jump_abs_break(co_blocks[byte.block].end);
  580. }
  581. DISPATCH();
  582. /*****************************************/
  583. TARGET(IMPORT_PATH)
  584. _0 = co_consts[byte.arg];
  585. PUSH(py_import(CAST(Str&, _0)));
  586. DISPATCH();
  587. TARGET(POP_IMPORT_STAR) {
  588. _0 = POPX(); // pop the module
  589. _1 = _0->attr().try_get(__all__);
  590. if(_1 != nullptr){
  591. for(PyObject* key: CAST(List&, _1)){
  592. _name = StrName::get(CAST(Str&, key).sv());
  593. PyObject* value = _0->attr().try_get_likely_found(_name);
  594. if(value == nullptr){
  595. ImportError(fmt("cannot import name ", _name.escape()));
  596. }else{
  597. frame->f_globals().set(_name, value);
  598. }
  599. }
  600. }else{
  601. for(auto& [name, value]: _0->attr().items()){
  602. std::string_view s = name.sv();
  603. if(s.empty() || s[0] == '_') continue;
  604. frame->f_globals().set(name, value);
  605. }
  606. }
  607. } DISPATCH();
  608. /*****************************************/
  609. TARGET(UNPACK_SEQUENCE){
  610. auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
  611. _0 = py_iter(POPX());
  612. for(int i=0; i<byte.arg; i++){
  613. _1 = py_next(_0);
  614. if(_1 == StopIteration) ValueError("not enough values to unpack");
  615. PUSH(_1);
  616. }
  617. if(py_next(_0) != StopIteration) ValueError("too many values to unpack");
  618. } DISPATCH();
  619. TARGET(UNPACK_EX) {
  620. auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
  621. _0 = py_iter(POPX());
  622. for(int i=0; i<byte.arg; i++){
  623. _1 = py_next(_0);
  624. if(_1 == StopIteration) ValueError("not enough values to unpack");
  625. PUSH(_1);
  626. }
  627. List extras;
  628. while(true){
  629. _1 = py_next(_0);
  630. if(_1 == StopIteration) break;
  631. extras.push_back(_1);
  632. }
  633. PUSH(VAR(extras));
  634. } DISPATCH();
  635. /*****************************************/
  636. TARGET(BEGIN_CLASS)
  637. _name = StrName(byte.arg);
  638. _0 = POPX(); // super
  639. if(_0 == None) _0 = _t(tp_object);
  640. check_non_tagged_type(_0, tp_type);
  641. _1 = new_type_object(frame->_module, _name, PK_OBJ_GET(Type, _0));
  642. PUSH(_1);
  643. DISPATCH();
  644. TARGET(END_CLASS)
  645. _0 = POPX();
  646. DISPATCH();
  647. TARGET(STORE_CLASS_ATTR){
  648. _name = StrName(byte.arg);
  649. _0 = POPX();
  650. if(is_non_tagged_type(_0, tp_function)){
  651. _0->attr().set(__class__, TOP());
  652. }
  653. TOP()->attr().set(_name, _0);
  654. } DISPATCH();
  655. /*****************************************/
  656. TARGET(WITH_ENTER)
  657. call_method(POPX(), __enter__);
  658. DISPATCH();
  659. TARGET(WITH_EXIT)
  660. call_method(POPX(), __exit__);
  661. DISPATCH();
  662. /*****************************************/
  663. TARGET(EXCEPTION_MATCH) {
  664. const auto& e = CAST(Exception&, TOP());
  665. _name = StrName(byte.arg);
  666. PUSH(VAR(e.match_type(_name)));
  667. } DISPATCH();
  668. TARGET(RAISE) {
  669. _0 = POPX();
  670. Str msg = _0 == None ? "" : CAST(Str, py_str(_0));
  671. _error(StrName(byte.arg), msg);
  672. } DISPATCH();
  673. TARGET(RAISE_ASSERT)
  674. if(byte.arg){
  675. _0 = py_str(POPX());
  676. _error("AssertionError", CAST(Str, _0));
  677. }else{
  678. _error("AssertionError", "");
  679. }
  680. DISPATCH();
  681. TARGET(RE_RAISE) _raise(true); DISPATCH();
  682. TARGET(POP_EXCEPTION) _last_exception = POPX(); DISPATCH();
  683. /*****************************************/
  684. TARGET(FORMAT_STRING) {
  685. _0 = POPX();
  686. const Str& spec = CAST(Str&, co_consts[byte.arg]);
  687. PUSH(format(spec, _0));
  688. } DISPATCH();
  689. /*****************************************/
  690. TARGET(INC_FAST){
  691. PyObject** p = &frame->_locals[byte.arg];
  692. if(*p == PY_NULL) vm->NameError(co->varnames[byte.arg]);
  693. *p = VAR(CAST(i64, *p) + 1);
  694. } DISPATCH();
  695. TARGET(DEC_FAST){
  696. PyObject** p = &frame->_locals[byte.arg];
  697. if(*p == PY_NULL) vm->NameError(co->varnames[byte.arg]);
  698. *p = VAR(CAST(i64, *p) - 1);
  699. } DISPATCH();
  700. TARGET(INC_GLOBAL){
  701. _name = StrName(byte.arg);
  702. PyObject** p = frame->f_globals().try_get_2_likely_found(_name);
  703. if(p == nullptr) vm->NameError(_name);
  704. *p = VAR(CAST(i64, *p) + 1);
  705. } DISPATCH();
  706. TARGET(DEC_GLOBAL){
  707. _name = StrName(byte.arg);
  708. PyObject** p = frame->f_globals().try_get_2_likely_found(_name);
  709. if(p == nullptr) vm->NameError(_name);
  710. *p = VAR(CAST(i64, *p) - 1);
  711. } DISPATCH();
  712. #if !PK_ENABLE_COMPUTED_GOTO
  713. #if PK_DEBUG_EXTRA_CHECK
  714. default: throw std::runtime_error(fmt(OP_NAMES[byte.op], " is not implemented"));
  715. #else
  716. default: UNREACHABLE();
  717. #endif
  718. }
  719. #endif
  720. }
  721. #undef DISPATCH
  722. #undef TARGET
  723. #undef DISPATCH_OP_CALL
  724. #undef CEVAL_STEP
  725. /**********************************************************************/
  726. UNREACHABLE();
  727. }catch(HandledException& e){
  728. PK_UNUSED(e);
  729. continue;
  730. }catch(UnhandledException& e){
  731. PK_UNUSED(e);
  732. PyObject* obj = POPX();
  733. Exception& _e = CAST(Exception&, obj);
  734. _pop_frame();
  735. if(callstack.empty()){
  736. #if PK_DEBUG_FULL_EXCEPTION
  737. std::cerr << _e.summary() << std::endl;
  738. #endif
  739. throw _e;
  740. }
  741. frame = top_frame();
  742. PUSH(obj);
  743. if(frame.index < base_id) throw ToBeRaisedException();
  744. need_raise = true;
  745. }catch(ToBeRaisedException& e){
  746. PK_UNUSED(e);
  747. need_raise = true;
  748. }
  749. }
  750. }
  751. #undef TOP
  752. #undef SECOND
  753. #undef THIRD
  754. #undef PEEK
  755. #undef STACK_SHRINK
  756. #undef PUSH
  757. #undef POP
  758. #undef POPX
  759. #undef STACK_VIEW
  760. #undef DISPATCH
  761. #undef TARGET
  762. #undef DISPATCH_OP_CALL
  763. } // namespace pkpy