ceval.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #pragma once
  2. #include "vm.h"
  3. #include "ref.h"
  4. namespace pkpy{
  5. PyVar VM::run_frame(Frame* frame){
  6. while(frame->has_next_bytecode()){
  7. const Bytecode& byte = frame->next_bytecode();
  8. // if(true || frame->_module != builtins){
  9. // printf("%d: %s (%d) %s\n", frame->_ip, OP_NAMES[byte.op], byte.arg, frame->stack_info().c_str());
  10. // }
  11. switch (byte.op)
  12. {
  13. case OP_NO_OP: continue;
  14. case OP_SETUP_DECORATOR: continue;
  15. case OP_LOAD_CONST: frame->push(frame->co->consts[byte.arg]); continue;
  16. case OP_LOAD_FUNCTION: {
  17. const PyVar obj = frame->co->consts[byte.arg];
  18. Function f = CAST(Function, obj); // copy
  19. f._module = frame->_module;
  20. frame->push(VAR(f));
  21. } continue;
  22. case OP_SETUP_CLOSURE: {
  23. Function& f = CAST(Function&, frame->top()); // reference
  24. f._closure = frame->_locals;
  25. } continue;
  26. case OP_LOAD_NAME_REF: {
  27. frame->push(PyRef(NameRef(frame->co->names[byte.arg])));
  28. } continue;
  29. case OP_LOAD_NAME: {
  30. frame->push(NameRef(frame->co->names[byte.arg]).get(this, frame));
  31. } continue;
  32. case OP_STORE_NAME: {
  33. auto& p = frame->co->names[byte.arg];
  34. NameRef(p).set(this, frame, frame->pop());
  35. } continue;
  36. case OP_BUILD_ATTR_REF: case OP_BUILD_ATTR: {
  37. auto& attr = frame->co->names[byte.arg];
  38. PyVar obj = frame->pop_value(this);
  39. AttrRef ref = AttrRef(obj, NameRef(attr));
  40. if(byte.op == OP_BUILD_ATTR) frame->push(ref.get(this, frame));
  41. else frame->push(PyRef(ref));
  42. } continue;
  43. case OP_BUILD_INDEX: {
  44. PyVar index = frame->pop_value(this);
  45. auto ref = IndexRef(frame->pop_value(this), index);
  46. if(byte.arg > 0) frame->push(ref.get(this, frame));
  47. else frame->push(PyRef(ref));
  48. } continue;
  49. case OP_FAST_INDEX: case OP_FAST_INDEX_REF: {
  50. auto& a = frame->co->names[byte.arg & 0xFFFF];
  51. auto& x = frame->co->names[(byte.arg >> 16) & 0xFFFF];
  52. auto ref = IndexRef(NameRef(a).get(this, frame), NameRef(x).get(this, frame));
  53. if(byte.op == OP_FAST_INDEX) frame->push(ref.get(this, frame));
  54. else frame->push(PyRef(ref));
  55. } continue;
  56. case OP_ROT_TWO: ::std::swap(frame->top(), frame->top_1()); continue;
  57. case OP_STORE_REF: {
  58. // PyVar obj = frame->pop_value(this);
  59. // PyVarRef r = frame->pop();
  60. // PyRef_AS_C(r)->set(this, frame, std::move(obj));
  61. PyRef_AS_C(frame->top_1())->set(this, frame, frame->top_value(this));
  62. frame->_pop(); frame->_pop();
  63. } continue;
  64. case OP_DELETE_REF:
  65. PyRef_AS_C(frame->top())->del(this, frame);
  66. frame->_pop();
  67. continue;
  68. case OP_BUILD_TUPLE: {
  69. Args items = frame->pop_n_values_reversed(this, byte.arg);
  70. frame->push(VAR(std::move(items)));
  71. } continue;
  72. case OP_BUILD_TUPLE_REF: {
  73. Args items = frame->pop_n_reversed(byte.arg);
  74. frame->push(PyRef(TupleRef(std::move(items))));
  75. } continue;
  76. case OP_BUILD_STRING: {
  77. Args items = frame->pop_n_values_reversed(this, byte.arg);
  78. StrStream ss;
  79. for(int i=0; i<items.size(); i++) ss << CAST(Str, asStr(items[i]));
  80. frame->push(VAR(ss.str()));
  81. } continue;
  82. case OP_LOAD_EVAL_FN: frame->push(builtins->attr(m_eval)); continue;
  83. case OP_LIST_APPEND: {
  84. PyVar obj = frame->pop_value(this);
  85. List& list = CAST(List&, frame->top_1());
  86. list.push_back(std::move(obj));
  87. } continue;
  88. case OP_BEGIN_CLASS: {
  89. auto& name = frame->co->names[byte.arg];
  90. PyVar clsBase = frame->pop_value(this);
  91. if(clsBase == None) clsBase = _t(tp_object);
  92. check_type(clsBase, tp_type);
  93. PyVar cls = new_type_object(frame->_module, name.first, clsBase);
  94. frame->push(cls);
  95. } continue;
  96. case OP_END_CLASS: {
  97. PyVar cls = frame->pop();
  98. cls->attr()._try_perfect_rehash();
  99. }; continue;
  100. case OP_STORE_CLASS_ATTR: {
  101. auto& name = frame->co->names[byte.arg];
  102. PyVar obj = frame->pop_value(this);
  103. PyVar& cls = frame->top();
  104. cls->attr().set(name.first, std::move(obj));
  105. } continue;
  106. case OP_RETURN_VALUE: return frame->pop_value(this);
  107. case OP_PRINT_EXPR: {
  108. const PyVar expr = frame->top_value(this);
  109. if(expr != None) *_stdout << CAST(Str, asRepr(expr)) << '\n';
  110. } continue;
  111. case OP_POP_TOP: frame->_pop(); continue;
  112. case OP_BINARY_OP: {
  113. Args args(2);
  114. args[1] = frame->pop_value(this);
  115. args[0] = frame->top_value(this);
  116. frame->top() = fast_call(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
  117. } continue;
  118. case OP_BITWISE_OP: {
  119. Args args(2);
  120. args[1] = frame->pop_value(this);
  121. args[0] = frame->top_value(this);
  122. frame->top() = fast_call(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args));
  123. } continue;
  124. case OP_INPLACE_BINARY_OP: {
  125. Args args(2);
  126. args[1] = frame->pop();
  127. args[0] = frame->top_value(this);
  128. PyVar ret = fast_call(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
  129. PyRef_AS_C(frame->top())->set(this, frame, std::move(ret));
  130. frame->_pop();
  131. } continue;
  132. case OP_INPLACE_BITWISE_OP: {
  133. Args args(2);
  134. args[1] = frame->pop_value(this);
  135. args[0] = frame->top_value(this);
  136. PyVar ret = fast_call(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args));
  137. PyRef_AS_C(frame->top())->set(this, frame, std::move(ret));
  138. frame->_pop();
  139. } continue;
  140. case OP_COMPARE_OP: {
  141. Args args(2);
  142. args[1] = frame->pop_value(this);
  143. args[0] = frame->top_value(this);
  144. frame->top() = fast_call(CMP_SPECIAL_METHODS[byte.arg], std::move(args));
  145. } continue;
  146. case OP_IS_OP: {
  147. PyVar rhs = frame->pop_value(this);
  148. bool ret_c = rhs == frame->top_value(this);
  149. if(byte.arg == 1) ret_c = !ret_c;
  150. frame->top() = VAR(ret_c);
  151. } continue;
  152. case OP_CONTAINS_OP: {
  153. PyVar rhs = frame->pop_value(this);
  154. bool ret_c = CAST(bool, call(rhs, __contains__, one_arg(frame->pop_value(this))));
  155. if(byte.arg == 1) ret_c = !ret_c;
  156. frame->push(VAR(ret_c));
  157. } continue;
  158. case OP_UNARY_NEGATIVE:
  159. frame->top() = num_negated(frame->top_value(this));
  160. continue;
  161. case OP_UNARY_NOT: {
  162. PyVar obj = frame->pop_value(this);
  163. const PyVar& obj_bool = asBool(obj);
  164. frame->push(VAR(!_CAST(bool, obj_bool)));
  165. } continue;
  166. case OP_POP_JUMP_IF_FALSE:
  167. if(!_CAST(bool, asBool(frame->pop_value(this)))) frame->jump_abs(byte.arg);
  168. continue;
  169. case OP_LOAD_NONE: frame->push(None); continue;
  170. case OP_LOAD_TRUE: frame->push(True); continue;
  171. case OP_LOAD_FALSE: frame->push(False); continue;
  172. case OP_LOAD_ELLIPSIS: frame->push(Ellipsis); continue;
  173. case OP_ASSERT: {
  174. PyVar _msg = frame->pop_value(this);
  175. Str msg = CAST(Str, asStr(_msg));
  176. PyVar expr = frame->pop_value(this);
  177. if(asBool(expr) != True) _error("AssertionError", msg);
  178. } continue;
  179. case OP_EXCEPTION_MATCH: {
  180. const auto& e = CAST(Exception&, frame->top());
  181. StrName name = frame->co->names[byte.arg].first;
  182. frame->push(VAR(e.match_type(name)));
  183. } continue;
  184. case OP_RAISE: {
  185. PyVar obj = frame->pop_value(this);
  186. Str msg = obj == None ? "" : CAST(Str, asStr(obj));
  187. StrName type = frame->co->names[byte.arg].first;
  188. _error(type, msg);
  189. } continue;
  190. case OP_RE_RAISE: _raise(); continue;
  191. case OP_BUILD_LIST:
  192. frame->push(VAR(frame->pop_n_values_reversed(this, byte.arg).move_to_list()));
  193. continue;
  194. case OP_BUILD_MAP: {
  195. Args items = frame->pop_n_values_reversed(this, byte.arg*2);
  196. PyVar obj = call(builtins->attr("dict"));
  197. for(int i=0; i<items.size(); i+=2){
  198. call(obj, __setitem__, two_args(items[i], items[i+1]));
  199. }
  200. frame->push(obj);
  201. } continue;
  202. case OP_BUILD_SET: {
  203. PyVar list = VAR(
  204. frame->pop_n_values_reversed(this, byte.arg).move_to_list()
  205. );
  206. PyVar obj = call(builtins->attr("set"), one_arg(list));
  207. frame->push(obj);
  208. } continue;
  209. case OP_DUP_TOP_VALUE: frame->push(frame->top_value(this)); continue;
  210. case OP_UNARY_STAR: {
  211. if(byte.arg > 0){ // rvalue
  212. frame->top() = VAR(StarWrapper(frame->top_value(this), true));
  213. }else{
  214. PyRef_AS_C(frame->top()); // check ref
  215. frame->top() = VAR(StarWrapper(frame->top(), false));
  216. }
  217. } continue;
  218. case OP_CALL_KWARGS_UNPACK: case OP_CALL_KWARGS: {
  219. int ARGC = byte.arg & 0xFFFF;
  220. int KWARGC = (byte.arg >> 16) & 0xFFFF;
  221. Args kwargs = frame->pop_n_values_reversed(this, KWARGC*2);
  222. Args args = frame->pop_n_values_reversed(this, ARGC);
  223. if(byte.op == OP_CALL_KWARGS_UNPACK) unpack_args(args);
  224. PyVar callable = frame->pop_value(this);
  225. PyVar ret = call(callable, std::move(args), kwargs, true);
  226. if(ret == _py_op_call) return ret;
  227. frame->push(std::move(ret));
  228. } continue;
  229. case OP_CALL_UNPACK: case OP_CALL: {
  230. Args args = frame->pop_n_values_reversed(this, byte.arg);
  231. if(byte.op == OP_CALL_UNPACK) unpack_args(args);
  232. PyVar callable = frame->pop_value(this);
  233. PyVar ret = call(callable, std::move(args), no_arg(), true);
  234. if(ret == _py_op_call) return ret;
  235. frame->push(std::move(ret));
  236. } continue;
  237. case OP_JUMP_ABSOLUTE: frame->jump_abs(byte.arg); continue;
  238. case OP_SAFE_JUMP_ABSOLUTE: frame->jump_abs_safe(byte.arg); continue;
  239. case OP_GOTO: {
  240. StrName label = frame->co->names[byte.arg].first;
  241. auto it = frame->co->labels.find(label);
  242. if(it == frame->co->labels.end()) _error("KeyError", "label " + label.str().escape(true) + " not found");
  243. frame->jump_abs_safe(it->second);
  244. } continue;
  245. case OP_GET_ITER: {
  246. PyVar obj = frame->pop_value(this);
  247. PyVar iter = asIter(obj);
  248. check_type(frame->top(), tp_ref);
  249. PyIter_AS_C(iter)->loop_var = frame->pop();
  250. frame->push(std::move(iter));
  251. } continue;
  252. case OP_FOR_ITER: {
  253. BaseIter* it = PyIter_AS_C(frame->top());
  254. PyVar obj = it->next();
  255. if(obj != nullptr){
  256. PyRef_AS_C(it->loop_var)->set(this, frame, std::move(obj));
  257. }else{
  258. int blockEnd = frame->co->blocks[byte.block].end;
  259. frame->jump_abs_safe(blockEnd);
  260. }
  261. } continue;
  262. case OP_LOOP_CONTINUE: {
  263. int blockStart = frame->co->blocks[byte.block].start;
  264. frame->jump_abs(blockStart);
  265. } continue;
  266. case OP_LOOP_BREAK: {
  267. int blockEnd = frame->co->blocks[byte.block].end;
  268. frame->jump_abs_safe(blockEnd);
  269. } continue;
  270. case OP_JUMP_IF_FALSE_OR_POP: {
  271. const PyVar expr = frame->top_value(this);
  272. if(asBool(expr)==False) frame->jump_abs(byte.arg);
  273. else frame->pop_value(this);
  274. } continue;
  275. case OP_JUMP_IF_TRUE_OR_POP: {
  276. const PyVar expr = frame->top_value(this);
  277. if(asBool(expr)==True) frame->jump_abs(byte.arg);
  278. else frame->pop_value(this);
  279. } continue;
  280. case OP_BUILD_SLICE: {
  281. PyVar stop = frame->pop_value(this);
  282. PyVar start = frame->pop_value(this);
  283. Slice s;
  284. if(start != None) { s.start = CAST(int, start);}
  285. if(stop != None) { s.stop = CAST(int, stop);}
  286. frame->push(VAR(s));
  287. } continue;
  288. case OP_IMPORT_NAME: {
  289. StrName name = frame->co->names[byte.arg].first;
  290. PyVar* ext_mod = _modules.try_get(name);
  291. if(ext_mod == nullptr){
  292. auto it2 = _lazy_modules.find(name);
  293. if(it2 == _lazy_modules.end()){
  294. _error("ImportError", "module " + name.str().escape(true) + " not found");
  295. }else{
  296. const Str& source = it2->second;
  297. CodeObject_ code = compile(source, name.str(), EXEC_MODE);
  298. PyVar new_mod = new_module(name);
  299. _exec(code, new_mod);
  300. frame->push(new_mod);
  301. _lazy_modules.erase(it2);
  302. new_mod->attr()._try_perfect_rehash();
  303. }
  304. }else{
  305. frame->push(*ext_mod);
  306. }
  307. } continue;
  308. case OP_STORE_ALL_NAMES: {
  309. PyVar obj = frame->pop_value(this);
  310. for(auto& [name, value]: obj->attr().items()){
  311. Str s = name.str();
  312. if(s.empty() || s[0] == '_') continue;
  313. frame->f_globals().set(name, value);
  314. }
  315. }; continue;
  316. case OP_YIELD_VALUE: return _py_op_yield;
  317. // TODO: using "goto" inside with block may cause __exit__ not called
  318. case OP_WITH_ENTER: call(frame->pop_value(this), __enter__); continue;
  319. case OP_WITH_EXIT: call(frame->pop_value(this), __exit__); continue;
  320. case OP_TRY_BLOCK_ENTER: frame->on_try_block_enter(); continue;
  321. case OP_TRY_BLOCK_EXIT: frame->on_try_block_exit(); continue;
  322. default: throw std::runtime_error(Str("opcode ") + OP_NAMES[byte.op] + " is not implemented");
  323. }
  324. }
  325. if(frame->co->src->mode == EVAL_MODE || frame->co->src->mode == JSON_MODE){
  326. if(frame->_data.size() != 1) throw std::runtime_error("_data.size() != 1 in EVAL/JSON_MODE");
  327. return frame->pop_value(this);
  328. }
  329. #if PK_EXTRA_CHECK
  330. if(!frame->_data.empty()) throw std::runtime_error("_data.size() != 0 in EXEC_MODE");
  331. #endif
  332. return None;
  333. }
  334. } // namespace pkpy