ceval.cpp 36 KB

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