ceval.cpp 32 KB

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