ceval.cpp 34 KB

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