ceval.h 18 KB

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