ceval.cpp 31 KB

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