ceval.cpp 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. #include "pocketpy/ceval.h"
  2. #include "pocketpy/codeobject.h"
  3. namespace pkpy{
  4. #define PREDICT_INT_OP(op) \
  5. if(is_int(_0) && is_int(_1)){ \
  6. TOP() = VAR(_0.as<i64>() op _1.as<i64>()); \
  7. DISPATCH() \
  8. }
  9. #define PREDICT_INT_DIV_OP(op) \
  10. if(is_int(_0) && is_int(_1)){ \
  11. i64 divisor = _1.as<i64>(); \
  12. if(divisor == 0) ZeroDivisionError(); \
  13. TOP() = VAR(_0.as<i64>() op divisor); \
  14. DISPATCH() \
  15. }
  16. #define BINARY_F_COMPARE(func, op, rfunc) \
  17. PyVar ret; \
  18. const PyTypeInfo* _ti = _tp_info(_0); \
  19. if(_ti->m##func){ \
  20. ret = _ti->m##func(this, _0, _1); \
  21. }else{ \
  22. PyVar self; \
  23. PyVar _2 = get_unbound_method(_0, func, &self, false); \
  24. if(_2 != nullptr) ret = call_method(self, _2, _1); \
  25. else ret = NotImplemented; \
  26. } \
  27. if(is_not_implemented(ret)){ \
  28. PyVar self; \
  29. PyVar _2 = get_unbound_method(_1, rfunc, &self, false); \
  30. if(_2 != nullptr) ret = call_method(self, _2, _0); \
  31. else BinaryOptError(op, _0, _1); \
  32. if(is_not_implemented(ret)) BinaryOptError(op, _0, _1); \
  33. }
  34. void VM::__op_unpack_sequence(uint16_t arg){
  35. PyVar _0 = POPX();
  36. if(is_type(_0, VM::tp_tuple)){
  37. // fast path for tuple
  38. Tuple& tuple = PK_OBJ_GET(Tuple, _0);
  39. if(tuple.size() == arg){
  40. for(PyVar obj: tuple) PUSH(obj);
  41. }else{
  42. ValueError(_S("expected ", (int)arg, " values to unpack, got ", (int)tuple.size()));
  43. }
  44. }else{
  45. auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
  46. _0 = py_iter(_0);
  47. const PyTypeInfo* ti = _tp_info(_0);
  48. for(int i=0; i<arg; i++){
  49. PyVar _1 = _py_next(ti, _0);
  50. if(_1 == StopIteration) ValueError("not enough values to unpack");
  51. PUSH(_1);
  52. }
  53. if(_py_next(ti, _0) != StopIteration) ValueError("too many values to unpack");
  54. }
  55. }
  56. bool VM::py_lt(PyVar _0, PyVar _1){
  57. BINARY_F_COMPARE(__lt__, "<", __gt__);
  58. return ret == True;
  59. }
  60. bool VM::py_le(PyVar _0, PyVar _1){
  61. BINARY_F_COMPARE(__le__, "<=", __ge__);
  62. return ret == True;
  63. }
  64. bool VM::py_gt(PyVar _0, PyVar _1){
  65. BINARY_F_COMPARE(__gt__, ">", __lt__);
  66. return ret == True;
  67. }
  68. bool VM::py_ge(PyVar _0, PyVar _1){
  69. BINARY_F_COMPARE(__ge__, ">=", __le__);
  70. return ret == True;
  71. }
  72. #undef BINARY_F_COMPARE
  73. #if PK_ENABLE_PROFILER
  74. #define CEVAL_STEP_CALLBACK() \
  75. if(_ceval_on_step) _ceval_on_step(this, frame, byte); \
  76. if(_profiler) _profiler->_step(callstack.size(), frame); \
  77. if(!_next_breakpoint.empty()) { _next_breakpoint._step(this); }
  78. #else
  79. #define CEVAL_STEP_CALLBACK() \
  80. if(_ceval_on_step && _ceval_on_step){ \
  81. if(_ceval_on_step) \
  82. if(_ceval_on_step) _ceval_on_step(this, frame, byte); \
  83. }
  84. #endif
  85. #define DISPATCH() { frame->_ip++; goto __NEXT_STEP; }
  86. #define DISPATCH_JUMP(__offset) { frame->_ip+=__offset; goto __NEXT_STEP; }
  87. #define DISPATCH_JUMP_ABSOLUTE(__target) { frame->_ip=&frame->co->codes[__target]; goto __NEXT_STEP; }
  88. PyVar VM::__run_top_frame(){
  89. Frame* frame = &callstack.top();
  90. const Frame* base_frame = frame;
  91. InternalException __internal_exception;
  92. while(true){
  93. try{
  94. /**********************************************************************/
  95. {
  96. __NEXT_FRAME:
  97. Bytecode byte;
  98. if(__internal_exception.type == InternalExceptionType::Null){
  99. // None
  100. frame->_ip++;
  101. }else if(__internal_exception.type == InternalExceptionType::Handled){
  102. // HandledException + continue
  103. frame->_ip = &frame->co->codes[__internal_exception.arg];
  104. __internal_exception = {};
  105. }else{
  106. // UnhandledException + continue (need_raise = true)
  107. // ToBeRaisedException + continue (need_raise = true)
  108. __internal_exception = {};
  109. __raise_exc(); // no return
  110. }
  111. __NEXT_STEP:
  112. byte = *frame->_ip;
  113. CEVAL_STEP_CALLBACK()
  114. #if PK_DEBUG_CEVAL_STEP
  115. __log_s_data();
  116. #endif
  117. switch ((Opcode)byte.op)
  118. {
  119. case OP_NO_OP: DISPATCH()
  120. /*****************************************/
  121. case OP_POP_TOP: POP(); DISPATCH()
  122. case OP_DUP_TOP: PUSH(TOP()); DISPATCH()
  123. case OP_DUP_TOP_TWO:
  124. // [a, b]
  125. PUSH(SECOND()); // [a, b, a]
  126. PUSH(SECOND()); // [a, b, a, b]
  127. DISPATCH()
  128. case OP_ROT_TWO: std::swap(TOP(), SECOND()); DISPATCH()
  129. case OP_ROT_THREE:{
  130. // [a, b, c] -> [c, a, b]
  131. PyVar _0 = TOP();
  132. TOP() = SECOND();
  133. SECOND() = THIRD();
  134. THIRD() = _0;
  135. } DISPATCH()
  136. case OP_PRINT_EXPR:
  137. if(TOP() != None) stdout_write(py_repr(TOP()) + "\n");
  138. POP();
  139. DISPATCH()
  140. /*****************************************/
  141. case OP_LOAD_CONST:
  142. PUSH(frame->co->consts[byte.arg]);
  143. DISPATCH()
  144. case OP_LOAD_NONE: PUSH(None); DISPATCH()
  145. case OP_LOAD_TRUE: PUSH(True); DISPATCH()
  146. case OP_LOAD_FALSE: PUSH(False); DISPATCH()
  147. /*****************************************/
  148. case OP_LOAD_SMALL_INT:
  149. s_data.emplace(tp_int, (i64)(int16_t)byte.arg);
  150. DISPATCH()
  151. /*****************************************/
  152. case OP_LOAD_ELLIPSIS: PUSH(Ellipsis); DISPATCH()
  153. case OP_LOAD_FUNCTION: {
  154. const FuncDecl_& decl = frame->co->func_decls[byte.arg];
  155. PyVar obj;
  156. if(decl->nested){
  157. NameDict_ captured = frame->_locals.to_namedict();
  158. obj = VAR(Function(decl, frame->_module, nullptr, captured));
  159. captured->set(decl->code->name, obj);
  160. }else{
  161. obj = VAR(Function(decl, frame->_module, nullptr, nullptr));
  162. }
  163. PUSH(obj);
  164. } DISPATCH()
  165. case OP_LOAD_NULL: PUSH(PY_NULL); DISPATCH()
  166. /*****************************************/
  167. case OP_LOAD_FAST: {
  168. PyVar _0 = frame->_locals[byte.arg];
  169. if(_0 == PY_NULL) vm->UnboundLocalError(frame->co->varnames[byte.arg]);
  170. PUSH(_0);
  171. } DISPATCH()
  172. case OP_LOAD_NAME: {
  173. StrName _name(byte.arg);
  174. PyVar* slot = frame->_locals.try_get_name(_name);
  175. if(slot != nullptr) {
  176. if(*slot == PY_NULL) vm->UnboundLocalError(_name);
  177. PUSH(*slot);
  178. DISPATCH()
  179. }
  180. PyVar* _0 = frame->f_closure_try_get(_name);
  181. if(_0 != nullptr) { PUSH(*_0); DISPATCH() }
  182. _0 = frame->f_globals().try_get_2_likely_found(_name);
  183. if(_0 != nullptr) { PUSH(*_0); DISPATCH() }
  184. _0 = vm->builtins->attr().try_get_2_likely_found(_name);
  185. if(_0 != nullptr) { PUSH(*_0); DISPATCH() }
  186. vm->NameError(_name);
  187. } DISPATCH()
  188. case OP_LOAD_NONLOCAL: {
  189. StrName _name(byte.arg);
  190. PyVar* _0 = frame->f_closure_try_get(_name);
  191. if(_0 != nullptr) { PUSH(*_0); DISPATCH() }
  192. _0 = frame->f_globals().try_get_2_likely_found(_name);
  193. if(_0 != nullptr) { PUSH(*_0); DISPATCH() }
  194. _0 = vm->builtins->attr().try_get_2_likely_found(_name);
  195. if(_0 != nullptr) { PUSH(*_0); DISPATCH() }
  196. vm->NameError(_name);
  197. } DISPATCH()
  198. case OP_LOAD_GLOBAL:{
  199. StrName _name(byte.arg);
  200. PyVar _0 = frame->f_globals().try_get_likely_found(_name);
  201. if(_0 != nullptr) { PUSH(_0); DISPATCH() }
  202. _0 = vm->builtins->attr().try_get_likely_found(_name);
  203. if(_0 != nullptr) { PUSH(_0); DISPATCH() }
  204. vm->NameError(_name);
  205. } DISPATCH()
  206. case OP_LOAD_ATTR:{
  207. TOP() = getattr(TOP(), StrName(byte.arg));
  208. } DISPATCH()
  209. case OP_LOAD_CLASS_GLOBAL:{
  210. PK_ASSERT(__curr_class != nullptr);
  211. StrName _name(byte.arg);
  212. PyVar _0 = getattr(__curr_class, _name, false);
  213. if(_0 != nullptr) { PUSH(_0); DISPATCH() }
  214. // load global if attribute not found
  215. _0 = frame->f_globals().try_get_likely_found(_name);
  216. if(_0 != nullptr) { PUSH(_0); DISPATCH() }
  217. _0 = vm->builtins->attr().try_get_likely_found(_name);
  218. if(_0 != nullptr) { PUSH(_0); DISPATCH() }
  219. vm->NameError(_name);
  220. } DISPATCH()
  221. case OP_LOAD_METHOD:{
  222. PyVar _0;
  223. TOP() = get_unbound_method(TOP(), StrName(byte.arg), &_0, true, true);
  224. PUSH(_0);
  225. }DISPATCH()
  226. case OP_LOAD_SUBSCR:{
  227. PyVar _1 = POPX(); // b
  228. PyVar _0 = TOP(); // a
  229. auto _ti = _tp_info(_0);
  230. if(_ti->m__getitem__){
  231. TOP() = _ti->m__getitem__(this, _0, _1);
  232. }else{
  233. TOP() = call_method(_0, __getitem__, _1);
  234. }
  235. } DISPATCH()
  236. case OP_LOAD_SUBSCR_FAST:{
  237. PyVar _1 = frame->_locals[byte.arg];
  238. if(_1 == PY_NULL) vm->UnboundLocalError(frame->co->varnames[byte.arg]);
  239. PyVar _0 = TOP(); // a
  240. auto _ti = _tp_info(_0);
  241. if(_ti->m__getitem__){
  242. TOP() = _ti->m__getitem__(this, _0, _1);
  243. }else{
  244. TOP() = call_method(_0, __getitem__, _1);
  245. }
  246. } DISPATCH()
  247. case OP_LOAD_SUBSCR_SMALL_INT:{
  248. PyVar _1 = VAR((int16_t)byte.arg);
  249. PyVar _0 = TOP(); // a
  250. auto _ti = _tp_info(_0);
  251. if(_ti->m__getitem__){
  252. TOP() = _ti->m__getitem__(this, _0, _1);
  253. }else{
  254. TOP() = call_method(_0, __getitem__, _1);
  255. }
  256. } DISPATCH()
  257. case OP_STORE_FAST:
  258. frame->_locals[byte.arg] = POPX();
  259. DISPATCH()
  260. case OP_STORE_NAME:{
  261. StrName _name(byte.arg);
  262. PyVar _0 = POPX();
  263. if(frame->_callable != nullptr){
  264. PyVar* slot = frame->_locals.try_get_name(_name);
  265. if(slot != nullptr){
  266. *slot = _0; // store in locals if possible
  267. }else{
  268. Function& func = frame->_callable->as<Function>();
  269. if(func.decl == __dynamic_func_decl){
  270. PK_DEBUG_ASSERT(func._closure != nullptr);
  271. func._closure->set(_name, _0);
  272. }else{
  273. vm->NameError(_name);
  274. }
  275. }
  276. }else{
  277. frame->f_globals().set(_name, _0);
  278. }
  279. } DISPATCH()
  280. case OP_STORE_GLOBAL:
  281. frame->f_globals().set(StrName(byte.arg), POPX());
  282. DISPATCH()
  283. case OP_STORE_ATTR: {
  284. PyVar _0 = TOP(); // a
  285. PyVar _1 = SECOND(); // val
  286. setattr(_0, StrName(byte.arg), _1);
  287. STACK_SHRINK(2);
  288. } DISPATCH()
  289. case OP_STORE_SUBSCR:{
  290. PyVar _2 = POPX(); // b
  291. PyVar _1 = POPX(); // a
  292. PyVar _0 = POPX(); // val
  293. auto _ti = _tp_info(_1);
  294. if(_ti->m__setitem__){
  295. _ti->m__setitem__(this, _1, _2, _0);
  296. }else{
  297. call_method(_1, __setitem__, _2, _0);
  298. }
  299. }DISPATCH()
  300. case OP_STORE_SUBSCR_FAST:{
  301. PyVar _2 = frame->_locals[byte.arg]; // b
  302. if(_2 == PY_NULL) vm->UnboundLocalError(frame->co->varnames[byte.arg]);
  303. PyVar _1 = POPX(); // a
  304. PyVar _0 = POPX(); // val
  305. auto _ti = _tp_info(_1);
  306. if(_ti->m__setitem__){
  307. _ti->m__setitem__(this, _1, _2, _0);
  308. }else{
  309. call_method(_1, __setitem__, _2, _0);
  310. }
  311. }DISPATCH()
  312. case OP_DELETE_FAST:{
  313. PyVar _0 = frame->_locals[byte.arg];
  314. if(_0 == PY_NULL) vm->UnboundLocalError(frame->co->varnames[byte.arg]);
  315. frame->_locals[byte.arg].set_null();
  316. }DISPATCH()
  317. case OP_DELETE_NAME:{
  318. StrName _name(byte.arg);
  319. if(frame->_callable != nullptr){
  320. PyVar* slot = frame->_locals.try_get_name(_name);
  321. if(slot != nullptr){
  322. slot->set_null();
  323. }else{
  324. Function& func = frame->_callable->as<Function>();
  325. if(func.decl == __dynamic_func_decl){
  326. PK_DEBUG_ASSERT(func._closure != nullptr);
  327. bool ok = func._closure->del(_name);
  328. if(!ok) vm->NameError(_name);
  329. }else{
  330. vm->NameError(_name);
  331. }
  332. }
  333. }else{
  334. if(!frame->f_globals().del(_name)) vm->NameError(_name);
  335. }
  336. } DISPATCH()
  337. case OP_DELETE_GLOBAL:{
  338. StrName _name(byte.arg);
  339. if(!frame->f_globals().del(_name)) vm->NameError(_name);
  340. }DISPATCH()
  341. case OP_DELETE_ATTR:{
  342. PyVar _0 = POPX();
  343. delattr(_0, StrName(byte.arg));
  344. } DISPATCH()
  345. case OP_DELETE_SUBSCR:{
  346. PyVar _1 = POPX();
  347. PyVar _0 = POPX();
  348. auto _ti = _tp_info(_0);
  349. if(_ti->m__delitem__){
  350. _ti->m__delitem__(this, _0, _1);
  351. }else{
  352. call_method(_0, __delitem__, _1);
  353. }
  354. }DISPATCH()
  355. /*****************************************/
  356. case OP_BUILD_LONG: {
  357. PyVar _0 = builtins->attr().try_get_likely_found(pk_id_long);
  358. if(_0 == nullptr) AttributeError(builtins, pk_id_long);
  359. TOP() = call(_0, TOP());
  360. } DISPATCH()
  361. case OP_BUILD_IMAG: {
  362. PyVar _0 = builtins->attr().try_get_likely_found(pk_id_complex);
  363. if(_0 == nullptr) AttributeError(builtins, pk_id_long);
  364. TOP() = call(_0, VAR(0), TOP());
  365. } DISPATCH()
  366. case OP_BUILD_BYTES: {
  367. const Str& s = CAST(Str&, TOP());
  368. unsigned char* p = new unsigned char[s.size];
  369. memcpy(p, s.data, s.size);
  370. TOP() = VAR(Bytes(p, s.size));
  371. } DISPATCH()
  372. case OP_BUILD_TUPLE:{
  373. PyVar _0 = VAR(STACK_VIEW(byte.arg).to_tuple());
  374. STACK_SHRINK(byte.arg);
  375. PUSH(_0);
  376. } DISPATCH()
  377. case OP_BUILD_LIST:{
  378. PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list());
  379. STACK_SHRINK(byte.arg);
  380. PUSH(_0);
  381. } DISPATCH()
  382. case OP_BUILD_DICT:{
  383. if(byte.arg == 0){
  384. PUSH(VAR(Dict()));
  385. DISPATCH()
  386. }
  387. PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list());
  388. _0 = call(_t(tp_dict), _0);
  389. STACK_SHRINK(byte.arg);
  390. PUSH(_0);
  391. } DISPATCH()
  392. case OP_BUILD_SET:{
  393. PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list());
  394. _0 = call(builtins->attr(pk_id_set), _0);
  395. STACK_SHRINK(byte.arg);
  396. PUSH(_0);
  397. } DISPATCH()
  398. case OP_BUILD_SLICE:{
  399. PyVar _2 = POPX(); // step
  400. PyVar _1 = POPX(); // stop
  401. PyVar _0 = POPX(); // start
  402. PUSH(VAR(Slice(_0, _1, _2)));
  403. } DISPATCH()
  404. case OP_BUILD_STRING: {
  405. SStream ss;
  406. ArgsView view = STACK_VIEW(byte.arg);
  407. for(PyVar obj : view) ss << py_str(obj);
  408. STACK_SHRINK(byte.arg);
  409. PUSH(VAR(ss.str()));
  410. } DISPATCH()
  411. /*****************************************/
  412. case OP_BUILD_TUPLE_UNPACK: {
  413. auto _lock = heap.gc_scope_lock();
  414. List list;
  415. __unpack_as_list(STACK_VIEW(byte.arg), list);
  416. STACK_SHRINK(byte.arg);
  417. PyVar _0 = VAR(Tuple(std::move(list)));
  418. PUSH(_0);
  419. } DISPATCH()
  420. case OP_BUILD_LIST_UNPACK: {
  421. auto _lock = heap.gc_scope_lock();
  422. List list;
  423. __unpack_as_list(STACK_VIEW(byte.arg), list);
  424. STACK_SHRINK(byte.arg);
  425. PyVar _0 = VAR(std::move(list));
  426. PUSH(_0);
  427. } DISPATCH()
  428. case OP_BUILD_DICT_UNPACK: {
  429. auto _lock = heap.gc_scope_lock();
  430. Dict dict;
  431. __unpack_as_dict(STACK_VIEW(byte.arg), dict);
  432. STACK_SHRINK(byte.arg);
  433. PyVar _0 = VAR(std::move(dict));
  434. PUSH(_0);
  435. } DISPATCH()
  436. case OP_BUILD_SET_UNPACK: {
  437. auto _lock = heap.gc_scope_lock();
  438. List list;
  439. __unpack_as_list(STACK_VIEW(byte.arg), list);
  440. STACK_SHRINK(byte.arg);
  441. PyVar _0 = VAR(std::move(list));
  442. _0 = call(builtins->attr(pk_id_set), _0);
  443. PUSH(_0);
  444. } DISPATCH()
  445. /*****************************************/
  446. #define BINARY_OP_SPECIAL(func) \
  447. _ti = _tp_info(_0); \
  448. if(_ti->m##func){ \
  449. TOP() = _ti->m##func(this, _0, _1); \
  450. }else{ \
  451. PyVar self; \
  452. PyVar _2 = get_unbound_method(_0, func, &self, false); \
  453. if(_2 != nullptr) TOP() = call_method(self, _2, _1); \
  454. else TOP() = NotImplemented; \
  455. }
  456. #define BINARY_OP_RSPECIAL(op, func) \
  457. if(is_not_implemented(TOP())){ \
  458. PyVar self; \
  459. PyVar _2 = get_unbound_method(_1, func, &self, false); \
  460. if(_2 != nullptr) TOP() = call_method(self, _2, _0); \
  461. else BinaryOptError(op, _0, _1); \
  462. if(is_not_implemented(TOP())) BinaryOptError(op, _0, _1); \
  463. }
  464. case OP_BINARY_TRUEDIV:{
  465. PyVar _1 = POPX();
  466. PyVar _0 = TOP();
  467. const PyTypeInfo* _ti;
  468. BINARY_OP_SPECIAL(__truediv__);
  469. if(is_not_implemented(TOP())) BinaryOptError("/", _0, _1);
  470. } DISPATCH()
  471. case OP_BINARY_POW:{
  472. PyVar _1 = POPX();
  473. PyVar _0 = TOP();
  474. const PyTypeInfo* _ti;
  475. BINARY_OP_SPECIAL(__pow__);
  476. if(is_not_implemented(TOP())) BinaryOptError("**", _0, _1);
  477. } DISPATCH()
  478. case OP_BINARY_ADD:{
  479. PyVar _1 = POPX();
  480. PyVar _0 = TOP();
  481. PREDICT_INT_OP(+)
  482. const PyTypeInfo* _ti;
  483. BINARY_OP_SPECIAL(__add__);
  484. BINARY_OP_RSPECIAL("+", __radd__);
  485. } DISPATCH()
  486. case OP_BINARY_SUB:{
  487. PyVar _1 = POPX();
  488. PyVar _0 = TOP();
  489. PREDICT_INT_OP(-)
  490. const PyTypeInfo* _ti;
  491. BINARY_OP_SPECIAL(__sub__);
  492. BINARY_OP_RSPECIAL("-", __rsub__);
  493. } DISPATCH()
  494. case OP_BINARY_MUL:{
  495. PyVar _1 = POPX();
  496. PyVar _0 = TOP();
  497. PREDICT_INT_OP(*)
  498. const PyTypeInfo* _ti;
  499. BINARY_OP_SPECIAL(__mul__);
  500. BINARY_OP_RSPECIAL("*", __rmul__);
  501. } DISPATCH()
  502. case OP_BINARY_FLOORDIV:{
  503. PyVar _1 = POPX();
  504. PyVar _0 = TOP();
  505. PREDICT_INT_DIV_OP(/)
  506. const PyTypeInfo* _ti;
  507. BINARY_OP_SPECIAL(__floordiv__);
  508. if(is_not_implemented(TOP())) BinaryOptError("//", _0, _1);
  509. } DISPATCH()
  510. case OP_BINARY_MOD:{
  511. PyVar _1 = POPX();
  512. PyVar _0 = TOP();
  513. PREDICT_INT_DIV_OP(%)
  514. const PyTypeInfo* _ti;
  515. BINARY_OP_SPECIAL(__mod__);
  516. if(is_not_implemented(TOP())) BinaryOptError("%", _0, _1);
  517. } DISPATCH()
  518. case OP_COMPARE_LT:{
  519. PyVar _1 = POPX();
  520. PyVar _0 = TOP();
  521. PREDICT_INT_OP(<)
  522. TOP() = VAR(py_lt(_0, _1));
  523. } DISPATCH()
  524. case OP_COMPARE_LE:{
  525. PyVar _1 = POPX();
  526. PyVar _0 = TOP();
  527. PREDICT_INT_OP(<=)
  528. TOP() = VAR(py_le(_0, _1));
  529. } DISPATCH()
  530. case OP_COMPARE_EQ:{
  531. PyVar _1 = POPX();
  532. PyVar _0 = TOP();
  533. TOP() = VAR(py_eq(_0, _1));
  534. } DISPATCH()
  535. case OP_COMPARE_NE:{
  536. PyVar _1 = POPX();
  537. PyVar _0 = TOP();
  538. TOP() = VAR(py_ne(_0, _1));
  539. } DISPATCH()
  540. case OP_COMPARE_GT:{
  541. PyVar _1 = POPX();
  542. PyVar _0 = TOP();
  543. PREDICT_INT_OP(>)
  544. TOP() = VAR(py_gt(_0, _1));
  545. } DISPATCH()
  546. case OP_COMPARE_GE:{
  547. PyVar _1 = POPX();
  548. PyVar _0 = TOP();
  549. PREDICT_INT_OP(>=)
  550. TOP() = VAR(py_ge(_0, _1));
  551. } DISPATCH()
  552. case OP_BITWISE_LSHIFT:{
  553. PyVar _1 = POPX();
  554. PyVar _0 = TOP();
  555. PREDICT_INT_OP(<<)
  556. const PyTypeInfo* _ti;
  557. BINARY_OP_SPECIAL(__lshift__);
  558. if(is_not_implemented(TOP())) BinaryOptError("<<", _0, _1);
  559. } DISPATCH()
  560. case OP_BITWISE_RSHIFT:{
  561. PyVar _1 = POPX();
  562. PyVar _0 = TOP();
  563. PREDICT_INT_OP(>>)
  564. const PyTypeInfo* _ti;
  565. BINARY_OP_SPECIAL(__rshift__);
  566. if(is_not_implemented(TOP())) BinaryOptError(">>", _0, _1);
  567. } DISPATCH()
  568. case OP_BITWISE_AND:{
  569. PyVar _1 = POPX();
  570. PyVar _0 = TOP();
  571. PREDICT_INT_OP(&)
  572. const PyTypeInfo* _ti;
  573. BINARY_OP_SPECIAL(__and__);
  574. if(is_not_implemented(TOP())) BinaryOptError("&", _0, _1);
  575. } DISPATCH()
  576. case OP_BITWISE_OR:{
  577. PyVar _1 = POPX();
  578. PyVar _0 = TOP();
  579. PREDICT_INT_OP(|)
  580. const PyTypeInfo* _ti;
  581. BINARY_OP_SPECIAL(__or__);
  582. if(is_not_implemented(TOP())) BinaryOptError("|", _0, _1);
  583. } DISPATCH()
  584. case OP_BITWISE_XOR:{
  585. PyVar _1 = POPX();
  586. PyVar _0 = TOP();
  587. PREDICT_INT_OP(^)
  588. const PyTypeInfo* _ti;
  589. BINARY_OP_SPECIAL(__xor__);
  590. if(is_not_implemented(TOP())) BinaryOptError("^", _0, _1);
  591. } DISPATCH()
  592. case OP_BINARY_MATMUL:{
  593. PyVar _1 = POPX();
  594. PyVar _0 = TOP();
  595. const PyTypeInfo* _ti;
  596. BINARY_OP_SPECIAL(__matmul__);
  597. if(is_not_implemented(TOP())) BinaryOptError("@", _0, _1);
  598. } DISPATCH()
  599. #undef BINARY_OP_SPECIAL
  600. #undef BINARY_OP_RSPECIAL
  601. #undef PREDICT_INT_OP
  602. case OP_IS_OP:{
  603. PyVar _1 = POPX(); // rhs
  604. PyVar _0 = TOP(); // lhs
  605. TOP() = _0 == _1 ? True : False;
  606. } DISPATCH()
  607. case OP_IS_NOT_OP:{
  608. PyVar _1 = POPX(); // rhs
  609. PyVar _0 = TOP(); // lhs
  610. TOP() = _0 != _1 ? True : False;
  611. } DISPATCH()
  612. case OP_CONTAINS_OP:{
  613. // a in b -> b __contains__ a
  614. auto _ti = _tp_info(TOP());
  615. PyVar _0;
  616. if(_ti->m__contains__){
  617. _0 = _ti->m__contains__(this, TOP(), SECOND());
  618. }else{
  619. _0 = call_method(TOP(), __contains__, SECOND());
  620. }
  621. POP();
  622. TOP() = VAR(static_cast<bool>((int)CAST(bool, _0) ^ byte.arg));
  623. } DISPATCH()
  624. /*****************************************/
  625. case OP_JUMP_FORWARD:
  626. DISPATCH_JUMP((int16_t)byte.arg)
  627. case OP_POP_JUMP_IF_FALSE:
  628. if(!py_bool(POPX())) DISPATCH_JUMP((int16_t)byte.arg)
  629. DISPATCH()
  630. case OP_POP_JUMP_IF_TRUE:
  631. if(py_bool(POPX())) DISPATCH_JUMP((int16_t)byte.arg)
  632. DISPATCH()
  633. case OP_JUMP_IF_TRUE_OR_POP:
  634. if(py_bool(TOP())){
  635. DISPATCH_JUMP((int16_t)byte.arg)
  636. }else{
  637. POP();
  638. DISPATCH()
  639. }
  640. case OP_JUMP_IF_FALSE_OR_POP:
  641. if(!py_bool(TOP())){
  642. DISPATCH_JUMP((int16_t)byte.arg)
  643. }else{
  644. POP();
  645. DISPATCH()
  646. }
  647. case OP_SHORTCUT_IF_FALSE_OR_POP:
  648. if(!py_bool(TOP())){ // [b, False]
  649. STACK_SHRINK(2); // []
  650. PUSH(vm->False); // [False]
  651. DISPATCH_JUMP((int16_t)byte.arg)
  652. } else{
  653. POP(); // [b]
  654. DISPATCH()
  655. }
  656. case OP_LOOP_CONTINUE:
  657. // just an alias of OP_JUMP_FORWARD
  658. DISPATCH_JUMP((int16_t)byte.arg)
  659. case OP_LOOP_BREAK: {
  660. frame->prepare_jump_break(&s_data, frame->ip()+byte.arg);
  661. DISPATCH_JUMP((int16_t)byte.arg)
  662. }
  663. case OP_JUMP_ABSOLUTE_TOP:
  664. DISPATCH_JUMP_ABSOLUTE(_CAST(int, POPX()))
  665. case OP_GOTO: {
  666. StrName _name(byte.arg);
  667. int target = frame->co->labels.try_get_likely_found(_name);
  668. if(target < 0) RuntimeError(_S("label ", _name.escape(), " not found"));
  669. frame->prepare_jump_break(&s_data, target);
  670. DISPATCH_JUMP_ABSOLUTE(target)
  671. }
  672. /*****************************************/
  673. case OP_FSTRING_EVAL:{
  674. PyVar _0 = frame->co->consts[byte.arg];
  675. std::string_view string = CAST(Str&, _0).sv();
  676. auto it = __cached_codes.find(string);
  677. CodeObject_ code;
  678. if(it == __cached_codes.end()){
  679. code = vm->compile(string, "<eval>", EVAL_MODE, true);
  680. __cached_codes[string] = code;
  681. }else{
  682. code = it->second;
  683. }
  684. _0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
  685. PUSH(_0);
  686. } DISPATCH()
  687. case OP_REPR:
  688. TOP() = VAR(py_repr(TOP()));
  689. DISPATCH()
  690. case OP_CALL:{
  691. if(heap._should_auto_collect()) heap._auto_collect();
  692. PyVar _0 = vectorcall(
  693. byte.arg & 0xFF, // ARGC
  694. (byte.arg>>8) & 0xFF, // KWARGC
  695. true
  696. );
  697. if(_0 == PY_OP_CALL){
  698. frame = &callstack.top();
  699. goto __NEXT_FRAME;
  700. }
  701. PUSH(_0);
  702. } DISPATCH()
  703. case OP_CALL_TP:{
  704. if(heap._should_auto_collect()) heap._auto_collect();
  705. PyVar _0;
  706. PyVar _1;
  707. PyVar _2;
  708. // [callable, <self>, args: tuple, kwargs: dict | NULL]
  709. if(byte.arg){
  710. _2 = POPX();
  711. _1 = POPX();
  712. for(PyVar obj: _CAST(Tuple&, _1)) PUSH(obj);
  713. _CAST(Dict&, _2).apply([this](PyVar k, PyVar v){
  714. PUSH(VAR(StrName(CAST(Str&, k)).index));
  715. PUSH(v);
  716. });
  717. _0 = vectorcall(
  718. _CAST(Tuple&, _1).size(), // ARGC
  719. _CAST(Dict&, _2).size(), // KWARGC
  720. true
  721. );
  722. }else{
  723. // no **kwargs
  724. _1 = POPX();
  725. for(PyVar obj: _CAST(Tuple&, _1)) PUSH(obj);
  726. _0 = vectorcall(
  727. _CAST(Tuple&, _1).size(), // ARGC
  728. 0, // KWARGC
  729. true
  730. );
  731. }
  732. if(_0 == PY_OP_CALL){
  733. frame = &callstack.top();
  734. goto __NEXT_FRAME;
  735. }
  736. PUSH(_0);
  737. } DISPATCH()
  738. case OP_RETURN_VALUE:{
  739. PyVar _0 = byte.arg == BC_NOARG ? POPX() : None;
  740. __pop_frame();
  741. if(frame == base_frame){ // [ frameBase<- ]
  742. return _0;
  743. }else{
  744. frame = &callstack.top();
  745. PUSH(_0);
  746. goto __NEXT_FRAME;
  747. }
  748. } DISPATCH()
  749. case OP_YIELD_VALUE: return PY_OP_YIELD;
  750. /*****************************************/
  751. case OP_LIST_APPEND:{
  752. PyVar _0 = POPX();
  753. PK_OBJ_GET(List, SECOND()).push_back(_0);
  754. } DISPATCH()
  755. case OP_DICT_ADD: {
  756. PyVar _0 = POPX();
  757. const Tuple& t = PK_OBJ_GET(Tuple, _0);
  758. PK_OBJ_GET(Dict, SECOND()).set(this, t[0], t[1]);
  759. } DISPATCH()
  760. case OP_SET_ADD:{
  761. PyVar _0 = POPX();
  762. call_method(SECOND(), pk_id_add, _0);
  763. } DISPATCH()
  764. /*****************************************/
  765. case OP_UNARY_NEGATIVE:
  766. TOP() = py_negate(TOP());
  767. DISPATCH()
  768. case OP_UNARY_NOT:{
  769. PyVar _0 = TOP();
  770. if(_0==True) TOP()=False;
  771. else if(_0==False) TOP()=True;
  772. else TOP() = VAR(!py_bool(_0));
  773. } DISPATCH()
  774. case OP_UNARY_STAR:
  775. TOP() = VAR(StarWrapper(byte.arg, TOP()));
  776. DISPATCH()
  777. case OP_UNARY_INVERT:{
  778. PyVar _0;
  779. auto _ti = _tp_info(TOP());
  780. if(_ti->m__invert__) _0 = _ti->m__invert__(this, TOP());
  781. else _0 = call_method(TOP(), __invert__);
  782. TOP() = _0;
  783. } DISPATCH()
  784. /*****************************************/
  785. case OP_GET_ITER:
  786. TOP() = py_iter(TOP());
  787. DISPATCH()
  788. case OP_GET_ITER_NEW: {
  789. // This opcode always creates a temporary iterator object
  790. const PyTypeInfo* _ti = _tp_info(TOP());
  791. if(_ti->op__iter__){
  792. PyVar _0 = POPX();
  793. _ti->op__iter__(this, _0);
  794. }else{
  795. TOP() = py_iter(TOP());
  796. }
  797. DISPATCH()
  798. }
  799. case OP_FOR_ITER:{
  800. PyVar _0 = py_next(TOP());
  801. if(_0 == StopIteration){
  802. int target = frame->prepare_loop_break(&s_data);
  803. DISPATCH_JUMP_ABSOLUTE(target)
  804. } else{
  805. PUSH(_0);
  806. DISPATCH()
  807. }
  808. }
  809. case OP_FOR_ITER_STORE_FAST:{
  810. PyVar _0 = py_next(TOP());
  811. if(_0 == StopIteration){
  812. int target = frame->prepare_loop_break(&s_data);
  813. DISPATCH_JUMP_ABSOLUTE(target)
  814. }else{
  815. frame->_locals[byte.arg] = _0;
  816. DISPATCH()
  817. }
  818. }
  819. case OP_FOR_ITER_STORE_GLOBAL:{
  820. PyVar _0 = py_next(TOP());
  821. if(_0 == StopIteration){
  822. int target = frame->prepare_loop_break(&s_data);
  823. DISPATCH_JUMP_ABSOLUTE(target)
  824. }else{
  825. frame->f_globals().set(StrName(byte.arg), _0);
  826. DISPATCH()
  827. }
  828. }
  829. case OP_FOR_ITER_YIELD_VALUE:{
  830. PyVar _0 = py_next(TOP());
  831. if(_0 == StopIteration){
  832. int target = frame->prepare_loop_break(&s_data);
  833. DISPATCH_JUMP_ABSOLUTE(target)
  834. }else{
  835. PUSH(_0);
  836. return PY_OP_YIELD;
  837. }
  838. }
  839. case OP_FOR_ITER_UNPACK:{
  840. PyVar _0 = TOP();
  841. const PyTypeInfo* _ti = _tp_info(_0);
  842. if(_ti->op__next__){
  843. unsigned n = _ti->op__next__(this, _0);
  844. if(n == 0){
  845. // StopIteration
  846. int target = frame->prepare_loop_break(&s_data);
  847. DISPATCH_JUMP_ABSOLUTE(target)
  848. }else if(n == 1){
  849. // UNPACK_SEQUENCE
  850. __op_unpack_sequence(byte.arg);
  851. }else{
  852. if(n != byte.arg){
  853. ValueError(_S("expected ", (int)byte.arg, " values to unpack, got ", (int)n));
  854. }
  855. }
  856. }else{
  857. // FOR_ITER
  858. _0 = call_method(_0, __next__);
  859. if(_0 != StopIteration){
  860. PUSH(_0);
  861. // UNPACK_SEQUENCE
  862. __op_unpack_sequence(byte.arg);
  863. }else{
  864. int target = frame->prepare_loop_break(&s_data);
  865. DISPATCH_JUMP_ABSOLUTE(target)
  866. }
  867. }
  868. } DISPATCH()
  869. /*****************************************/
  870. case OP_IMPORT_PATH:{
  871. PyVar _0 = frame->co->consts[byte.arg];
  872. PUSH(py_import(CAST(Str&, _0)));
  873. } DISPATCH()
  874. case OP_POP_IMPORT_STAR: {
  875. PyVar _0 = POPX(); // pop the module
  876. PyVar _1 = _0->attr().try_get(__all__);
  877. StrName _name;
  878. if(_1 != nullptr){
  879. for(PyVar key: CAST(List&, _1)){
  880. _name = StrName::get(CAST(Str&, key).sv());
  881. PyVar value = _0->attr().try_get_likely_found(_name);
  882. if(value == nullptr){
  883. ImportError(_S("cannot import name ", _name.escape()));
  884. }else{
  885. frame->f_globals().set(_name, value);
  886. }
  887. }
  888. }else{
  889. for(auto& [name, value]: _0->attr().items()){
  890. std::string_view s = name.sv();
  891. if(s.empty() || s[0] == '_') continue;
  892. frame->f_globals().set(name, value);
  893. }
  894. }
  895. } DISPATCH()
  896. /*****************************************/
  897. case OP_UNPACK_SEQUENCE:{
  898. __op_unpack_sequence(byte.arg);
  899. } DISPATCH()
  900. case OP_UNPACK_EX: {
  901. auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
  902. PyVar _0 = py_iter(POPX());
  903. const PyTypeInfo* _ti = _tp_info(_0);
  904. PyVar _1;
  905. for(int i=0; i<byte.arg; i++){
  906. _1 = _py_next(_ti, _0);
  907. if(_1 == StopIteration) ValueError("not enough values to unpack");
  908. PUSH(_1);
  909. }
  910. List extras;
  911. while(true){
  912. _1 = _py_next(_ti, _0);
  913. if(_1 == StopIteration) break;
  914. extras.push_back(_1);
  915. }
  916. PUSH(VAR(extras));
  917. } DISPATCH()
  918. /*****************************************/
  919. case OP_BEGIN_CLASS:{
  920. StrName _name(byte.arg);
  921. PyVar _0 = POPX(); // super
  922. if(_0 == None) _0 = _t(tp_object);
  923. check_type(_0, tp_type);
  924. __curr_class = new_type_object(frame->_module, _name, PK_OBJ_GET(Type, _0), true);
  925. } DISPATCH()
  926. case OP_END_CLASS: {
  927. PK_ASSERT(__curr_class != nullptr);
  928. StrName _name(byte.arg);
  929. frame->_module->attr().set(_name, __curr_class);
  930. // call on_end_subclass
  931. PyTypeInfo* ti = &_all_types[__curr_class->as<Type>()];
  932. if(ti->base != tp_object){
  933. PyTypeInfo* base_ti = &_all_types[ti->base];
  934. if(base_ti->on_end_subclass) base_ti->on_end_subclass(this, ti);
  935. }
  936. __curr_class = nullptr;
  937. } DISPATCH()
  938. case OP_STORE_CLASS_ATTR:{
  939. PK_ASSERT(__curr_class != nullptr);
  940. StrName _name(byte.arg);
  941. PyVar _0 = POPX();
  942. if(is_type(_0, tp_function)){
  943. PK_OBJ_GET(Function, _0)._class = __curr_class;
  944. }
  945. __curr_class->attr().set(_name, _0);
  946. } DISPATCH()
  947. case OP_BEGIN_CLASS_DECORATION:{
  948. PUSH(__curr_class);
  949. } DISPATCH()
  950. case OP_END_CLASS_DECORATION:{
  951. __curr_class = POPX().get();
  952. } DISPATCH()
  953. case OP_ADD_CLASS_ANNOTATION: {
  954. PK_ASSERT(__curr_class != nullptr);
  955. StrName _name(byte.arg);
  956. Type type = __curr_class->as<Type>();
  957. _all_types[type].annotated_fields.push_back(_name);
  958. } DISPATCH()
  959. /*****************************************/
  960. case OP_WITH_ENTER:
  961. PUSH(call_method(TOP(), __enter__));
  962. DISPATCH()
  963. case OP_WITH_EXIT:
  964. call_method(TOP(), __exit__);
  965. POP();
  966. DISPATCH()
  967. /*****************************************/
  968. case OP_TRY_ENTER: {
  969. frame->set_unwind_target(s_data._sp);
  970. DISPATCH()
  971. }
  972. case OP_EXCEPTION_MATCH: {
  973. PyVar assumed_type = POPX();
  974. check_type(assumed_type, tp_type);
  975. PyVar e_obj = TOP();
  976. bool ok = isinstance(e_obj, PK_OBJ_GET(Type, assumed_type));
  977. PUSH(VAR(ok));
  978. } DISPATCH()
  979. case OP_RAISE: {
  980. if(is_type(TOP(), tp_type)){
  981. TOP() = call(TOP());
  982. }
  983. if(!isinstance(TOP(), tp_exception)){
  984. TypeError("exceptions must derive from Exception");
  985. }
  986. _error(POPX());
  987. } DISPATCH()
  988. case OP_RAISE_ASSERT:
  989. if(byte.arg){
  990. Str msg = py_str(TOP());
  991. POP();
  992. AssertionError(msg);
  993. }else{
  994. AssertionError();
  995. }
  996. DISPATCH()
  997. case OP_RE_RAISE: __raise_exc(true); DISPATCH()
  998. case OP_POP_EXCEPTION: __last_exception = POPX().get(); DISPATCH()
  999. /*****************************************/
  1000. case OP_FORMAT_STRING: {
  1001. PyVar _0 = POPX();
  1002. const Str& spec = CAST(Str&, frame->co->consts[byte.arg]);
  1003. PUSH(__format_object(_0, spec));
  1004. } DISPATCH()
  1005. /*****************************************/
  1006. case OP_INC_FAST:{
  1007. PyVar* p = &frame->_locals[byte.arg];
  1008. if(*p == PY_NULL) vm->NameError(frame->co->varnames[byte.arg]);
  1009. *p = VAR(CAST(i64, *p) + 1);
  1010. } DISPATCH()
  1011. case OP_DEC_FAST:{
  1012. PyVar* p = &frame->_locals[byte.arg];
  1013. if(*p == PY_NULL) vm->NameError(frame->co->varnames[byte.arg]);
  1014. *p = VAR(CAST(i64, *p) - 1);
  1015. } DISPATCH()
  1016. case OP_INC_GLOBAL:{
  1017. StrName _name(byte.arg);
  1018. PyVar* p = frame->f_globals().try_get_2_likely_found(_name);
  1019. if(p == nullptr) vm->NameError(_name);
  1020. *p = VAR(CAST(i64, *p) + 1);
  1021. } DISPATCH()
  1022. case OP_DEC_GLOBAL:{
  1023. StrName _name(byte.arg);
  1024. PyVar* p = frame->f_globals().try_get_2_likely_found(_name);
  1025. if(p == nullptr) vm->NameError(_name);
  1026. *p = VAR(CAST(i64, *p) - 1);
  1027. } DISPATCH()
  1028. /*****************************************/
  1029. default: PK_UNREACHABLE();
  1030. }
  1031. }
  1032. /**********************************************************************/
  1033. PK_UNREACHABLE();
  1034. }catch(InternalException internal){
  1035. __internal_exception = internal;
  1036. if(internal.type == InternalExceptionType::Unhandled){
  1037. PyVar e_obj = POPX();
  1038. Exception& _e = PK_OBJ_GET(Exception, e_obj);
  1039. bool is_base_frame_to_be_popped = frame == base_frame;
  1040. __pop_frame();
  1041. if(callstack.empty()) throw _e; // propagate to the top level
  1042. frame = &callstack.top();
  1043. PUSH(e_obj);
  1044. if(is_base_frame_to_be_popped){
  1045. throw InternalException(InternalExceptionType::ToBeRaised);
  1046. }
  1047. }
  1048. }
  1049. }
  1050. }
  1051. #undef TOP
  1052. #undef SECOND
  1053. #undef THIRD
  1054. #undef STACK_SHRINK
  1055. #undef PUSH
  1056. #undef POP
  1057. #undef POPX
  1058. #undef STACK_VIEW
  1059. #undef DISPATCH
  1060. #undef DISPATCH_JUMP
  1061. #undef CEVAL_STEP_CALLBACK
  1062. } // namespace pkpy