vm.h 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148
  1. #pragma once
  2. #include "codeobject.h"
  3. #include "iter.h"
  4. #include "error.h"
  5. #define __DEF_PY_AS_C(type, ctype, ptype) \
  6. inline ctype& Py##type##_AS_C(const PyVar& obj) { \
  7. __checkType(obj, ptype); \
  8. return std::get<ctype>(obj->_native); \
  9. }
  10. #define __DEF_PY(type, ctype, ptype) \
  11. inline PyVar Py##type(ctype value) { \
  12. return newObject(ptype, value); \
  13. }
  14. #define DEF_NATIVE(type, ctype, ptype) \
  15. __DEF_PY(type, ctype, ptype) \
  16. __DEF_PY_AS_C(type, ctype, ptype)
  17. #define __DEF_PY_POOL(name, ctype, ptype, max_size) \
  18. std::vector<PyObject*> _pool##name; \
  19. PyVar Py##name(ctype _native) { \
  20. PyObject* _raw = nullptr; \
  21. if(_pool##name.size() > 0) { \
  22. _raw = _pool##name.back(); \
  23. _raw->_native = std::move(_native); \
  24. _pool##name.pop_back(); \
  25. }else{ \
  26. __checkType(ptype, _tp_type); \
  27. _raw = new PyObject(std::move(_native));\
  28. _raw->setType(ptype); \
  29. } \
  30. return PyVar(_raw, [this](PyObject* p){ \
  31. if(_pool##name.size() < max_size){ \
  32. _pool##name.push_back(p); \
  33. }else{ \
  34. delete p; \
  35. } \
  36. }); \
  37. }
  38. typedef void(*PrintFn)(const VM*, const char*);
  39. class VM: public PkExportedResource{
  40. protected:
  41. std::deque< std::unique_ptr<Frame> > callstack;
  42. PyVarDict _modules; // 3rd modules
  43. PyVar __py2py_call_signal;
  44. PyVar runFrame(Frame* frame){
  45. while(!frame->isCodeEnd()){
  46. const ByteCode& byte = frame->readCode();
  47. //printf("%s (%d) stack_size: %d\n", OP_NAMES[byte.op], byte.arg, frame->stackSize());
  48. switch (byte.op)
  49. {
  50. case OP_NO_OP: break; // do nothing
  51. case OP_LOAD_CONST: frame->push(frame->code->co_consts[byte.arg]); break;
  52. case OP_LOAD_LAMBDA: {
  53. PyVar obj = frame->code->co_consts[byte.arg];
  54. setAttr(obj, __module__, frame->_module);
  55. frame->push(obj);
  56. } break;
  57. case OP_LOAD_NAME_PTR: {
  58. frame->push(PyPointer(frame->code->co_names[byte.arg]));
  59. } break;
  60. case OP_STORE_NAME_PTR: {
  61. const auto& p = frame->code->co_names[byte.arg];
  62. p->set(this, frame, frame->popValue(this));
  63. } break;
  64. case OP_BUILD_ATTR_PTR: {
  65. const auto& attr = frame->code->co_names[byte.arg];
  66. PyVar obj = frame->popValue(this);
  67. frame->push(PyPointer(std::make_shared<AttrPointer>(obj, attr.get())));
  68. } break;
  69. case OP_BUILD_ATTR_PTR_PTR: {
  70. const auto& attr = frame->code->co_names[byte.arg];
  71. PyVar obj = frame->popValue(this);
  72. __checkType(obj, _tp_user_pointer);
  73. const _Pointer& p = std::get<_Pointer>(obj->_native);
  74. frame->push(PyPointer(std::make_shared<AttrPointer>(p->get(this, frame), attr.get())));
  75. } break;
  76. case OP_BUILD_INDEX_PTR: {
  77. PyVar index = frame->popValue(this);
  78. PyVar obj = frame->popValue(this);
  79. frame->push(PyPointer(std::make_shared<IndexPointer>(obj, index)));
  80. } break;
  81. case OP_STORE_PTR: {
  82. PyVar obj = frame->popValue(this);
  83. const _Pointer& p = PyPointer_AS_C(frame->__pop());
  84. p->set(this, frame, std::move(obj));
  85. } break;
  86. case OP_DELETE_PTR: {
  87. const _Pointer& p = PyPointer_AS_C(frame->__pop());
  88. p->del(this, frame);
  89. } break;
  90. case OP_BUILD_SMART_TUPLE:
  91. {
  92. PyVarList items = frame->__popNReversed(byte.arg);
  93. bool done = false;
  94. for(auto& item : items){
  95. if(!item->isType(_tp_pointer)) {
  96. done = true;
  97. PyVarList values(items.size());
  98. for(int i=0; i<items.size(); i++){
  99. values[i] = frame->__deref_pointer(this, items[i]);
  100. }
  101. frame->push(PyTuple(values));
  102. break;
  103. }
  104. }
  105. if(done) break;
  106. std::vector<_Pointer> pointers(items.size());
  107. for(int i=0; i<items.size(); i++)
  108. pointers[i] = PyPointer_AS_C(items[i]);
  109. frame->push(PyPointer(std::make_shared<CompoundPointer>(pointers)));
  110. } break;
  111. case OP_BUILD_STRING:
  112. {
  113. PyVarList items = frame->popNValuesReversed(this, byte.arg);
  114. _StrStream ss;
  115. for(const auto& i : items) ss << PyStr_AS_C(asStr(i));
  116. frame->push(PyStr(ss.str()));
  117. } break;
  118. case OP_LOAD_EVAL_FN: {
  119. frame->push(builtins->attribs["eval"_c]);
  120. } break;
  121. case OP_LIST_APPEND: {
  122. pkpy::ArgList args(2);
  123. args[1] = frame->popValue(this); // obj
  124. args[0] = frame->__topValueN(this, -2); // list
  125. fastCall(args[0], "append"_c, std::move(args));
  126. } break;
  127. case OP_STORE_FUNCTION:
  128. {
  129. PyVar obj = frame->popValue(this);
  130. const _Func& fn = PyFunction_AS_C(obj);
  131. setAttr(obj, __module__, frame->_module);
  132. frame->f_globals()[fn->name] = obj;
  133. } break;
  134. case OP_BUILD_CLASS:
  135. {
  136. const _Str& clsName = frame->code->co_names[byte.arg]->name;
  137. PyVar clsBase = frame->popValue(this);
  138. if(clsBase == None) clsBase = _tp_object;
  139. __checkType(clsBase, _tp_type);
  140. PyVar cls = newUserClassType(clsName, clsBase);
  141. while(true){
  142. PyVar fn = frame->popValue(this);
  143. if(fn == None) break;
  144. const _Func& f = PyFunction_AS_C(fn);
  145. setAttr(fn, __module__, frame->_module);
  146. setAttr(cls, f->name, fn);
  147. }
  148. frame->f_globals()[clsName] = cls;
  149. } break;
  150. case OP_RETURN_VALUE: return frame->popValue(this);
  151. case OP_PRINT_EXPR:
  152. {
  153. const PyVar& expr = frame->topValue(this);
  154. if(expr == None) break;
  155. *_stdout << PyStr_AS_C(asRepr(expr)) << '\n';
  156. } break;
  157. case OP_POP_TOP: frame->popValue(this); break;
  158. case OP_BINARY_OP:
  159. {
  160. pkpy::ArgList args(2);
  161. args[1] = frame->popValue(this);
  162. args[0] = frame->popValue(this);
  163. frame->push(fastCall(args[0], BINARY_SPECIAL_METHODS[byte.arg], std::move(args)));
  164. } break;
  165. case OP_BITWISE_OP:
  166. {
  167. pkpy::ArgList args(2);
  168. args[1] = frame->popValue(this);
  169. args[0] = frame->popValue(this);
  170. frame->push(fastCall(args[0], BITWISE_SPECIAL_METHODS[byte.arg], std::move(args)));
  171. } break;
  172. case OP_COMPARE_OP:
  173. {
  174. pkpy::ArgList args(2);
  175. args[1] = frame->popValue(this);
  176. args[0] = frame->popValue(this);
  177. // for __ne__ we use the negation of __eq__
  178. int op = byte.arg == 3 ? 2 : byte.arg;
  179. PyVar res = fastCall(args[0], CMP_SPECIAL_METHODS[op], std::move(args));
  180. if(op != byte.arg) res = PyBool(!PyBool_AS_C(res));
  181. frame->push(std::move(res));
  182. } break;
  183. case OP_IS_OP:
  184. {
  185. bool ret_c = frame->popValue(this) == frame->popValue(this);
  186. if(byte.arg == 1) ret_c = !ret_c;
  187. frame->push(PyBool(ret_c));
  188. } break;
  189. case OP_CONTAINS_OP:
  190. {
  191. PyVar rhs = frame->popValue(this);
  192. PyVar lhs = frame->popValue(this);
  193. bool ret_c = PyBool_AS_C(call(std::move(rhs), __contains__, {std::move(lhs)}));
  194. if(byte.arg == 1) ret_c = !ret_c;
  195. frame->push(PyBool(ret_c));
  196. } break;
  197. case OP_UNARY_NEGATIVE:
  198. {
  199. PyVar obj = frame->popValue(this);
  200. frame->push(numNegated(obj));
  201. } break;
  202. case OP_UNARY_NOT:
  203. {
  204. PyVar obj = frame->popValue(this);
  205. const PyVar& obj_bool = asBool(obj);
  206. frame->push(PyBool(!PyBool_AS_C(obj_bool)));
  207. } break;
  208. case OP_UNARY_REF:
  209. {
  210. // _pointer to pointer
  211. const _Pointer& p = PyPointer_AS_C(frame->__pop());
  212. _Pointer up = std::make_shared<UserPointer>(p, frame->id);
  213. frame->push(newObject(_tp_user_pointer, std::move(up)));
  214. } break;
  215. case OP_UNARY_DEREF:
  216. {
  217. // pointer to _pointer
  218. PyVar obj = frame->popValue(this);
  219. __checkType(obj, _tp_user_pointer);
  220. frame->push(PyPointer(std::get<_Pointer>(obj->_native)));
  221. } break;
  222. case OP_POP_JUMP_IF_FALSE:
  223. if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg);
  224. break;
  225. case OP_LOAD_NONE: frame->push(None); break;
  226. case OP_LOAD_TRUE: frame->push(True); break;
  227. case OP_LOAD_FALSE: frame->push(False); break;
  228. case OP_LOAD_ELLIPSIS: frame->push(Ellipsis); break;
  229. case OP_ASSERT:
  230. {
  231. PyVar expr = frame->popValue(this);
  232. _assert(PyBool_AS_C(expr), "assertion failed");
  233. } break;
  234. case OP_RAISE_ERROR:
  235. {
  236. _Str msg = PyStr_AS_C(asRepr(frame->popValue(this)));
  237. _Str type = PyStr_AS_C(frame->popValue(this));
  238. _error(type, msg);
  239. } break;
  240. case OP_BUILD_LIST:
  241. {
  242. PyVarList items = frame->popNValuesReversed(this, byte.arg);
  243. frame->push(PyList(items));
  244. } break;
  245. case OP_BUILD_MAP:
  246. {
  247. PyVarList items = frame->popNValuesReversed(this, byte.arg*2);
  248. PyVar obj = call(builtins->attribs["dict"], {});
  249. for(int i=0; i<items.size(); i+=2){
  250. call(obj, __setitem__, {items[i], items[i+1]});
  251. }
  252. frame->push(obj);
  253. } break;
  254. case OP_DUP_TOP: frame->push(frame->topValue(this)); break;
  255. case OP_CALL:
  256. {
  257. PyVarList args = frame->popNValuesReversed(this, byte.arg);
  258. PyVar callable = frame->popValue(this);
  259. PyVar ret = call(std::move(callable), std::move(args), true);
  260. if(ret == __py2py_call_signal) return ret;
  261. frame->push(std::move(ret));
  262. } break;
  263. case OP_JUMP_ABSOLUTE: frame->jump(byte.arg); break;
  264. case OP_SAFE_JUMP_ABSOLUTE: frame->safeJump(byte.arg); break;
  265. case OP_GOTO: {
  266. PyVar obj = frame->popValue(this);
  267. const _Str& label = PyStr_AS_C(obj);
  268. auto it = frame->code->co_labels.find(label);
  269. if(it == frame->code->co_labels.end()){
  270. _error("KeyError", "label '" + label + "' not found");
  271. }
  272. frame->safeJump(it->second);
  273. } break;
  274. case OP_GET_ITER:
  275. {
  276. PyVar obj = frame->popValue(this);
  277. PyVarOrNull iter_fn = getAttr(obj, __iter__, false);
  278. if(iter_fn != nullptr){
  279. PyVar tmp = call(iter_fn, {obj});
  280. PyIter_AS_C(tmp)->var = std::move(PyPointer_AS_C(frame->__pop()));
  281. frame->push(std::move(tmp));
  282. }else{
  283. typeError("'" + obj->getTypeName() + "' object is not iterable");
  284. }
  285. } break;
  286. case OP_FOR_ITER:
  287. {
  288. frame->__reportForIter();
  289. // __top() must be PyIter, so no need to __deref()
  290. auto& it = PyIter_AS_C(frame->__top());
  291. if(it->hasNext()){
  292. it->var->set(this, frame, it->next());
  293. }
  294. else{
  295. frame->safeJump(byte.arg);
  296. }
  297. } break;
  298. case OP_JUMP_IF_FALSE_OR_POP:
  299. {
  300. const PyVar& expr = frame->topValue(this);
  301. if(asBool(expr)==False) frame->jump(byte.arg);
  302. else frame->popValue(this);
  303. } break;
  304. case OP_JUMP_IF_TRUE_OR_POP:
  305. {
  306. const PyVar& expr = frame->topValue(this);
  307. if(asBool(expr)==True) frame->jump(byte.arg);
  308. else frame->popValue(this);
  309. } break;
  310. case OP_BUILD_SLICE:
  311. {
  312. PyVar stop = frame->popValue(this);
  313. PyVar start = frame->popValue(this);
  314. _Slice s;
  315. if(start != None) {__checkType(start, _tp_int); s.start = PyInt_AS_C(start);}
  316. if(stop != None) {__checkType(stop, _tp_int); s.stop = PyInt_AS_C(stop);}
  317. frame->push(PySlice(s));
  318. } break;
  319. case OP_IMPORT_NAME:
  320. {
  321. const _Str& name = frame->code->co_names[byte.arg]->name;
  322. auto it = _modules.find(name);
  323. if(it == _modules.end()) _error("ImportError", "module '" + name + "' not found");
  324. else frame->push(it->second);
  325. } break;
  326. default:
  327. systemError(_Str("opcode ") + OP_NAMES[byte.op] + " is not implemented");
  328. break;
  329. }
  330. }
  331. if(frame->code->src->mode == EVAL_MODE) {
  332. if(frame->stackSize() != 1) systemError("stack size is not 1 in EVAL_MODE");
  333. return frame->popValue(this);
  334. }
  335. if(frame->stackSize() != 0) systemError("stack not empty in EXEC_MODE");
  336. return None;
  337. }
  338. public:
  339. PyVarDict _types;
  340. PyVar None, True, False, Ellipsis;
  341. bool use_stdio;
  342. std::ostream* _stdout;
  343. std::ostream* _stderr;
  344. PyVar builtins; // builtins module
  345. PyVar _main; // __main__ module
  346. int maxRecursionDepth = 1000;
  347. VM(bool use_stdio){
  348. this->use_stdio = use_stdio;
  349. if(use_stdio){
  350. std::cout.setf(std::ios::unitbuf);
  351. std::cerr.setf(std::ios::unitbuf);
  352. this->_stdout = &std::cout;
  353. this->_stderr = &std::cerr;
  354. }else{
  355. this->_stdout = new _StrStream();
  356. this->_stderr = new _StrStream();
  357. }
  358. initializeBuiltinClasses();
  359. }
  360. PyVar asStr(const PyVar& obj){
  361. PyVarOrNull str_fn = getAttr(obj, __str__, false);
  362. if(str_fn != nullptr) return call(str_fn, {});
  363. return asRepr(obj);
  364. }
  365. Frame* __findFrame(uint64_t up_f_id){
  366. for(auto it=callstack.crbegin(); it!=callstack.crend(); ++it){
  367. uint64_t f_id = it->get()->id;
  368. if(f_id == up_f_id) return it->get();
  369. if(f_id < up_f_id) return nullptr;
  370. }
  371. return nullptr;
  372. }
  373. Frame* topFrame(){
  374. if(callstack.size() == 0) UNREACHABLE();
  375. return callstack.back().get();
  376. }
  377. PyVar asRepr(const PyVar& obj){
  378. if(obj->isType(_tp_type)) return PyStr("<class '" + obj->getName() + "'>");
  379. return call(obj, __repr__, {});
  380. }
  381. PyVar asJson(const PyVar& obj){
  382. return call(obj, __json__, {});
  383. }
  384. const PyVar& asBool(const PyVar& obj){
  385. if(obj == None) return False;
  386. if(obj->_type == _tp_bool) return obj;
  387. if(obj->_type == _tp_int) return PyBool(PyInt_AS_C(obj) != 0);
  388. if(obj->_type == _tp_float) return PyBool(PyFloat_AS_C(obj) != 0.0);
  389. PyVarOrNull len_fn = getAttr(obj, __len__, false);
  390. if(len_fn != nullptr){
  391. PyVar ret = call(std::move(len_fn), {});
  392. return PyBool(PyInt_AS_C(ret) > 0);
  393. }
  394. return True;
  395. }
  396. PyVar fastCall(const PyVar& obj, const _Str& name, pkpy::ArgList&& args){
  397. PyObject* cls = obj->_type.get();
  398. while(cls != None.get()) {
  399. auto it = cls->attribs.find(name);
  400. if(it != cls->attribs.end()){
  401. return call(it->second, args);
  402. }
  403. cls = cls->attribs[__base__].get();
  404. }
  405. attributeError(obj, name);
  406. return nullptr;
  407. }
  408. PyVar call(const PyVar& _callable, pkpy::ArgList args, bool opCall=false){
  409. if(_callable->isType(_tp_type)){
  410. auto it = _callable->attribs.find(__new__);
  411. PyVar obj;
  412. if(it != _callable->attribs.end()){
  413. obj = call(it->second, args);
  414. }else{
  415. obj = newObject(_callable, (_Int)-1);
  416. }
  417. if(obj->isType(_callable)){
  418. PyVarOrNull init_fn = getAttr(obj, __init__, false);
  419. if (init_fn != nullptr) call(init_fn, args);
  420. }
  421. return obj;
  422. }
  423. const PyVar* callable = &_callable;
  424. if((*callable)->isType(_tp_bounded_method)){
  425. auto& bm = PyBoundedMethod_AS_C((*callable));
  426. // TODO: avoid insertion here, bad performance
  427. pkpy::ArgList new_args(args.size()+1);
  428. new_args[0] = bm.obj;
  429. for(int i=0; i<args.size(); i++) new_args[i+1] = args[i];
  430. callable = &bm.method;
  431. args = std::move(new_args);
  432. }
  433. if((*callable)->isType(_tp_native_function)){
  434. const auto& f = std::get<_CppFunc>((*callable)->_native);
  435. return f(this, args);
  436. } else if((*callable)->isType(_tp_function)){
  437. const _Func& fn = PyFunction_AS_C((*callable));
  438. PyVarDict locals;
  439. int i = 0;
  440. for(const auto& name : fn->args){
  441. if(i < args.size()) {
  442. locals[name] = args[i++];
  443. }else{
  444. typeError("missing positional argument '" + name + "'");
  445. }
  446. }
  447. // handle *args
  448. if(!fn->starredArg.empty()){
  449. PyVarList vargs;
  450. while(i < args.size()) vargs.push_back(args[i++]);
  451. locals[fn->starredArg] = PyTuple(vargs);
  452. }
  453. // handle keyword arguments
  454. for(const _Str& name : fn->kwArgsOrder){
  455. if(i < args.size()) {
  456. locals[name] = args[i++];
  457. }else{
  458. locals[name] = fn->kwArgs[name];
  459. }
  460. }
  461. if(i < args.size()) typeError("too many arguments");
  462. auto it_m = (*callable)->attribs.find(__module__);
  463. PyVar _module = it_m != (*callable)->attribs.end() ? it_m->second : topFrame()->_module;
  464. if(opCall){
  465. __pushNewFrame(fn->code, _module, locals);
  466. return __py2py_call_signal;
  467. }
  468. return _exec(fn->code, _module, locals);
  469. }
  470. typeError("'" + (*callable)->getTypeName() + "' object is not callable");
  471. return None;
  472. }
  473. inline PyVar call(const PyVar& obj, const _Str& func, const pkpy::ArgList& args){
  474. return call(getAttr(obj, func), args);
  475. }
  476. inline PyVar call(const PyVar& obj, const _Str& func, pkpy::ArgList&& args){
  477. return call(getAttr(obj, func), args);
  478. }
  479. // repl mode is only for setting `frame->id` to 0
  480. virtual PyVarOrNull exec(const _Code& code, PyVar _module=nullptr){
  481. if(_module == nullptr) _module = _main;
  482. try {
  483. return _exec(code, _module, {});
  484. } catch (const std::exception& e) {
  485. if(const _Error* _ = dynamic_cast<const _Error*>(&e)){
  486. *_stderr << e.what() << '\n';
  487. }else{
  488. auto re = RuntimeError("UnexpectedError", e.what(), _cleanErrorAndGetSnapshots());
  489. *_stderr << re.what() << '\n';
  490. }
  491. return nullptr;
  492. }
  493. }
  494. virtual void execAsync(const _Code& code) {
  495. exec(code);
  496. }
  497. Frame* __pushNewFrame(const _Code& code, PyVar _module, const PyVarDict& locals){
  498. if(code == nullptr) UNREACHABLE();
  499. if(callstack.size() > maxRecursionDepth){
  500. throw RuntimeError("RecursionError", "maximum recursion depth exceeded", _cleanErrorAndGetSnapshots());
  501. }
  502. Frame* frame = new Frame(code.get(), _module, locals);
  503. callstack.emplace_back(std::unique_ptr<Frame>(frame));
  504. return frame;
  505. }
  506. PyVar _exec(const _Code& code, PyVar _module, const PyVarDict& locals){
  507. Frame* frame = __pushNewFrame(code, _module, locals);
  508. if(code->mode() == SINGLE_MODE) frame->id = 0;
  509. Frame* frameBase = frame;
  510. PyVar ret = nullptr;
  511. while(true){
  512. ret = runFrame(frame);
  513. if(ret != __py2py_call_signal){
  514. if(frame == frameBase){ // [ frameBase<- ]
  515. break;
  516. }else{
  517. callstack.pop_back();
  518. frame = callstack.back().get();
  519. frame->push(ret);
  520. }
  521. }else{
  522. frame = callstack.back().get(); // [ frameBase, newFrame<- ]
  523. }
  524. }
  525. callstack.pop_back();
  526. return ret;
  527. }
  528. PyVar newUserClassType(_Str name, PyVar base){
  529. PyVar obj = newClassType(name, base);
  530. setAttr(obj, __name__, PyStr(name));
  531. _types.erase(name);
  532. return obj;
  533. }
  534. PyVar newClassType(_Str name, PyVar base=nullptr) {
  535. if(base == nullptr) base = _tp_object;
  536. PyVar obj = std::make_shared<PyObject>((_Int)0);
  537. obj->setType(_tp_type);
  538. setAttr(obj, __base__, base);
  539. _types[name] = obj;
  540. return obj;
  541. }
  542. PyVar newObject(PyVar type, _Value _native) {
  543. __checkType(type, _tp_type);
  544. PyVar obj = std::make_shared<PyObject>(_native);
  545. obj->setType(type);
  546. return obj;
  547. }
  548. PyVar newModule(_Str name, bool saveToPath=true) {
  549. PyVar obj = newObject(_tp_module, (_Int)-2);
  550. setAttr(obj, __name__, PyStr(name));
  551. if(saveToPath) _modules[name] = obj;
  552. return obj;
  553. }
  554. PyVarOrNull getAttr(const PyVar& obj, const _Str& name, bool throw_err=true) {
  555. PyVarDict::iterator it;
  556. PyObject* cls;
  557. if(obj->isType(_tp_super)){
  558. const PyVar* root = &obj;
  559. int depth = 1;
  560. while(true){
  561. root = &std::get<PyVar>((*root)->_native);
  562. if(!(*root)->isType(_tp_super)) break;
  563. depth++;
  564. }
  565. cls = (*root)->_type.get();
  566. for(int i=0; i<depth; i++) cls = cls->attribs[__base__].get();
  567. it = (*root)->attribs.find(name);
  568. if(it != (*root)->attribs.end()) return it->second;
  569. }else{
  570. it = obj->attribs.find(name);
  571. if(it != obj->attribs.end()) return it->second;
  572. cls = obj->_type.get();
  573. }
  574. while(cls != None.get()) {
  575. it = cls->attribs.find(name);
  576. if(it != cls->attribs.end()){
  577. PyVar valueFromCls = it->second;
  578. if(valueFromCls->isType(_tp_function) || valueFromCls->isType(_tp_native_function)){
  579. return PyBoundedMethod({obj, std::move(valueFromCls)});
  580. }else{
  581. return valueFromCls;
  582. }
  583. }
  584. cls = cls->attribs[__base__].get();
  585. }
  586. if(throw_err) attributeError(obj, name);
  587. return nullptr;
  588. }
  589. inline void setAttr(PyVar& obj, const _Str& name, const PyVar& value) {
  590. if(obj->isType(_tp_super)){
  591. const PyVar* root = &obj;
  592. while(true){
  593. root = &std::get<PyVar>((*root)->_native);
  594. if(!(*root)->isType(_tp_super)) break;
  595. }
  596. (*root)->attribs[name] = value;
  597. }else{
  598. obj->attribs[name] = value;
  599. }
  600. }
  601. inline void setAttr(PyVar& obj, const _Str& name, PyVar&& value) {
  602. if(obj->isType(_tp_super)){
  603. const PyVar* root = &obj;
  604. while(true){
  605. root = &std::get<PyVar>((*root)->_native);
  606. if(!(*root)->isType(_tp_super)) break;
  607. }
  608. (*root)->attribs[name] = std::move(value);
  609. }else{
  610. obj->attribs[name] = std::move(value);
  611. }
  612. }
  613. void bindMethod(_Str typeName, _Str funcName, _CppFunc fn) {
  614. funcName.intern();
  615. PyVar type = _types[typeName];
  616. PyVar func = PyNativeFunction(fn);
  617. setAttr(type, funcName, func);
  618. }
  619. void bindMethodMulti(std::vector<_Str> typeNames, _Str funcName, _CppFunc fn) {
  620. for(auto& typeName : typeNames){
  621. bindMethod(typeName, funcName, fn);
  622. }
  623. }
  624. void bindBuiltinFunc(_Str funcName, _CppFunc fn) {
  625. bindFunc(builtins, funcName, fn);
  626. }
  627. void bindFunc(PyVar module, _Str funcName, _CppFunc fn) {
  628. funcName.intern();
  629. __checkType(module, _tp_module);
  630. PyVar func = PyNativeFunction(fn);
  631. setAttr(module, funcName, func);
  632. }
  633. bool isInstance(PyVar obj, PyVar type){
  634. __checkType(type, _tp_type);
  635. PyVar t = obj->_type;
  636. while (t != None){
  637. if (t == type) return true;
  638. t = t->attribs[__base__];
  639. }
  640. return false;
  641. }
  642. inline bool isIntOrFloat(const PyVar& obj){
  643. return obj->isType(_tp_int) || obj->isType(_tp_float);
  644. }
  645. inline bool isIntOrFloat(const PyVar& obj1, const PyVar& obj2){
  646. return isIntOrFloat(obj1) && isIntOrFloat(obj2);
  647. }
  648. _Float numToFloat(const PyVar& obj){
  649. if (obj->isType(_tp_int)){
  650. return (_Float)PyInt_AS_C(obj);
  651. }else if(obj->isType(_tp_float)){
  652. return PyFloat_AS_C(obj);
  653. }
  654. UNREACHABLE();
  655. }
  656. PyVar numNegated(const PyVar& obj){
  657. if (obj->isType(_tp_int)){
  658. return PyInt(-PyInt_AS_C(obj));
  659. }else if(obj->isType(_tp_float)){
  660. return PyFloat(-PyFloat_AS_C(obj));
  661. }
  662. typeError("unsupported operand type(s) for -");
  663. return nullptr;
  664. }
  665. int normalizedIndex(int index, int size){
  666. if(index < 0) index += size;
  667. if(index < 0 || index >= size){
  668. indexError("index out of range, " + std::to_string(index) + " not in [0, " + std::to_string(size) + ")");
  669. }
  670. return index;
  671. }
  672. // for quick access
  673. PyVar _tp_object, _tp_type, _tp_int, _tp_float, _tp_bool, _tp_str;
  674. PyVar _tp_list, _tp_tuple;
  675. PyVar _tp_function, _tp_native_function, _tp_native_iterator, _tp_bounded_method;
  676. PyVar _tp_slice, _tp_range, _tp_module, _tp_pointer;
  677. PyVar _tp_user_pointer, _tp_super;
  678. __DEF_PY_POOL(Int, _Int, _tp_int, 256);
  679. __DEF_PY_AS_C(Int, _Int, _tp_int)
  680. __DEF_PY_POOL(Float, _Float, _tp_float, 256);
  681. __DEF_PY_AS_C(Float, _Float, _tp_float)
  682. __DEF_PY_POOL(Pointer, _Pointer, _tp_pointer, 256)
  683. inline _Pointer& PyPointer_AS_C(const PyVar& obj)
  684. {
  685. if(!obj->isType(_tp_pointer)) typeError("expected an l-value");
  686. return std::get<_Pointer>(obj->_native);
  687. }
  688. DEF_NATIVE(Str, _Str, _tp_str)
  689. DEF_NATIVE(List, PyVarList, _tp_list)
  690. DEF_NATIVE(Tuple, PyVarList, _tp_tuple)
  691. DEF_NATIVE(Function, _Func, _tp_function)
  692. DEF_NATIVE(NativeFunction, _CppFunc, _tp_native_function)
  693. DEF_NATIVE(Iter, std::shared_ptr<_Iterator>, _tp_native_iterator)
  694. DEF_NATIVE(BoundedMethod, _BoundedMethod, _tp_bounded_method)
  695. DEF_NATIVE(Range, _Range, _tp_range)
  696. DEF_NATIVE(Slice, _Slice, _tp_slice)
  697. // there is only one True/False, so no need to copy them!
  698. inline bool PyBool_AS_C(const PyVar& obj){return obj == True;}
  699. inline const PyVar& PyBool(bool value){return value ? True : False;}
  700. void initializeBuiltinClasses(){
  701. _tp_object = std::make_shared<PyObject>((_Int)0);
  702. _tp_type = std::make_shared<PyObject>((_Int)0);
  703. _types["object"] = _tp_object;
  704. _types["type"] = _tp_type;
  705. _tp_bool = newClassType("bool");
  706. _tp_int = newClassType("int");
  707. _tp_float = newClassType("float");
  708. _tp_str = newClassType("str");
  709. _tp_list = newClassType("list");
  710. _tp_tuple = newClassType("tuple");
  711. _tp_slice = newClassType("slice");
  712. _tp_range = newClassType("range");
  713. _tp_module = newClassType("module");
  714. _tp_pointer = newClassType("_pointer");
  715. _tp_user_pointer = newClassType("pointer");
  716. newClassType("NoneType");
  717. newClassType("ellipsis");
  718. _tp_function = newClassType("function");
  719. _tp_native_function = newClassType("_native_function");
  720. _tp_native_iterator = newClassType("_native_iterator");
  721. _tp_bounded_method = newClassType("_bounded_method");
  722. _tp_super = newClassType("super");
  723. this->None = newObject(_types["NoneType"], (_Int)0);
  724. this->Ellipsis = newObject(_types["ellipsis"], (_Int)0);
  725. this->True = newObject(_tp_bool, true);
  726. this->False = newObject(_tp_bool, false);
  727. this->builtins = newModule("builtins");
  728. this->_main = newModule("__main__"_c, false);
  729. setAttr(_tp_type, __base__, _tp_object);
  730. _tp_type->setType(_tp_type);
  731. setAttr(_tp_object, __base__, None);
  732. _tp_object->setType(_tp_type);
  733. for (auto& [name, type] : _types) {
  734. setAttr(type, __name__, PyStr(name));
  735. }
  736. this->__py2py_call_signal = newObject(_tp_object, (_Int)7);
  737. std::vector<_Str> publicTypes = {"type", "object", "bool", "int", "float", "str", "list", "tuple", "range"};
  738. for (auto& name : publicTypes) {
  739. setAttr(builtins, name, _types[name]);
  740. }
  741. }
  742. _Int hash(const PyVar& obj){
  743. if (obj->isType(_tp_int)) return PyInt_AS_C(obj);
  744. if (obj->isType(_tp_bool)) return PyBool_AS_C(obj) ? 1 : 0;
  745. if (obj->isType(_tp_float)){
  746. _Float val = PyFloat_AS_C(obj);
  747. return (_Int)std::hash<_Float>()(val);
  748. }
  749. if (obj->isType(_tp_str)) return PyStr_AS_C(obj).hash();
  750. if (obj->isType(_tp_type)) return (_Int)obj.get();
  751. if (obj->isType(_tp_tuple)) {
  752. _Int x = 1000003;
  753. for (const auto& item : PyTuple_AS_C(obj)) {
  754. _Int y = hash(item);
  755. // this is recommended by Github Copilot
  756. // i am not sure whether it is a good idea
  757. x = x ^ (y + 0x9e3779b9 + (x << 6) + (x >> 2));
  758. }
  759. return x;
  760. }
  761. typeError("unhashable type: " + obj->getTypeName());
  762. return 0;
  763. }
  764. /***** Error Reporter *****/
  765. private:
  766. void _error(const _Str& name, const _Str& msg){
  767. throw RuntimeError(name, msg, _cleanErrorAndGetSnapshots());
  768. }
  769. std::stack<_Str> _cleanErrorAndGetSnapshots(){
  770. std::stack<_Str> snapshots;
  771. while (!callstack.empty()){
  772. if(snapshots.size() < 8){
  773. snapshots.push(callstack.back()->errorSnapshot());
  774. }
  775. callstack.pop_back();
  776. }
  777. return snapshots;
  778. }
  779. public:
  780. void typeError(const _Str& msg){
  781. _error("TypeError", msg);
  782. }
  783. void systemError(const _Str& msg){
  784. _error("SystemError", msg);
  785. }
  786. void nullPointerError(){
  787. _error("NullPointerError", "pointer is invalid");
  788. }
  789. void zeroDivisionError(){
  790. _error("ZeroDivisionError", "division by zero");
  791. }
  792. void indexError(const _Str& msg){
  793. _error("IndexError", msg);
  794. }
  795. void valueError(const _Str& msg){
  796. _error("ValueError", msg);
  797. }
  798. void nameError(const _Str& name){
  799. _error("NameError", "name '" + name + "' is not defined");
  800. }
  801. void attributeError(PyVar obj, const _Str& name){
  802. _error("AttributeError", "type '" + obj->getTypeName() + "' has no attribute '" + name + "'");
  803. }
  804. inline void __checkType(const PyVar& obj, const PyVar& type){
  805. if(!obj->isType(type)) typeError("expected '" + type->getName() + "', but got '" + obj->getTypeName() + "'");
  806. }
  807. inline void __checkArgSize(const pkpy::ArgList& args, int size, bool method=false){
  808. if(args.size() == size) return;
  809. if(method) typeError(args.size()>size ? "too many arguments" : "too few arguments");
  810. else typeError("expected " + std::to_string(size) + " arguments, but got " + std::to_string(args.size()));
  811. }
  812. void _assert(bool val, const _Str& msg){
  813. if (!val) _error("AssertionError", msg);
  814. }
  815. virtual ~VM() {
  816. if(!use_stdio){
  817. delete _stdout;
  818. delete _stderr;
  819. }
  820. }
  821. };
  822. /***** Pointers' Impl *****/
  823. PyVar NamePointer::get(VM* vm, Frame* frame) const{
  824. auto it = frame->f_locals.find(name);
  825. if(it != frame->f_locals.end()) return it->second;
  826. it = frame->f_globals().find(name);
  827. if(it != frame->f_globals().end()) return it->second;
  828. it = vm->builtins->attribs.find(name);
  829. if(it != vm->builtins->attribs.end()) return it->second;
  830. vm->nameError(name);
  831. return nullptr;
  832. }
  833. void NamePointer::set(VM* vm, Frame* frame, PyVar val) const{
  834. switch(scope) {
  835. case NAME_LOCAL: frame->f_locals[name] = std::move(val); break;
  836. case NAME_GLOBAL:
  837. {
  838. if(frame->f_locals.count(name) > 0){
  839. frame->f_locals[name] = std::move(val);
  840. }else{
  841. frame->f_globals()[name] = std::move(val);
  842. }
  843. } break;
  844. default: UNREACHABLE();
  845. }
  846. }
  847. void NamePointer::del(VM* vm, Frame* frame) const{
  848. switch(scope) {
  849. case NAME_LOCAL: {
  850. if(frame->f_locals.count(name) > 0){
  851. frame->f_locals.erase(name);
  852. }else{
  853. vm->nameError(name);
  854. }
  855. } break;
  856. case NAME_GLOBAL:
  857. {
  858. if(frame->f_locals.count(name) > 0){
  859. frame->f_locals.erase(name);
  860. }else{
  861. if(frame->f_globals().count(name) > 0){
  862. frame->f_globals().erase(name);
  863. }else{
  864. vm->nameError(name);
  865. }
  866. }
  867. } break;
  868. default: UNREACHABLE();
  869. }
  870. }
  871. PyVar AttrPointer::get(VM* vm, Frame* frame) const{
  872. return vm->getAttr(obj, attr->name);
  873. }
  874. void AttrPointer::set(VM* vm, Frame* frame, PyVar val) const{
  875. vm->setAttr(obj, attr->name, val);
  876. }
  877. void AttrPointer::del(VM* vm, Frame* frame) const{
  878. vm->typeError("cannot delete attribute");
  879. }
  880. PyVar IndexPointer::get(VM* vm, Frame* frame) const{
  881. return vm->call(obj, __getitem__, {index});
  882. }
  883. void IndexPointer::set(VM* vm, Frame* frame, PyVar val) const{
  884. vm->call(obj, __setitem__, {index, val});
  885. }
  886. void IndexPointer::del(VM* vm, Frame* frame) const{
  887. vm->call(obj, __delitem__, {index});
  888. }
  889. PyVar CompoundPointer::get(VM* vm, Frame* frame) const{
  890. PyVarList args(pointers.size());
  891. for (int i = 0; i < pointers.size(); i++) {
  892. args[i] = pointers[i]->get(vm, frame);
  893. }
  894. return vm->PyTuple(args);
  895. }
  896. void CompoundPointer::set(VM* vm, Frame* frame, PyVar val) const{
  897. if(!val->isType(vm->_tp_tuple) && !val->isType(vm->_tp_list)){
  898. vm->typeError("only tuple or list can be unpacked");
  899. }
  900. const PyVarList& args = std::get<PyVarList>(val->_native);
  901. if(args.size() > pointers.size()) vm->valueError("too many values to unpack");
  902. if(args.size() < pointers.size()) vm->valueError("not enough values to unpack");
  903. for (int i = 0; i < pointers.size(); i++) {
  904. pointers[i]->set(vm, frame, args[i]);
  905. }
  906. }
  907. void CompoundPointer::del(VM* vm, Frame* frame) const{
  908. for (auto& ptr : pointers) ptr->del(vm, frame);
  909. }
  910. PyVar UserPointer::get(VM* vm, Frame* frame) const{
  911. frame = vm->__findFrame(f_id);
  912. if(frame == nullptr) vm->nullPointerError();
  913. return p->get(vm, frame);
  914. }
  915. void UserPointer::set(VM* vm, Frame* frame, PyVar val) const{
  916. frame = vm->__findFrame(f_id);
  917. if(frame == nullptr) vm->nullPointerError();
  918. p->set(vm, frame, val);
  919. }
  920. void UserPointer::del(VM* vm, Frame* frame) const{
  921. vm->typeError("delete is unsupported");
  922. }
  923. /***** Frame's Impl *****/
  924. inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){
  925. if(v->isType(vm->_tp_pointer)) return vm->PyPointer_AS_C(v)->get(vm, this);
  926. return v;
  927. }
  928. /***** Iterators' Impl *****/
  929. PyVar RangeIterator::next(){
  930. PyVar val = vm->PyInt(current);
  931. current += r.step;
  932. return val;
  933. }
  934. PyVar StringIterator::next(){
  935. return vm->PyStr(str.u8_getitem(index++));
  936. }
  937. enum ThreadState {
  938. THREAD_READY,
  939. THREAD_RUNNING,
  940. THREAD_SUSPENDED,
  941. THREAD_FINISHED
  942. };
  943. const _Str INPUT_JSONRPC_STR = "{\"method\": \"input\", \"params\": []}";
  944. class ThreadedVM : public VM {
  945. std::thread* _thread = nullptr;
  946. std::atomic<ThreadState> _state = THREAD_READY;
  947. std::optional<_Str> _sharedStr = {};
  948. PyVar jsonRpc(const _Str& _json){
  949. _sharedStr = _json;
  950. suspend();
  951. std::optional<_Str> ret = readSharedStr();
  952. if(ret.has_value()) return PyStr(ret.value());
  953. return None;
  954. }
  955. void __deleteThread(){
  956. if(_thread != nullptr){
  957. if(!_thread->joinable()) UNREACHABLE();
  958. _thread->join();
  959. delete _thread;
  960. _thread = nullptr;
  961. }
  962. }
  963. public:
  964. ThreadedVM(bool use_stdio) : VM(use_stdio) {
  965. bindBuiltinFunc("jsonrpc", [](VM* vm, const pkpy::ArgList& args){
  966. ThreadedVM *tvm = dynamic_cast<ThreadedVM*>(vm);
  967. if(tvm == nullptr) UNREACHABLE();
  968. tvm->__checkArgSize(args, 1);
  969. tvm->__checkType(args[0], vm->builtins->attribs["dict"_c]);
  970. _Str _json = tvm->PyStr_AS_C(tvm->asJson(args[0]));
  971. return tvm->jsonRpc(_json);
  972. });
  973. bindBuiltinFunc("input", [](VM* vm, const pkpy::ArgList& args) {
  974. ThreadedVM *tvm = dynamic_cast<ThreadedVM*>(vm);
  975. if(tvm == nullptr) UNREACHABLE();
  976. tvm->__checkArgSize(args, 0);
  977. return tvm->jsonRpc(INPUT_JSONRPC_STR);
  978. });
  979. }
  980. void suspend(){
  981. if(_state != THREAD_RUNNING) UNREACHABLE();
  982. _state = THREAD_SUSPENDED;
  983. // 50 fps is enough
  984. while(_state == THREAD_SUSPENDED) std::this_thread::sleep_for(std::chrono::milliseconds(20));
  985. }
  986. std::optional<_Str> readSharedStr(){
  987. std::optional<_Str> copy = _sharedStr;
  988. _sharedStr = {};
  989. return copy;
  990. }
  991. /***** For outer use *****/
  992. ThreadState getState(){
  993. return _state;
  994. }
  995. void resume(const char* value=nullptr){
  996. if(_state != THREAD_SUSPENDED) UNREACHABLE();
  997. _state = THREAD_RUNNING;
  998. if(value == nullptr){
  999. _sharedStr = {};
  1000. }else{
  1001. _sharedStr = _Str(value);
  1002. }
  1003. }
  1004. void execAsync(const _Code& code) override {
  1005. if(_state != THREAD_READY) UNREACHABLE();
  1006. __deleteThread();
  1007. _thread = new std::thread([this, code](){
  1008. this->_state = THREAD_RUNNING;
  1009. VM::exec(code);
  1010. this->_state = THREAD_FINISHED;
  1011. });
  1012. }
  1013. PyVarOrNull exec(const _Code& code, PyVar _module = nullptr) override {
  1014. if(_state == THREAD_READY) return VM::exec(code, _module);
  1015. auto callstackBackup = std::move(callstack);
  1016. callstack.clear();
  1017. PyVarOrNull ret = VM::exec(code, _module);
  1018. callstack = std::move(callstackBackup);
  1019. return ret;
  1020. }
  1021. void resetState(){
  1022. if(this->_state != THREAD_FINISHED) UNREACHABLE();
  1023. this->_state = THREAD_READY;
  1024. }
  1025. ~ThreadedVM(){
  1026. __deleteThread();
  1027. }
  1028. };