ceval.cpp 34 KB

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