vm.h 43 KB

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