vm.cpp 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941
  1. #include "pocketpy/interpreter/vm.hpp"
  2. #include <iostream>
  3. #include <cmath>
  4. #include <stdexcept>
  5. const static char* OP_NAMES[] = {
  6. #define OPCODE(name) #name,
  7. #include "pocketpy/opcodes.h"
  8. #undef OPCODE
  9. };
  10. namespace pkpy {
  11. struct JsonSerializer {
  12. VM* vm;
  13. PyVar root;
  14. SStream ss;
  15. JsonSerializer(VM* vm, PyVar root) : vm(vm), root(root) {}
  16. template <typename T>
  17. void write_array(T& arr) {
  18. ss << '[';
  19. for(int i = 0; i < arr.size(); i++) {
  20. if(i != 0) ss << ", ";
  21. write_object(arr[i]);
  22. }
  23. ss << ']';
  24. }
  25. void write_dict(Dict& dict) {
  26. ss << '{';
  27. bool first = true;
  28. dict.apply([&](PyVar k, PyVar v) {
  29. if(!first) ss << ", ";
  30. first = false;
  31. if(!is_type(k, VM::tp_str)) {
  32. vm->TypeError(_S("json keys must be string, got ", _type_name(vm, vm->_tp(k))));
  33. }
  34. ss << _CAST(Str&, k).escape(false) << ": ";
  35. write_object(v);
  36. });
  37. ss << '}';
  38. }
  39. void write_object(PyVar obj) {
  40. Type obj_t = vm->_tp(obj);
  41. if(obj == vm->None) {
  42. ss << "null";
  43. } else if(obj_t == vm->tp_int) {
  44. ss << _CAST(i64, obj);
  45. } else if(obj_t == vm->tp_float) {
  46. f64 val = _CAST(f64, obj);
  47. if(std::isinf(val) || std::isnan(val)) vm->ValueError("cannot jsonify 'nan' or 'inf'");
  48. ss << val;
  49. } else if(obj_t == vm->tp_bool) {
  50. ss << (obj == vm->True ? "true" : "false");
  51. } else if(obj_t == vm->tp_str) {
  52. _CAST(Str&, obj).escape_(ss, false);
  53. } else if(obj_t == vm->tp_list) {
  54. write_array<List>(_CAST(List&, obj));
  55. } else if(obj_t == vm->tp_tuple) {
  56. write_array<Tuple>(_CAST(Tuple&, obj));
  57. } else if(obj_t == vm->tp_dict) {
  58. write_dict(_CAST(Dict&, obj));
  59. } else {
  60. vm->TypeError(_S("unrecognized type ", _type_name(vm, obj_t).escape()));
  61. }
  62. }
  63. Str serialize() {
  64. auto _lock = vm->heap.gc_scope_lock();
  65. write_object(root);
  66. return ss.str();
  67. }
  68. };
  69. VM::VM(bool enable_os) : heap(this), enable_os(enable_os) {
  70. this->vm = this;
  71. this->__c.error = nullptr;
  72. _ceval_on_step = nullptr;
  73. _stdout = [](const char* buf, int size) {
  74. std::cout.write(buf, size);
  75. };
  76. _stderr = [](const char* buf, int size) {
  77. std::cerr.write(buf, size);
  78. };
  79. builtins = nullptr;
  80. _main = nullptr;
  81. __last_exception = nullptr;
  82. _import_handler = [](const char* name, int* out_size) -> unsigned char* {
  83. return nullptr;
  84. };
  85. __init_builtin_types();
  86. }
  87. Str VM::py_str(PyVar obj) {
  88. const PyTypeInfo* ti = _tp_info(obj);
  89. if(ti->m__str__) return ti->m__str__(this, obj);
  90. PyVar self;
  91. PyVar f = get_unbound_method(obj, __str__, &self, false);
  92. if(self != PY_NULL) {
  93. PyVar retval = call_method(self, f);
  94. if(!is_type(retval, tp_str)) { throw std::runtime_error("object.__str__ must return str"); }
  95. return PK_OBJ_GET(Str, retval);
  96. }
  97. return py_repr(obj);
  98. }
  99. Str VM::py_repr(PyVar obj) {
  100. const PyTypeInfo* ti = _tp_info(obj);
  101. if(ti->m__repr__) return ti->m__repr__(this, obj);
  102. PyVar retval = call_method(obj, __repr__);
  103. if(!is_type(retval, tp_str)) { throw std::runtime_error("object.__repr__ must return str"); }
  104. return PK_OBJ_GET(Str, retval);
  105. }
  106. Str VM::py_json(PyVar obj) {
  107. auto j = JsonSerializer(this, obj);
  108. return j.serialize();
  109. }
  110. PyVar VM::py_iter(PyVar obj) {
  111. const PyTypeInfo* ti = _tp_info(obj);
  112. if(ti->m__iter__) return ti->m__iter__(this, obj);
  113. PyVar self;
  114. PyVar iter_f = get_unbound_method(obj, __iter__, &self, false);
  115. if(self != PY_NULL) return call_method(self, iter_f);
  116. TypeError(_type_name(vm, _tp(obj)).escape() + " object is not iterable");
  117. return nullptr;
  118. }
  119. ArgsView VM::cast_array_view(PyVar obj) {
  120. if(is_type(obj, VM::tp_list)) {
  121. List& list = PK_OBJ_GET(List, obj);
  122. return ArgsView(list.begin(), list.end());
  123. } else if(is_type(obj, VM::tp_tuple)) {
  124. Tuple& tuple = PK_OBJ_GET(Tuple, obj);
  125. return ArgsView(tuple.begin(), tuple.end());
  126. }
  127. TypeError(_S("expected list or tuple, got ", _type_name(this, _tp(obj)).escape()));
  128. }
  129. void VM::set_main_argv(int argc, char** argv) {
  130. PyVar mod = vm->_modules["sys"];
  131. List argv_(argc);
  132. for(int i = 0; i < argc; i++)
  133. argv_[i] = VAR(std::string_view(argv[i]));
  134. mod->attr().set("argv", VAR(std::move(argv_)));
  135. }
  136. PyVar* VM::find_name_in_mro(Type cls, StrName name) {
  137. PyVar* val;
  138. do {
  139. val = _t(cls)->attr().try_get_2(name);
  140. if(val != nullptr) return val;
  141. cls = _all_types[cls].base;
  142. if(!cls) break;
  143. } while(true);
  144. return nullptr;
  145. }
  146. bool VM::isinstance(PyVar obj, Type base) { return issubclass(_tp(obj), base); }
  147. bool VM::issubclass(Type cls, Type base) {
  148. do {
  149. if(cls == base) return true;
  150. Type next = _all_types[cls].base;
  151. if(!next) break;
  152. cls = next;
  153. } while(true);
  154. return false;
  155. }
  156. PyVar VM::exec(std::string_view source, Str filename, CompileMode mode, PyObject* _module) {
  157. if(_module == nullptr) _module = _main;
  158. try {
  159. #if PK_DEBUG_PRECOMPILED_EXEC == 1
  160. Str precompiled = vm->precompile(source, filename, mode);
  161. source = precompiled.sv();
  162. #endif
  163. CodeObject_ code = compile(source, filename, mode);
  164. return _exec(code, _module);
  165. } catch(TopLevelException e) { stderr_write(e.summary() + "\n"); } catch(const std::exception& e) {
  166. Str msg = "An std::exception occurred! It could be a bug.\n";
  167. msg = msg + e.what() + "\n";
  168. stderr_write(msg);
  169. } catch(NeedMoreLines) { throw; } catch(...) {
  170. Str msg = "An unknown exception occurred! It could be a bug. Please report it to @blueloveTH on GitHub.\n";
  171. stderr_write(msg);
  172. }
  173. callstack.clear();
  174. s_data.clear();
  175. return nullptr;
  176. }
  177. PyVar VM::exec(std::string_view source) { return exec(source, "main.py", EXEC_MODE); }
  178. PyVar VM::eval(std::string_view source) { return exec(source, "<eval>", EVAL_MODE); }
  179. PyObject* VM::new_type_object(PyObject* mod, StrName name, Type base, bool subclass_enabled, PyTypeInfo::Vt vt) {
  180. PyObject* obj = heap._new<Type>(tp_type, Type(_all_types.size()));
  181. const PyTypeInfo& base_info = _all_types[base];
  182. if(!base_info.subclass_enabled) {
  183. Str error = _S("type ", base_info.name.escape(), " is not `subclass_enabled`");
  184. throw std::runtime_error(error.c_str());
  185. }
  186. if(base_info.vt) {
  187. if(vt) {
  188. Str error = _S("type ", base_info.name.escape(), " has a custom vtable, cannot override");
  189. throw std::runtime_error(error.c_str());
  190. } else {
  191. // promote base vt to its subclass
  192. vt = base_info.vt;
  193. }
  194. }
  195. _all_types.emplace_back(obj, base, mod, name, subclass_enabled, vt);
  196. return obj;
  197. }
  198. bool VM::py_eq(PyVar lhs, PyVar rhs) {
  199. if(is_int(lhs) && is_int(rhs)) return lhs.as<i64>() == rhs.as<i64>();
  200. const PyTypeInfo* ti = _tp_info(lhs);
  201. PyVar res;
  202. if(ti->m__eq__) {
  203. res = ti->m__eq__(this, lhs, rhs);
  204. if(!is_not_implemented(res)) return res == vm->True;
  205. }
  206. res = call_method(lhs, __eq__, rhs);
  207. if(!is_not_implemented(res)) return res == vm->True;
  208. ti = _tp_info(rhs);
  209. if(ti->m__eq__) {
  210. res = ti->m__eq__(this, rhs, lhs);
  211. if(!is_not_implemented(res)) return res == vm->True;
  212. }
  213. res = call_method(rhs, __eq__, lhs);
  214. if(!is_not_implemented(res)) return res == vm->True;
  215. return false;
  216. }
  217. PyVar VM::py_op(std::string_view name) {
  218. PyVar func;
  219. auto it = __cached_op_funcs.try_get(name);
  220. if(it == nullptr) {
  221. func = py_import("operator")->attr(StrName::get(name));
  222. __cached_op_funcs.insert(name, func);
  223. } else {
  224. func = *it;
  225. }
  226. return func;
  227. }
  228. i64 VM::normalized_index(i64 index, int size) {
  229. if(index < 0) index += size;
  230. if(index < 0 || index >= size) { IndexError(std::to_string(index) + " not in [0, " + std::to_string(size) + ")"); }
  231. return index;
  232. }
  233. PyVar VM::_py_next(const PyTypeInfo* ti, PyVar obj) {
  234. if(ti->op__next__) {
  235. unsigned n = ti->op__next__(this, obj);
  236. return __pack_next_retval(n);
  237. }
  238. return call_method(obj, __next__);
  239. }
  240. PyVar VM::py_next(PyVar obj) {
  241. const PyTypeInfo* ti = _tp_info(obj);
  242. return _py_next(ti, obj);
  243. }
  244. bool VM::py_callable(PyVar obj) {
  245. Type cls = vm->_tp(obj);
  246. switch(cls.index) {
  247. case VM::tp_function.index: return true;
  248. case VM::tp_native_func.index: return true;
  249. case VM::tp_bound_method.index: return true;
  250. case VM::tp_type.index: return true;
  251. }
  252. return vm->find_name_in_mro(cls, __call__) != nullptr;
  253. }
  254. PyVar VM::__minmax_reduce(bool (VM::*op)(PyVar, PyVar), PyVar args, PyVar key) {
  255. auto _lock = heap.gc_scope_lock();
  256. const Tuple& args_tuple = PK_OBJ_GET(Tuple, args); // from *args, it must be a tuple
  257. if(key == vm->None && args_tuple.size() == 2) {
  258. // fast path
  259. PyVar a = args_tuple[0];
  260. PyVar b = args_tuple[1];
  261. return (this->*op)(a, b) ? a : b;
  262. }
  263. if(args_tuple.size() == 0) TypeError("expected at least 1 argument, got 0");
  264. ArgsView view(nullptr, nullptr);
  265. if(args_tuple.size() == 1) {
  266. view = cast_array_view(args_tuple[0]);
  267. } else {
  268. view = ArgsView(args_tuple);
  269. }
  270. if(view.empty()) ValueError("arg is an empty sequence");
  271. PyVar res = view[0];
  272. if(key == vm->None) {
  273. for(int i = 1; i < view.size(); i++) {
  274. if((this->*op)(view[i], res)) res = view[i];
  275. }
  276. } else {
  277. auto _lock = heap.gc_scope_lock();
  278. for(int i = 1; i < view.size(); i++) {
  279. PyVar a = call(key, view[i]);
  280. PyVar b = call(key, res);
  281. if((this->*op)(a, b)) res = view[i];
  282. }
  283. }
  284. return res;
  285. }
  286. PyObject* VM::py_import(Str path, bool throw_err) {
  287. if(path.empty()) vm->ValueError("empty module name");
  288. static auto f_join = [](const vector<std::string_view>& cpnts) {
  289. SStream ss;
  290. for(int i = 0; i < cpnts.size(); i++) {
  291. if(i != 0) ss << ".";
  292. ss << cpnts[i];
  293. }
  294. return ss.str();
  295. };
  296. if(path[0] == '.') {
  297. if(__import_context.pending.empty()) { ImportError("relative import outside of package"); }
  298. Str curr_path = __import_context.pending.back();
  299. bool curr_is_init = __import_context.pending_is_init.back();
  300. // convert relative path to absolute path
  301. vector<std::string_view> cpnts = curr_path.split('.');
  302. int prefix = 0; // how many dots in the prefix
  303. for(int i = 0; i < path.length(); i++) {
  304. if(path[i] == '.')
  305. prefix++;
  306. else
  307. break;
  308. }
  309. if(prefix > cpnts.size()) ImportError("attempted relative import beyond top-level package");
  310. path = path.substr(prefix); // remove prefix
  311. for(int i = (int)curr_is_init; i < prefix; i++)
  312. cpnts.pop_back();
  313. if(!path.empty()) cpnts.push_back(path.sv());
  314. path = f_join(cpnts);
  315. }
  316. assert(path.begin()[0] != '.' && path.end()[-1] != '.');
  317. // check existing module
  318. StrName name(path);
  319. PyVar ext_mod = _modules.try_get(name);
  320. if(ext_mod != nullptr) return ext_mod.get();
  321. vector<std::string_view> path_cpnts = path.split('.');
  322. // check circular import
  323. if(__import_context.pending.size() > 128) { ImportError("maximum recursion depth exceeded while importing"); }
  324. // try import
  325. Str filename = path.replace('.', PK_PLATFORM_SEP) + ".py";
  326. Str source;
  327. bool is_init = false;
  328. auto it = _lazy_modules.try_get(name);
  329. if(it == nullptr) {
  330. int out_size;
  331. unsigned char* out = _import_handler(filename.c_str(), &out_size);
  332. if(out == nullptr) {
  333. filename = path.replace('.', PK_PLATFORM_SEP).str() + PK_PLATFORM_SEP + "__init__.py";
  334. is_init = true;
  335. out = _import_handler(filename.c_str(), &out_size);
  336. }
  337. if(out == nullptr) {
  338. if(throw_err)
  339. ImportError(_S("module ", path.escape(), " not found"));
  340. else
  341. return nullptr;
  342. }
  343. assert(out_size >= 0);
  344. source = Str(std::string_view((char*)out, out_size));
  345. std::free(out);
  346. } else {
  347. source = *it;
  348. // _lazy_modules.erase(it); // no need to erase
  349. }
  350. auto _ = __import_context.scope(path, is_init);
  351. CodeObject_ code = compile(source, filename, EXEC_MODE);
  352. Str name_cpnt = path_cpnts.back();
  353. path_cpnts.pop_back();
  354. PyObject* new_mod = new_module(name_cpnt, f_join(path_cpnts));
  355. _exec(code, new_mod);
  356. return new_mod;
  357. }
  358. VM::~VM() {
  359. // clear managed heap
  360. for(PyObject* obj: heap.gen)
  361. heap._delete(obj);
  362. for(PyObject* obj: heap._no_gc)
  363. heap._delete(obj);
  364. // clear everything
  365. callstack.clear();
  366. s_data.clear();
  367. _all_types.clear();
  368. _modules.clear();
  369. _lazy_modules.clear();
  370. }
  371. PyVar VM::py_negate(PyVar obj) {
  372. const PyTypeInfo* ti = _tp_info(obj);
  373. if(ti->m__neg__) return ti->m__neg__(this, obj);
  374. return call_method(obj, __neg__);
  375. }
  376. bool VM::__py_bool_non_trivial(PyVar obj) {
  377. if(obj == None) return false;
  378. if(is_int(obj)) return _CAST(i64, obj) != 0;
  379. if(is_float(obj)) return _CAST(f64, obj) != 0.0;
  380. PyVar self;
  381. PyVar len_f = get_unbound_method(obj, __len__, &self, false);
  382. if(self != PY_NULL) {
  383. PyVar ret = call_method(self, len_f);
  384. return CAST(i64, ret) != 0;
  385. }
  386. return true;
  387. }
  388. void VM::__obj_gc_mark(PyObject* obj) {
  389. if(obj->gc_marked) return;
  390. obj->gc_marked = true;
  391. const PyTypeInfo* ti = _tp_info(obj->type);
  392. if(ti->vt._gc_mark) ti->vt._gc_mark(obj->_value_ptr(), this);
  393. if(obj->is_attr_valid()) {
  394. obj->attr().apply([](StrName _, PyVar obj, void* userdata) {
  395. VM* vm = (VM*)userdata;
  396. if(obj.is_ptr) vm->__obj_gc_mark((obj).get());
  397. }, vm);
  398. }
  399. }
  400. void VM::__stack_gc_mark(PyVar* begin, PyVar* end) {
  401. for(PyVar* it = begin; it != end; it++) {
  402. if(it->is_ptr) {
  403. __obj_gc_mark(it->get());
  404. } else {
  405. if(it->type == tp_stack_memory) {
  406. // [sm:3, _0, _1, _2, sm:-3]
  407. int count = it->as<StackMemory>().count;
  408. if(count > 0) it += count;
  409. }
  410. }
  411. }
  412. }
  413. void* VM::__stack_alloc(int size) {
  414. int count = size / sizeof(PyVar) + 1;
  415. s_data.emplace(tp_stack_memory, StackMemory(count));
  416. void* out = s_data._sp;
  417. s_data._sp += count;
  418. s_data.emplace(tp_stack_memory, StackMemory(-count));
  419. return out;
  420. }
  421. List VM::py_list(PyVar it) {
  422. auto _lock = heap.gc_scope_lock();
  423. it = py_iter(it);
  424. List list;
  425. const PyTypeInfo* info = _tp_info(it);
  426. PyVar obj = _py_next(info, it);
  427. while(obj != StopIteration) {
  428. list.push_back(obj);
  429. obj = _py_next(info, it);
  430. }
  431. return list;
  432. }
  433. void VM::parse_int_slice(const Slice& s, int length, int& start, int& stop, int& step) {
  434. auto clip = [](int value, int min, int max) {
  435. if(value < min) return min;
  436. if(value > max) return max;
  437. return value;
  438. };
  439. if(s.step == None)
  440. step = 1;
  441. else
  442. step = CAST(int, s.step);
  443. if(step == 0) ValueError("slice step cannot be zero");
  444. if(step > 0) {
  445. if(s.start == None) {
  446. start = 0;
  447. } else {
  448. start = CAST(int, s.start);
  449. if(start < 0) start += length;
  450. start = clip(start, 0, length);
  451. }
  452. if(s.stop == None) {
  453. stop = length;
  454. } else {
  455. stop = CAST(int, s.stop);
  456. if(stop < 0) stop += length;
  457. stop = clip(stop, 0, length);
  458. }
  459. } else {
  460. if(s.start == None) {
  461. start = length - 1;
  462. } else {
  463. start = CAST(int, s.start);
  464. if(start < 0) start += length;
  465. start = clip(start, -1, length - 1);
  466. }
  467. if(s.stop == None) {
  468. stop = -1;
  469. } else {
  470. stop = CAST(int, s.stop);
  471. if(stop < 0) stop += length;
  472. stop = clip(stop, -1, length - 1);
  473. }
  474. }
  475. }
  476. i64 VM::py_hash(PyVar obj) {
  477. // https://docs.python.org/3.10/reference/datamodel.html#object.__hash__
  478. const PyTypeInfo* ti = _tp_info(obj);
  479. if(ti->m__hash__) return ti->m__hash__(this, obj);
  480. PyVar self;
  481. PyVar f = get_unbound_method(obj, __hash__, &self, false);
  482. if(f != nullptr) {
  483. PyVar ret = call_method(self, f);
  484. return CAST(i64, ret);
  485. }
  486. // if it is trivial `object`, return PK_BITS
  487. if(ti == &_all_types[tp_object]) return obj.hash();
  488. // otherwise, we check if it has a custom __eq__ other than object.__eq__
  489. bool has_custom_eq = false;
  490. if(ti->m__eq__)
  491. has_custom_eq = true;
  492. else {
  493. f = get_unbound_method(obj, __eq__, &self, false);
  494. has_custom_eq = f != _t(tp_object)->attr(__eq__);
  495. }
  496. if(has_custom_eq) {
  497. TypeError(_S("unhashable type: ", ti->name.escape()));
  498. } else {
  499. return obj.hash();
  500. }
  501. }
  502. PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar locals) {
  503. Frame* frame = nullptr;
  504. if(!callstack.empty()) frame = &callstack.top();
  505. // fast path
  506. if(frame && globals == vm->None && locals == vm->None) {
  507. return vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
  508. }
  509. auto _lock = heap.gc_scope_lock(); // for safety
  510. PyObject* globals_obj = nullptr;
  511. Dict* globals_dict = nullptr;
  512. NameDict_ locals_closure = nullptr;
  513. Dict* locals_dict = nullptr;
  514. if(frame && globals == vm->None) {
  515. globals_obj = frame->_module;
  516. } else {
  517. if(is_type(globals, VM::tp_mappingproxy)) {
  518. globals_obj = PK_OBJ_GET(MappingProxy, globals).obj;
  519. } else {
  520. check_compatible_type(globals, VM::tp_dict);
  521. // make a temporary object and copy globals into it
  522. globals_obj = new_object<DummyInstance>(VM::tp_object).get();
  523. globals_obj->_attr = new NameDict();
  524. globals_dict = &PK_OBJ_GET(Dict, globals);
  525. globals_dict->apply([&](PyVar k, PyVar v) {
  526. globals_obj->attr().set(CAST(Str&, k), v);
  527. });
  528. }
  529. }
  530. PyVar retval = nullptr;
  531. if(locals == vm->None) {
  532. retval = vm->_exec(code, globals_obj); // only globals
  533. } else {
  534. check_compatible_type(locals, VM::tp_dict);
  535. locals_dict = &PK_OBJ_GET(Dict, locals);
  536. locals_closure = std::make_shared<NameDict>();
  537. locals_dict->apply([&](PyVar k, PyVar v) {
  538. locals_closure->set(CAST(Str&, k), v);
  539. });
  540. PyObject* _callable =
  541. heap.gcnew<Function>(tp_function, __dynamic_func_decl, globals_obj, nullptr, locals_closure);
  542. retval = vm->_exec(code.get(), globals_obj, _callable, vm->s_data._sp);
  543. }
  544. if(globals_dict) {
  545. globals_dict->clear();
  546. for(auto [k, v]: globals_obj->attr().items()){
  547. globals_dict->set(vm, VAR(k.sv()), v);
  548. }
  549. }
  550. if(locals_dict) {
  551. locals_dict->clear();
  552. for(auto [k, v]: locals_closure->items()){
  553. locals_dict->set(vm, VAR(k.sv()), v);
  554. }
  555. }
  556. return retval;
  557. }
  558. void VM::py_exec(std::string_view source, PyVar globals, PyVar locals) {
  559. CodeObject_ code = vm->compile(source, "<exec>", EXEC_MODE, true);
  560. __py_exec_internal(code, globals, locals);
  561. }
  562. PyVar VM::py_eval(std::string_view source, PyVar globals, PyVar locals) {
  563. CodeObject_ code = vm->compile(source, "<eval>", EVAL_MODE, true);
  564. return __py_exec_internal(code, globals, locals);
  565. }
  566. PyVar VM::__format_object(PyVar obj, Str spec) {
  567. if(spec.empty()) return VAR(py_str(obj));
  568. char type;
  569. switch(spec.end()[-1]) {
  570. case 'f':
  571. case 'd':
  572. case 's':
  573. type = spec.end()[-1];
  574. spec = spec.substr(0, spec.length() - 1);
  575. break;
  576. default: type = ' '; break;
  577. }
  578. char pad_c = ' ';
  579. for(char c: std::string_view("0-=*#@!~")) {
  580. if(spec[0] == c) {
  581. pad_c = c;
  582. spec = spec.substr(1);
  583. break;
  584. }
  585. }
  586. char align;
  587. if(spec[0] == '^') {
  588. align = '^';
  589. spec = spec.substr(1);
  590. } else if(spec[0] == '>') {
  591. align = '>';
  592. spec = spec.substr(1);
  593. } else if(spec[0] == '<') {
  594. align = '<';
  595. spec = spec.substr(1);
  596. } else {
  597. if(is_int(obj) || is_float(obj))
  598. align = '>';
  599. else
  600. align = '<';
  601. }
  602. int dot = spec.index(".");
  603. int width, precision;
  604. try {
  605. if(dot >= 0) {
  606. if(dot == 0) {
  607. width = -1;
  608. } else {
  609. width = std::stoi(spec.substr(0, dot).str());
  610. }
  611. precision = std::stoi(spec.substr(dot + 1).str());
  612. } else {
  613. width = std::stoi(spec.str());
  614. precision = -1;
  615. }
  616. } catch(...) { ValueError("invalid format specifer"); }
  617. if(type != 'f' && dot >= 0) ValueError("precision not allowed in the format specifier");
  618. Str ret;
  619. if(type == 'f') {
  620. f64 val = CAST(f64, obj);
  621. if(precision < 0) precision = 6;
  622. SStream ss;
  623. ss.setprecision(precision);
  624. ss << val;
  625. ret = ss.str();
  626. } else if(type == 'd') {
  627. ret = std::to_string(CAST(i64, obj));
  628. } else if(type == 's') {
  629. ret = CAST(Str&, obj);
  630. } else {
  631. ret = py_str(obj);
  632. }
  633. if(width != -1 && width > ret.length()) {
  634. int pad = width - ret.length();
  635. if(align == '>' || align == '<') {
  636. std::string padding(pad, pad_c);
  637. if(align == '>')
  638. ret = padding.c_str() + ret;
  639. else
  640. ret = ret + padding.c_str();
  641. } else { // ^
  642. int pad_left = pad / 2;
  643. int pad_right = pad - pad_left;
  644. std::string padding_left(pad_left, pad_c);
  645. std::string padding_right(pad_right, pad_c);
  646. ret = padding_left.c_str() + ret + padding_right.c_str();
  647. }
  648. }
  649. return VAR(ret);
  650. }
  651. PyObject* VM::new_module(Str name, Str package) {
  652. PyObject* obj = heap._new<DummyModule>(tp_module);
  653. obj->attr().set(__name__, VAR(name));
  654. obj->attr().set(__package__, VAR(package));
  655. // convert to fullname
  656. if(!package.empty()) name = package + "." + name;
  657. obj->attr().set(__path__, VAR(name));
  658. // we do not allow override in order to avoid memory leak
  659. // it is because Module objects are not garbage collected
  660. if(_modules.contains(name)) { throw std::runtime_error(_S("module ", name.escape(), " already exists").str()); }
  661. // set it into _modules
  662. _modules.set(name, obj);
  663. return obj;
  664. }
  665. static std::string _opcode_argstr(VM* vm, int i, Bytecode byte, const CodeObject* co) {
  666. SStream ss;
  667. if(byte.is_forward_jump()) {
  668. std::string argStr = std::to_string((int16_t)byte.arg);
  669. ss << (i64)(int16_t)byte.arg;
  670. ss << " (to " << (i64)((int16_t)byte.arg + i) << ")";
  671. return ss.str().str();
  672. }
  673. ss << (i64)byte.arg;
  674. switch(byte.op) {
  675. case OP_LOAD_CONST:
  676. case OP_FORMAT_STRING:
  677. case OP_IMPORT_PATH:
  678. if(vm != nullptr) ss << " (" << vm->py_repr(co->consts[byte.arg]) << ")";
  679. break;
  680. case OP_LOAD_NAME:
  681. case OP_LOAD_GLOBAL:
  682. case OP_LOAD_NONLOCAL:
  683. case OP_STORE_GLOBAL:
  684. case OP_LOAD_ATTR:
  685. case OP_LOAD_METHOD:
  686. case OP_STORE_ATTR:
  687. case OP_DELETE_ATTR:
  688. case OP_BEGIN_CLASS:
  689. case OP_GOTO:
  690. case OP_DELETE_GLOBAL:
  691. case OP_STORE_CLASS_ATTR:
  692. case OP_FOR_ITER_STORE_GLOBAL: ss << " (" << StrName(byte.arg).sv() << ")"; break;
  693. case OP_LOAD_FAST:
  694. case OP_STORE_FAST:
  695. case OP_DELETE_FAST:
  696. case OP_FOR_ITER_STORE_FAST:
  697. case OP_LOAD_SUBSCR_FAST:
  698. case OP_STORE_SUBSCR_FAST: ss << " (" << co->varnames[byte.arg].sv() << ")"; break;
  699. case OP_LOAD_FUNCTION: ss << " (" << co->func_decls[byte.arg]->code->name << ")"; break;
  700. }
  701. return ss.str().str();
  702. }
  703. Str VM::disassemble(CodeObject_ co) {
  704. auto pad = [](const Str& s, const int n) {
  705. if(s.length() >= n) return s.substr(0, n);
  706. return s + std::string(n - s.length(), ' ');
  707. };
  708. vector<int> jumpTargets;
  709. for(int i = 0; i < co->codes.size(); i++) {
  710. Bytecode byte = co->codes[i];
  711. if(byte.is_forward_jump()) { jumpTargets.push_back((int16_t)byte.arg + i); }
  712. }
  713. SStream ss;
  714. int prev_line = -1;
  715. for(int i = 0; i < co->codes.size(); i++) {
  716. const Bytecode& byte = co->codes[i];
  717. Str line = std::to_string(co->lines[i].lineno);
  718. if(co->lines[i].lineno == prev_line)
  719. line = "";
  720. else {
  721. if(prev_line != -1) ss << "\n";
  722. prev_line = co->lines[i].lineno;
  723. }
  724. std::string pointer;
  725. if(jumpTargets.contains(i)) {
  726. pointer = "-> ";
  727. } else {
  728. pointer = " ";
  729. }
  730. ss << pad(line, 8) << pointer << pad(std::to_string(i), 3);
  731. std::string bc_name(OP_NAMES[byte.op]);
  732. if(co->lines[i].is_virtual) bc_name += '*';
  733. ss << " " << pad(bc_name, 25) << " ";
  734. std::string argStr = _opcode_argstr(this, i, byte, co.get());
  735. ss << argStr;
  736. if(i != co->codes.size() - 1) ss << '\n';
  737. }
  738. for(auto& decl: co->func_decls) {
  739. ss << "\n\n"
  740. << "Disassembly of " << decl->code->name << ":\n";
  741. ss << disassemble(decl->code);
  742. }
  743. ss << "\n";
  744. return Str(ss.str());
  745. }
  746. #if PK_DEBUG_CEVAL_STEP
  747. void VM::__log_s_data(const char* title) {
  748. if(_main == nullptr) return;
  749. if(callstack.empty()) return;
  750. SStream ss;
  751. if(title) ss << title << " | ";
  752. std::map<PyVar*, int> sp_bases;
  753. callstack.apply([&](Frame& f) {
  754. assert(f._sp_base != nullptr);
  755. sp_bases[f._sp_base] += 1;
  756. });
  757. Frame* frame = &callstack.top();
  758. int line = frame->curr_lineno();
  759. ss << frame->co->name << ":" << line << " [";
  760. for(PyVar* p = s_data.begin(); p != s_data.end(); p++) {
  761. ss << std::string(sp_bases[p], '|');
  762. if(sp_bases[p] > 0) ss << " ";
  763. if(*p == PY_NULL)
  764. ss << "NULL";
  765. else {
  766. switch(p->type) {
  767. case tp_none_type: ss << "None"; break;
  768. case tp_int: ss << _CAST(i64, *p); break;
  769. case tp_float: ss << _CAST(f64, *p); break;
  770. case tp_bool: ss << ((*p == True) ? "True" : "False"); break;
  771. case tp_str: ss << _CAST(Str, *p).escape(); break;
  772. case tp_function: ss << p->obj_get<Function>().decl->code->name << "()"; break;
  773. case tp_type: ss << "<class " + _type_name(this, p->obj_get<Type>()).escape() + ">"; break;
  774. case tp_list: ss << "list(size=" << p->obj_get<List>().size() << ")"; break;
  775. case tp_tuple: ss << "tuple(size=" << p->obj_get<Tuple>().size() << ")"; break;
  776. case tp_stack_memory: {
  777. int count = p->obj_get<StackMemory>().count;
  778. ss << "M[" << count << "]";
  779. if(count > 0) p += count;
  780. break;
  781. }
  782. default: ss << "(" << _type_name(this, p->type) << ")"; break;
  783. }
  784. }
  785. ss << ", ";
  786. }
  787. std::string output = ss.str().str();
  788. if(!s_data.empty()) {
  789. output.pop_back();
  790. output.pop_back();
  791. }
  792. output.push_back(']');
  793. Bytecode byte = *frame->_ip;
  794. std::cout << output << " " << OP_NAMES[byte.op] << " " << _opcode_argstr(nullptr, frame->ip(), byte, frame->co)
  795. << std::endl;
  796. }
  797. #endif
  798. void VM::__init_builtin_types() {
  799. _all_types.emplace_back(nullptr, Type(), nullptr, "", false); // 0 is not used
  800. _all_types.emplace_back(heap._new<Type>(tp_type, tp_object), Type(), nullptr, "object", true);
  801. _all_types.emplace_back(heap._new<Type>(tp_type, tp_type), tp_object, nullptr, "type", false);
  802. auto validate = [](Type type, PyObject* ret) {
  803. Type ret_t = ret->as<Type>();
  804. if(ret_t != type) exit(-3);
  805. };
  806. validate(tp_int, new_type_object(nullptr, "int", tp_object, false));
  807. validate(tp_float, new_type_object(nullptr, "float", tp_object, false));
  808. validate(tp_bool, new_type_object(nullptr, "bool", tp_object, false));
  809. validate(tp_str, new_type_object<Str>(nullptr, "str", tp_object, false));
  810. validate(tp_list, new_type_object<List>(nullptr, "list", tp_object, false));
  811. validate(tp_tuple, new_type_object<Tuple>(nullptr, "tuple", tp_object, false));
  812. validate(tp_slice, new_type_object<Slice>(nullptr, "slice", tp_object, false));
  813. validate(tp_range, new_type_object<Range>(nullptr, "range", tp_object, false));
  814. validate(tp_module, new_type_object<DummyModule>(nullptr, "module", tp_object, false));
  815. validate(tp_function, new_type_object<Function>(nullptr, "function", tp_object, false));
  816. validate(tp_native_func, new_type_object<NativeFunc>(nullptr, "native_func", tp_object, false));
  817. validate(tp_bound_method, new_type_object<BoundMethod>(nullptr, "bound_method", tp_object, false));
  818. validate(tp_super, new_type_object<Super>(nullptr, "super", tp_object, false));
  819. validate(tp_exception, new_type_object<Exception>(nullptr, "Exception", tp_object, true));
  820. validate(tp_bytes, new_type_object<Bytes>(nullptr, "bytes", tp_object, false));
  821. validate(tp_mappingproxy, new_type_object<MappingProxy>(nullptr, "mappingproxy", tp_object, false));
  822. validate(tp_dict, new_type_object<Dict>(nullptr, "dict", tp_object, true));
  823. validate(tp_property, new_type_object<Property>(nullptr, "property", tp_object, false));
  824. validate(tp_star_wrapper, new_type_object<StarWrapper>(nullptr, "_star_wrapper", tp_object, false));
  825. validate(tp_staticmethod, new_type_object<StaticMethod>(nullptr, "staticmethod", tp_object, false));
  826. validate(tp_classmethod, new_type_object<ClassMethod>(nullptr, "classmethod", tp_object, false));
  827. validate(tp_none_type, new_type_object(nullptr, "NoneType", tp_object, false));
  828. validate(tp_not_implemented, new_type_object(nullptr, "NotImplementedType", tp_object, false));
  829. validate(tp_ellipsis, new_type_object(nullptr, "ellipsis", tp_object, false));
  830. validate(tp_stack_memory, new_type_object<StackMemory>(nullptr, "_stack_memory", tp_object, false));
  831. // SyntaxError and IndentationError must be created here
  832. PyObject* SyntaxError = new_type_object(nullptr, "SyntaxError", tp_exception, true);
  833. PyObject* IndentationError = new_type_object(nullptr, "IndentationError", SyntaxError->as<Type>(), true);
  834. this->StopIteration = new_type_object(nullptr, "StopIteration", tp_exception, true);
  835. this->builtins = new_module("builtins");
  836. // setup public types
  837. builtins->attr().set("type", _t(tp_type));
  838. builtins->attr().set("object", _t(tp_object));
  839. builtins->attr().set("bool", _t(tp_bool));
  840. builtins->attr().set("int", _t(tp_int));
  841. builtins->attr().set("float", _t(tp_float));
  842. builtins->attr().set("str", _t(tp_str));
  843. builtins->attr().set("list", _t(tp_list));
  844. builtins->attr().set("tuple", _t(tp_tuple));
  845. builtins->attr().set("range", _t(tp_range));
  846. builtins->attr().set("bytes", _t(tp_bytes));
  847. builtins->attr().set("dict", _t(tp_dict));
  848. builtins->attr().set("property", _t(tp_property));
  849. builtins->attr().set("StopIteration", StopIteration);
  850. builtins->attr().set("NotImplemented", NotImplemented);
  851. builtins->attr().set("slice", _t(tp_slice));
  852. builtins->attr().set("Exception", _t(tp_exception));
  853. builtins->attr().set("SyntaxError", SyntaxError);
  854. builtins->attr().set("IndentationError", IndentationError);
  855. __post_init_builtin_types();
  856. this->_main = new_module("__main__");
  857. }
  858. void VM::__unpack_as_list(ArgsView args, List& list) {
  859. auto _lock = heap.gc_scope_lock();
  860. for(PyVar obj: args) {
  861. if(is_type(obj, tp_star_wrapper)) {
  862. const StarWrapper& w = _CAST(StarWrapper&, obj);
  863. // maybe this check should be done in the compile time
  864. if(w.level != 1) TypeError("expected level 1 star wrapper");
  865. PyVar _0 = py_iter(w.obj);
  866. const PyTypeInfo* info = _tp_info(_0);
  867. PyVar _1 = _py_next(info, _0);
  868. while(_1 != StopIteration) {
  869. list.push_back(_1);
  870. _1 = _py_next(info, _0);
  871. }
  872. } else {
  873. list.push_back(obj);
  874. }
  875. }
  876. }
  877. void VM::__unpack_as_dict(ArgsView args, Dict& dict) {
  878. auto _lock = heap.gc_scope_lock();
  879. for(PyVar obj: args) {
  880. if(is_type(obj, tp_star_wrapper)) {
  881. const StarWrapper& w = _CAST(StarWrapper&, obj);
  882. // maybe this check should be done in the compile time
  883. if(w.level != 2) TypeError("expected level 2 star wrapper");
  884. const Dict& other = CAST(Dict&, w.obj);
  885. dict.update(this, other);
  886. } else {
  887. const Tuple& t = CAST(Tuple&, obj);
  888. if(t.size() != 2) TypeError("expected tuple of length 2");
  889. dict.set(this, t[0], t[1]);
  890. }
  891. }
  892. }
  893. void VM::__prepare_py_call(PyVar* buffer, ArgsView args, ArgsView kwargs, const FuncDecl_& decl) {
  894. const CodeObject* co = decl->code.get();
  895. int decl_argc = decl->args.size();
  896. if(args.size() < decl_argc) {
  897. vm->TypeError(_S(co->name, "() takes ", decl_argc, " positional arguments but ", args.size(), " were given"));
  898. }
  899. int i = 0;
  900. // prepare args
  901. std::memset(buffer, 0, co->nlocals * sizeof(PyVar));
  902. for(int index: decl->args)
  903. buffer[index] = args[i++];
  904. // prepare kwdefaults
  905. for(auto& kv: decl->kwargs)
  906. buffer[kv.index] = kv.value;
  907. // handle *args
  908. if(decl->starred_arg != -1) {
  909. ArgsView vargs(args.begin() + i, args.end());
  910. buffer[decl->starred_arg] = VAR(vargs.to_tuple());
  911. i += vargs.size();
  912. } else {
  913. // kwdefaults override
  914. for(auto& kv: decl->kwargs) {
  915. if(i >= args.size()) break;
  916. buffer[kv.index] = args[i++];
  917. }
  918. if(i < args.size()) TypeError(_S("too many arguments", " (", decl->code->name, ')'));
  919. }
  920. PyVar vkwargs;
  921. if(decl->starred_kwarg != -1) {
  922. vkwargs = VAR(Dict());
  923. buffer[decl->starred_kwarg] = vkwargs;
  924. } else {
  925. vkwargs = nullptr;
  926. }
  927. for(int j = 0; j < kwargs.size(); j += 2) {
  928. StrName key(_CAST(uint16_t, kwargs[j]));
  929. int index = decl->kw_to_index.get(key, -1);
  930. // if key is an explicit key, set as local variable
  931. if(index >= 0) {
  932. buffer[index] = kwargs[j + 1];
  933. } else {
  934. // otherwise, set as **kwargs if possible
  935. if(vkwargs == nullptr) {
  936. TypeError(_S(key.escape(), " is an invalid keyword argument for ", co->name, "()"));
  937. } else {
  938. Dict& dict = _CAST(Dict&, vkwargs);
  939. dict.set(this, VAR(key.sv()), kwargs[j + 1]);
  940. }
  941. }
  942. }
  943. }
  944. PyVar VM::vectorcall(int ARGC, int KWARGC, bool op_call) {
  945. PyVar* p1 = s_data._sp - KWARGC * 2;
  946. PyVar* p0 = p1 - ARGC - 2;
  947. // [callable, <self>, args..., kwargs...]
  948. // ^p0 ^p1 ^_sp
  949. PyVar callable = p1[-ARGC - 2];
  950. Type callable_t = _tp(callable);
  951. // handle boundmethod, do a patch
  952. if(callable_t == tp_bound_method) {
  953. assert(p0[1] == PY_NULL);
  954. BoundMethod& bm = PK_OBJ_GET(BoundMethod, callable);
  955. callable = bm.func; // get unbound method
  956. callable_t = _tp(callable);
  957. p1[-(ARGC + 2)] = bm.func;
  958. p1[-(ARGC + 1)] = bm.self;
  959. // [unbound, self, args..., kwargs...]
  960. }
  961. ArgsView args(p0[1] == PY_NULL ? (p0 + 2) : (p0 + 1), p1);
  962. ArgsView kwargs(p1, s_data._sp);
  963. PyVar* _base = args.begin();
  964. if(callable_t == tp_function) {
  965. /*****************_py_call*****************/
  966. // check stack overflow
  967. if(s_data.is_overflow()) StackOverflowError();
  968. const Function& fn = PK_OBJ_GET(Function, callable);
  969. const CodeObject* co = fn.decl->code.get();
  970. switch(fn.decl->type) {
  971. case FuncType::NORMAL:
  972. __prepare_py_call(__vectorcall_buffer, args, kwargs, fn.decl);
  973. // copy buffer back to stack
  974. s_data.reset(_base + co->nlocals);
  975. for(int j = 0; j < co->nlocals; j++)
  976. _base[j] = __vectorcall_buffer[j];
  977. break;
  978. case FuncType::SIMPLE:
  979. if(args.size() != fn.decl->args.size())
  980. TypeError(_S(co->name,
  981. "() takes ",
  982. fn.decl->args.size(),
  983. " positional arguments but ",
  984. args.size(),
  985. " were given"));
  986. if(!kwargs.empty()) TypeError(_S(co->name, "() takes no keyword arguments"));
  987. // [callable, <self>, args..., local_vars...]
  988. // ^p0 ^p1 ^_sp
  989. s_data.reset(_base + co->nlocals);
  990. // initialize local variables to PY_NULL
  991. std::memset(p1, 0, (char*)s_data._sp - (char*)p1);
  992. break;
  993. case FuncType::EMPTY:
  994. if(args.size() != fn.decl->args.size())
  995. TypeError(_S(co->name,
  996. "() takes ",
  997. fn.decl->args.size(),
  998. " positional arguments but ",
  999. args.size(),
  1000. " were given"));
  1001. if(!kwargs.empty()) TypeError(_S(co->name, "() takes no keyword arguments"));
  1002. s_data.reset(p0);
  1003. return None;
  1004. case FuncType::GENERATOR:
  1005. __prepare_py_call(__vectorcall_buffer, args, kwargs, fn.decl);
  1006. s_data.reset(p0);
  1007. callstack.emplace(nullptr, co, fn._module, callable.get(), nullptr);
  1008. return __py_generator(callstack.popx(),
  1009. ArgsView(__vectorcall_buffer, __vectorcall_buffer + co->nlocals));
  1010. default: PK_UNREACHABLE()
  1011. };
  1012. // simple or normal
  1013. callstack.emplace(p0, co, fn._module, callable.get(), args.begin());
  1014. if(op_call) return PY_OP_CALL;
  1015. return __run_top_frame();
  1016. /*****************_py_call*****************/
  1017. }
  1018. if(callable_t == tp_native_func) {
  1019. const auto& f = PK_OBJ_GET(NativeFunc, callable);
  1020. PyVar ret;
  1021. if(f.decl != nullptr) {
  1022. int co_nlocals = f.decl->code->nlocals;
  1023. __prepare_py_call(__vectorcall_buffer, args, kwargs, f.decl);
  1024. // copy buffer back to stack
  1025. s_data.reset(_base + co_nlocals);
  1026. for(int j = 0; j < co_nlocals; j++)
  1027. _base[j] = __vectorcall_buffer[j];
  1028. ret = f.call(vm, ArgsView(s_data._sp - co_nlocals, s_data._sp));
  1029. } else {
  1030. if(f.argc != -1) {
  1031. if(KWARGC != 0)
  1032. TypeError(
  1033. "old-style native_func does not accept keyword arguments. If you want to skip this check, specify `argc` to -1");
  1034. if(args.size() != f.argc) { vm->TypeError(_S("expected ", f.argc, " arguments, got ", args.size())); }
  1035. }
  1036. ret = f.call(this, args);
  1037. }
  1038. s_data.reset(p0);
  1039. return ret;
  1040. }
  1041. if(callable_t == tp_type) {
  1042. // [type, NULL, args..., kwargs...]
  1043. PyVar new_f = *find_name_in_mro(PK_OBJ_GET(Type, callable), __new__);
  1044. PyVar obj;
  1045. assert(new_f != nullptr && p0[1] == PY_NULL);
  1046. if(new_f == __cached_object_new) {
  1047. // fast path for object.__new__
  1048. obj = vm->new_object<DummyInstance>(PK_OBJ_GET(Type, callable));
  1049. } else {
  1050. PUSH(new_f);
  1051. PUSH(PY_NULL);
  1052. PUSH(callable); // cls
  1053. for(PyVar o: args)
  1054. PUSH(o);
  1055. for(PyVar o: kwargs)
  1056. PUSH(o);
  1057. // if obj is not an instance of `cls`, the behavior is undefined
  1058. obj = vectorcall(ARGC + 1, KWARGC);
  1059. }
  1060. // __init__
  1061. PyVar self;
  1062. callable = get_unbound_method(obj, __init__, &self, false);
  1063. if(callable != nullptr) {
  1064. callable_t = _tp(callable);
  1065. // replace `NULL` with `self`
  1066. p1[-(ARGC + 2)] = callable;
  1067. p1[-(ARGC + 1)] = self;
  1068. // [init_f, self, args..., kwargs...]
  1069. vectorcall(ARGC, KWARGC);
  1070. // We just discard the return value of `__init__`
  1071. // in cpython it raises a TypeError if the return value is not None
  1072. } else {
  1073. // manually reset the stack
  1074. s_data.reset(p0);
  1075. }
  1076. return obj;
  1077. }
  1078. // handle `__call__` overload
  1079. PyVar self;
  1080. PyVar call_f = get_unbound_method(callable, __call__, &self, false);
  1081. if(self != PY_NULL) {
  1082. p1[-(ARGC + 2)] = call_f;
  1083. p1[-(ARGC + 1)] = self;
  1084. // [call_f, self, args..., kwargs...]
  1085. return vectorcall(ARGC, KWARGC, op_call);
  1086. }
  1087. TypeError(_type_name(vm, callable_t).escape() + " object is not callable");
  1088. }
  1089. void VM::delattr(PyVar _0, StrName _name) {
  1090. const PyTypeInfo* ti = _tp_info(_0);
  1091. if(ti->m__delattr__ && ti->m__delattr__(this, _0, _name)) return;
  1092. if(is_tagged(_0) || !_0->is_attr_valid()) TypeError("cannot delete attribute");
  1093. if(!_0->attr().del(_name)) AttributeError(_0, _name);
  1094. }
  1095. // https://docs.python.org/3/howto/descriptor.html#invocation-from-an-instance
  1096. PyVar VM::getattr(PyVar obj, StrName name, bool throw_err) {
  1097. Type objtype(0);
  1098. // handle super() proxy
  1099. if(is_type(obj, tp_super)) {
  1100. const Super& super = PK_OBJ_GET(Super, obj);
  1101. obj = super.first;
  1102. objtype = super.second;
  1103. } else {
  1104. objtype = _tp(obj);
  1105. }
  1106. PyVar* cls_var = find_name_in_mro(objtype, name);
  1107. if(cls_var != nullptr) {
  1108. // handle descriptor
  1109. if(is_type(*cls_var, tp_property)) {
  1110. const Property& prop = PK_OBJ_GET(Property, *cls_var);
  1111. return call(prop.getter, obj);
  1112. }
  1113. }
  1114. // handle instance __dict__
  1115. if(!is_tagged(obj) && obj->is_attr_valid()) {
  1116. PyVar* val;
  1117. if(obj.type == tp_type) {
  1118. val = find_name_in_mro(PK_OBJ_GET(Type, obj), name);
  1119. if(val != nullptr) {
  1120. if(is_tagged(*val)) return *val;
  1121. if(val->type == tp_staticmethod) return PK_OBJ_GET(StaticMethod, *val).func;
  1122. if(val->type == tp_classmethod) return VAR(BoundMethod(obj, PK_OBJ_GET(ClassMethod, *val).func));
  1123. return *val;
  1124. }
  1125. } else {
  1126. val = obj->attr().try_get_2_likely_found(name);
  1127. if(val != nullptr) return *val;
  1128. }
  1129. }
  1130. if(cls_var != nullptr) {
  1131. // bound method is non-data descriptor
  1132. if(!is_tagged(*cls_var)) {
  1133. switch(cls_var->type.index) {
  1134. case tp_function.index: return VAR(BoundMethod(obj, *cls_var));
  1135. case tp_native_func.index: return VAR(BoundMethod(obj, *cls_var));
  1136. case tp_staticmethod.index: return PK_OBJ_GET(StaticMethod, *cls_var).func;
  1137. case tp_classmethod.index: return VAR(BoundMethod(_t(objtype), PK_OBJ_GET(ClassMethod, *cls_var).func));
  1138. }
  1139. }
  1140. return *cls_var;
  1141. }
  1142. const PyTypeInfo* ti = &_all_types[objtype];
  1143. if(ti->m__getattr__) {
  1144. PyVar ret = ti->m__getattr__(this, obj, name);
  1145. if(ret) return ret;
  1146. }
  1147. if(throw_err) AttributeError(obj, name);
  1148. return nullptr;
  1149. }
  1150. // used by OP_LOAD_METHOD
  1151. // try to load a unbound method (fallback to `getattr` if not found)
  1152. PyVar VM::get_unbound_method(PyVar obj, StrName name, PyVar* self, bool throw_err, bool fallback) {
  1153. self->set_null();
  1154. Type objtype(0);
  1155. // handle super() proxy
  1156. if(is_type(obj, tp_super)) {
  1157. const Super& super = PK_OBJ_GET(Super, obj);
  1158. obj = super.first;
  1159. objtype = super.second;
  1160. } else {
  1161. objtype = _tp(obj);
  1162. }
  1163. PyVar* cls_var = find_name_in_mro(objtype, name);
  1164. if(fallback) {
  1165. if(cls_var != nullptr) {
  1166. // handle descriptor
  1167. if(is_type(*cls_var, tp_property)) {
  1168. const Property& prop = PK_OBJ_GET(Property, *cls_var);
  1169. return call(prop.getter, obj);
  1170. }
  1171. }
  1172. // handle instance __dict__
  1173. if(!is_tagged(obj) && obj->is_attr_valid()) {
  1174. PyVar* val;
  1175. if(obj.type == tp_type) {
  1176. val = find_name_in_mro(PK_OBJ_GET(Type, obj), name);
  1177. if(val != nullptr) {
  1178. if(is_tagged(*val)) return *val;
  1179. if(val->type == tp_staticmethod) return PK_OBJ_GET(StaticMethod, *val).func;
  1180. if(val->type == tp_classmethod) return VAR(BoundMethod(obj, PK_OBJ_GET(ClassMethod, *val).func));
  1181. return *val;
  1182. }
  1183. } else {
  1184. val = obj->attr().try_get_2_likely_found(name);
  1185. if(val != nullptr) return *val;
  1186. }
  1187. }
  1188. }
  1189. if(cls_var != nullptr) {
  1190. if(!is_tagged(*cls_var)) {
  1191. switch(cls_var->type.index) {
  1192. case tp_function.index: *self = obj; break;
  1193. case tp_native_func.index: *self = obj; break;
  1194. case tp_staticmethod.index: self->set_null(); return PK_OBJ_GET(StaticMethod, *cls_var).func;
  1195. case tp_classmethod.index: *self = _t(objtype); return PK_OBJ_GET(ClassMethod, *cls_var).func;
  1196. }
  1197. }
  1198. return *cls_var;
  1199. }
  1200. const PyTypeInfo* ti = &_all_types[objtype];
  1201. if(fallback && ti->m__getattr__) {
  1202. PyVar ret = ti->m__getattr__(this, obj, name);
  1203. if(ret) return ret;
  1204. }
  1205. if(throw_err) AttributeError(obj, name);
  1206. return nullptr;
  1207. }
  1208. void VM::setattr(PyVar obj, StrName name, PyVar value) {
  1209. Type objtype(0);
  1210. // handle super() proxy
  1211. if(is_type(obj, tp_super)) {
  1212. Super& super = PK_OBJ_GET(Super, obj);
  1213. obj = super.first;
  1214. objtype = super.second;
  1215. } else {
  1216. objtype = _tp(obj);
  1217. }
  1218. PyVar* cls_var = find_name_in_mro(objtype, name);
  1219. if(cls_var != nullptr) {
  1220. // handle descriptor
  1221. if(is_type(*cls_var, tp_property)) {
  1222. const Property& prop = _CAST(Property&, *cls_var);
  1223. if(prop.setter != vm->None) {
  1224. call(prop.setter, obj, value);
  1225. } else {
  1226. TypeError(_S("readonly attribute: ", name.escape()));
  1227. }
  1228. return;
  1229. }
  1230. }
  1231. const PyTypeInfo* ti = &_all_types[objtype];
  1232. if(ti->m__setattr__) {
  1233. ti->m__setattr__(this, obj, name, value);
  1234. return;
  1235. }
  1236. // handle instance __dict__
  1237. if(is_tagged(obj) || !obj->is_attr_valid()) TypeError("cannot set attribute");
  1238. obj->attr().set(name, value);
  1239. }
  1240. PyObject* VM::bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, any userdata, BindType bt) {
  1241. PyObject* nf = heap.gcnew<NativeFunc>(tp_native_func, fn, argc, std::move(userdata));
  1242. switch(bt) {
  1243. case BindType::DEFAULT: break;
  1244. case BindType::STATICMETHOD: nf = heap.gcnew<StaticMethod>(tp_staticmethod, nf); break;
  1245. case BindType::CLASSMETHOD: nf = heap.gcnew<ClassMethod>(tp_classmethod, nf); break;
  1246. }
  1247. if(obj != nullptr) obj->attr().set(name, nf);
  1248. return nf;
  1249. }
  1250. PyObject* VM::bind(PyObject* obj, const char* sig, NativeFuncC fn, any userdata, BindType bt) {
  1251. return bind(obj, sig, nullptr, fn, std::move(userdata), bt);
  1252. }
  1253. PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, NativeFuncC fn, any userdata, BindType bt) {
  1254. CodeObject_ co;
  1255. try {
  1256. // fn(a, b, *c, d=1) -> None
  1257. co = compile(_S("def ", sig, " : pass"), "<bind>", EXEC_MODE);
  1258. } catch(TopLevelException) { throw std::runtime_error("invalid signature: " + std::string(sig)); }
  1259. if(co->func_decls.size() != 1) { throw std::runtime_error("expected 1 function declaration"); }
  1260. FuncDecl_ decl = co->func_decls[0];
  1261. decl->docstring = docstring;
  1262. PyObject* f_obj = heap.gcnew<NativeFunc>(tp_native_func, fn, decl, std::move(userdata));
  1263. switch(bt) {
  1264. case BindType::STATICMETHOD: f_obj = heap.gcnew<StaticMethod>(tp_staticmethod, f_obj); break;
  1265. case BindType::CLASSMETHOD: f_obj = heap.gcnew<ClassMethod>(tp_classmethod, f_obj); break;
  1266. case BindType::DEFAULT: break;
  1267. }
  1268. if(obj != nullptr) obj->attr().set(decl->code->name, f_obj);
  1269. return f_obj;
  1270. }
  1271. PyObject* VM::bind_property(PyObject* obj, const char* name, NativeFuncC fget, NativeFuncC fset) {
  1272. assert(is_type(obj, tp_type));
  1273. std::string_view name_sv(name);
  1274. int pos = name_sv.find(':');
  1275. if(pos > 0) name_sv = name_sv.substr(0, pos);
  1276. PyVar _0 = new_object<NativeFunc>(tp_native_func, fget, 1);
  1277. PyVar _1 = vm->None;
  1278. if(fset != nullptr) _1 = new_object<NativeFunc>(tp_native_func, fset, 2);
  1279. PyObject* prop = heap.gcnew<Property>(tp_property, _0, _1);
  1280. obj->attr().set(StrName(name_sv), prop);
  1281. return prop;
  1282. }
  1283. void VM::__builtin_error(StrName type) { _error(call(builtins->attr(type))); }
  1284. void VM::__builtin_error(StrName type, PyVar arg) { _error(call(builtins->attr(type), arg)); }
  1285. void VM::__builtin_error(StrName type, const Str& msg) { __builtin_error(type, VAR(msg)); }
  1286. void VM::BinaryOptError(const char* op, PyVar _0, PyVar _1) {
  1287. StrName name_0 = _type_name(vm, _tp(_0));
  1288. StrName name_1 = _type_name(vm, _tp(_1));
  1289. TypeError(_S("unsupported operand type(s) for ", op, ": ", name_0.escape(), " and ", name_1.escape()));
  1290. }
  1291. void VM::AttributeError(PyVar obj, StrName name) {
  1292. if(isinstance(obj, vm->tp_type)) {
  1293. __builtin_error(
  1294. "AttributeError",
  1295. _S("type object ", _type_name(vm, PK_OBJ_GET(Type, obj)).escape(), " has no attribute ", name.escape()));
  1296. } else {
  1297. __builtin_error("AttributeError",
  1298. _S(_type_name(vm, _tp(obj)).escape(), " object has no attribute ", name.escape()));
  1299. }
  1300. }
  1301. void VM::_error(PyVar e_obj) {
  1302. assert(isinstance(e_obj, tp_exception));
  1303. Exception& e = PK_OBJ_GET(Exception, e_obj);
  1304. if(callstack.empty()) {
  1305. e.is_re = false;
  1306. __last_exception = e_obj.get();
  1307. throw TopLevelException(this, &e);
  1308. }
  1309. PUSH(e_obj);
  1310. __raise_exc();
  1311. }
  1312. void VM::__raise_exc(bool re_raise) {
  1313. Frame* frame = &callstack.top();
  1314. Exception& e = PK_OBJ_GET(Exception, s_data.top());
  1315. if(!re_raise) {
  1316. e._ip_on_error = frame->ip();
  1317. e._code_on_error = (void*)frame->co;
  1318. }
  1319. int next_ip = frame->prepare_jump_exception_handler(&s_data);
  1320. int actual_ip = frame->ip();
  1321. if(e._ip_on_error >= 0 && e._code_on_error == (void*)frame->co) actual_ip = e._ip_on_error;
  1322. int current_line = frame->co->lines[actual_ip].lineno; // current line
  1323. auto current_f_name = frame->co->name.sv(); // current function name
  1324. if(frame->_callable == nullptr) current_f_name = ""; // not in a function
  1325. e.st_push(frame->co->src, current_line, nullptr, current_f_name);
  1326. if(next_ip >= 0) {
  1327. throw InternalException(InternalExceptionType::Handled, next_ip);
  1328. } else {
  1329. throw InternalException(InternalExceptionType::Unhandled);
  1330. }
  1331. }
  1332. StrName _type_name(VM* vm, Type type) { return vm->_all_types[type].name; }
  1333. void VM::bind__getitem__(Type type, PyVar (*f)(VM*, PyVar, PyVar)) {
  1334. _all_types[type].m__getitem__ = f;
  1335. bind_func(
  1336. type,
  1337. __getitem__,
  1338. 2,
  1339. [](VM* vm, ArgsView args) {
  1340. return lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0], args[1]);
  1341. },
  1342. f);
  1343. }
  1344. void VM::bind__setitem__(Type type, void (*f)(VM*, PyVar, PyVar, PyVar)) {
  1345. _all_types[type].m__setitem__ = f;
  1346. bind_func(
  1347. type,
  1348. __setitem__,
  1349. 3,
  1350. [](VM* vm, ArgsView args) {
  1351. lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0], args[1], args[2]);
  1352. return vm->None;
  1353. },
  1354. f);
  1355. }
  1356. void VM::bind__delitem__(Type type, void (*f)(VM*, PyVar, PyVar)) {
  1357. _all_types[type].m__delitem__ = f;
  1358. bind_func(
  1359. type,
  1360. __delitem__,
  1361. 2,
  1362. [](VM* vm, ArgsView args) {
  1363. lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0], args[1]);
  1364. return vm->None;
  1365. },
  1366. f);
  1367. }
  1368. PyVar VM::__pack_next_retval(unsigned n) {
  1369. if(n == 0) return StopIteration;
  1370. if(n == 1) return s_data.popx();
  1371. PyVar retval = VAR(s_data.view(n).to_tuple());
  1372. s_data._sp -= n;
  1373. return retval;
  1374. }
  1375. void VM::bind__next__(Type type, unsigned (*f)(VM*, PyVar)) {
  1376. _all_types[type].op__next__ = f;
  1377. bind_func(
  1378. type,
  1379. __next__,
  1380. 1,
  1381. [](VM* vm, ArgsView args) {
  1382. int n = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
  1383. return vm->__pack_next_retval(n);
  1384. },
  1385. f);
  1386. }
  1387. void VM::bind__next__(Type type, PyVar (*f)(VM*, PyVar)) {
  1388. bind_func(
  1389. type,
  1390. __next__,
  1391. 1,
  1392. [](VM* vm, ArgsView args) {
  1393. auto f = lambda_get_userdata<PyVar (*)(VM*, PyVar)>(args.begin());
  1394. return f(vm, args[0]);
  1395. },
  1396. f);
  1397. }
  1398. #define BIND_UNARY_SPECIAL(name) \
  1399. void VM::bind##name(Type type, PyVar (*f)(VM*, PyVar)) { \
  1400. _all_types[type].m##name = f; \
  1401. bind_func( \
  1402. type, \
  1403. name, \
  1404. 1, \
  1405. [](VM* vm, ArgsView args) { \
  1406. return lambda_get_userdata<PyVar (*)(VM*, PyVar)>(args.begin())(vm, args[0]); \
  1407. }, \
  1408. f); \
  1409. }
  1410. BIND_UNARY_SPECIAL(__iter__)
  1411. BIND_UNARY_SPECIAL(__neg__)
  1412. BIND_UNARY_SPECIAL(__invert__)
  1413. #undef BIND_UNARY_SPECIAL
  1414. void VM::bind__str__(Type type, Str (*f)(VM*, PyVar)) {
  1415. _all_types[type].m__str__ = f;
  1416. bind_func(
  1417. type,
  1418. __str__,
  1419. 1,
  1420. [](VM* vm, ArgsView args) {
  1421. Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
  1422. return VAR(s);
  1423. },
  1424. f);
  1425. }
  1426. void VM::bind__repr__(Type type, Str (*f)(VM*, PyVar)) {
  1427. _all_types[type].m__repr__ = f;
  1428. bind_func(
  1429. type,
  1430. __repr__,
  1431. 1,
  1432. [](VM* vm, ArgsView args) {
  1433. Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
  1434. return VAR(s);
  1435. },
  1436. f);
  1437. }
  1438. void VM::bind__hash__(Type type, i64 (*f)(VM*, PyVar)) {
  1439. _all_types[type].m__hash__ = f;
  1440. bind_func(
  1441. type,
  1442. __hash__,
  1443. 1,
  1444. [](VM* vm, ArgsView args) {
  1445. i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
  1446. return VAR(ret);
  1447. },
  1448. f);
  1449. }
  1450. void VM::bind__len__(Type type, i64 (*f)(VM*, PyVar)) {
  1451. _all_types[type].m__len__ = f;
  1452. bind_func(
  1453. type,
  1454. __len__,
  1455. 1,
  1456. [](VM* vm, ArgsView args) {
  1457. i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
  1458. return VAR(ret);
  1459. },
  1460. f);
  1461. }
  1462. #define BIND_BINARY_SPECIAL(name) \
  1463. void VM::bind##name(Type type, BinaryFuncC f) { \
  1464. _all_types[type].m##name = f; \
  1465. bind_func( \
  1466. type, \
  1467. name, \
  1468. 2, \
  1469. [](VM* vm, ArgsView args) { \
  1470. return lambda_get_userdata<BinaryFuncC>(args.begin())(vm, args[0], args[1]); \
  1471. }, \
  1472. f); \
  1473. }
  1474. BIND_BINARY_SPECIAL(__eq__)
  1475. BIND_BINARY_SPECIAL(__lt__)
  1476. BIND_BINARY_SPECIAL(__le__)
  1477. BIND_BINARY_SPECIAL(__gt__)
  1478. BIND_BINARY_SPECIAL(__ge__)
  1479. BIND_BINARY_SPECIAL(__contains__)
  1480. BIND_BINARY_SPECIAL(__add__)
  1481. BIND_BINARY_SPECIAL(__sub__)
  1482. BIND_BINARY_SPECIAL(__mul__)
  1483. BIND_BINARY_SPECIAL(__truediv__)
  1484. BIND_BINARY_SPECIAL(__floordiv__)
  1485. BIND_BINARY_SPECIAL(__mod__)
  1486. BIND_BINARY_SPECIAL(__pow__)
  1487. BIND_BINARY_SPECIAL(__matmul__)
  1488. BIND_BINARY_SPECIAL(__lshift__)
  1489. BIND_BINARY_SPECIAL(__rshift__)
  1490. BIND_BINARY_SPECIAL(__and__)
  1491. BIND_BINARY_SPECIAL(__or__)
  1492. BIND_BINARY_SPECIAL(__xor__)
  1493. #undef BIND_BINARY_SPECIAL
  1494. void Dict::_probe_0(VM* vm, PyVar key, bool& ok, int& i) const {
  1495. ok = false;
  1496. i64 hash = vm->py_hash(key);
  1497. i = hash & _mask;
  1498. for(int j = 0; j < _capacity; j++) {
  1499. if(_items[i].first != nullptr) {
  1500. if(vm->py_eq(_items[i].first, key)) {
  1501. ok = true;
  1502. break;
  1503. }
  1504. } else {
  1505. if(_items[i].second == nullptr) break;
  1506. }
  1507. // https://github.com/python/cpython/blob/3.8/Objects/dictobject.c#L166
  1508. i = ((5 * i) + 1) & _mask;
  1509. }
  1510. }
  1511. void Dict::_probe_1(VM* vm, PyVar key, bool& ok, int& i) const {
  1512. ok = false;
  1513. i = vm->py_hash(key) & _mask;
  1514. while(_items[i].first != nullptr) {
  1515. if(vm->py_eq(_items[i].first, key)) {
  1516. ok = true;
  1517. break;
  1518. }
  1519. // https://github.com/python/cpython/blob/3.8/Objects/dictobject.c#L166
  1520. i = ((5 * i) + 1) & _mask;
  1521. }
  1522. }
  1523. #if PK_ENABLE_PROFILER
  1524. void NextBreakpoint::_step(VM* vm) {
  1525. int curr_callstack_size = vm->callstack.size();
  1526. int curr_lineno = vm->callstack.top().curr_lineno();
  1527. if(should_step_into) {
  1528. if(curr_callstack_size != callstack_size || curr_lineno != lineno) { vm->__breakpoint(); }
  1529. } else {
  1530. if(curr_callstack_size == callstack_size) {
  1531. if(curr_lineno != lineno) vm->__breakpoint();
  1532. } else if(curr_callstack_size < callstack_size) {
  1533. // returning
  1534. vm->__breakpoint();
  1535. }
  1536. }
  1537. }
  1538. #endif
  1539. void VM::__pop_frame() {
  1540. s_data.reset(callstack.top()._sp_base);
  1541. callstack.pop();
  1542. #if PK_ENABLE_PROFILER
  1543. if(!_next_breakpoint.empty() && callstack.size() < _next_breakpoint.callstack_size) {
  1544. _next_breakpoint = NextBreakpoint();
  1545. }
  1546. #endif
  1547. }
  1548. void VM::__breakpoint() {
  1549. #if PK_ENABLE_PROFILER
  1550. _next_breakpoint = NextBreakpoint();
  1551. bool show_where = false;
  1552. bool show_headers = true;
  1553. while(true) {
  1554. vector<LinkedFrame*> frames;
  1555. LinkedFrame* lf = callstack._tail;
  1556. while(lf != nullptr) {
  1557. frames.push_back(lf);
  1558. lf = lf->f_back;
  1559. if(frames.size() >= 4) break;
  1560. }
  1561. if(show_headers) {
  1562. for(int i = frames.size() - 1; i >= 0; i--) {
  1563. if(!show_where && i != 0) continue;
  1564. SStream ss;
  1565. Frame* frame = &frames[i]->frame;
  1566. int lineno = frame->curr_lineno();
  1567. ss << "File \"" << frame->co->src->filename << "\", line " << lineno;
  1568. if(frame->_callable) {
  1569. ss << ", in ";
  1570. ss << frame->_callable->as<Function>().decl->code->name;
  1571. }
  1572. ss << '\n';
  1573. ss << "-> " << frame->co->src->get_line(lineno) << '\n';
  1574. stdout_write(ss.str());
  1575. }
  1576. show_headers = false;
  1577. }
  1578. vm->stdout_write("(Pdb) ");
  1579. Frame* frame_0 = &frames[0]->frame;
  1580. std::string line;
  1581. if(!std::getline(std::cin, line)) {
  1582. stdout_write("--KeyboardInterrupt--\n");
  1583. continue;
  1584. }
  1585. if(line == "h" || line == "help") {
  1586. stdout_write("h, help: show this help message\n");
  1587. stdout_write("q, quit: exit the debugger\n");
  1588. stdout_write("n, next: execute next line\n");
  1589. stdout_write("s, step: step into\n");
  1590. stdout_write("w, where: show current stack frame\n");
  1591. stdout_write("c, continue: continue execution\n");
  1592. stdout_write("a, args: show local variables\n");
  1593. stdout_write("p, print <expr>: evaluate expression\n");
  1594. stdout_write("l, list: show lines around current line\n");
  1595. stderr_write("ll, longlist: show all lines\n");
  1596. stdout_write("!: execute statement\n");
  1597. continue;
  1598. }
  1599. if(line == "q" || line == "quit") { vm->RuntimeError("pdb quit"); }
  1600. if(line == "n" || line == "next") {
  1601. vm->_next_breakpoint = NextBreakpoint(vm->callstack.size(), frame_0->curr_lineno(), false);
  1602. break;
  1603. }
  1604. if(line == "s" || line == "step") {
  1605. vm->_next_breakpoint = NextBreakpoint(vm->callstack.size(), frame_0->curr_lineno(), true);
  1606. break;
  1607. }
  1608. if(line == "w" || line == "where") {
  1609. show_where = !show_where;
  1610. show_headers = true;
  1611. continue;
  1612. }
  1613. if(line == "c" || line == "continue") break;
  1614. if(line == "a" || line == "args") {
  1615. int i = 0;
  1616. for(PyVar obj: frame_0->_locals) {
  1617. if(obj == PY_NULL) continue;
  1618. StrName name = frame_0->co->varnames[i++];
  1619. stdout_write(_S(name.sv(), " = ", vm->py_repr(obj), '\n'));
  1620. }
  1621. continue;
  1622. }
  1623. bool is_list = line == "l" || line == "list";
  1624. bool is_longlist = line == "ll" || line == "longlist";
  1625. if(is_list || is_longlist) {
  1626. if(frame_0->co->src->is_precompiled) continue;
  1627. int lineno = frame_0->curr_lineno();
  1628. int start, end;
  1629. if(is_list) {
  1630. int max_line = frame_0->co->src->line_starts.size() + 1;
  1631. start = (std::max)(1, lineno - 5);
  1632. end = (std::min)(max_line, lineno + 5);
  1633. } else {
  1634. start = frame_0->co->start_line;
  1635. end = frame_0->co->end_line;
  1636. if(start == -1 || end == -1) continue;
  1637. }
  1638. SStream ss;
  1639. int max_width = std::to_string(end).size();
  1640. for(int i = start; i <= end; i++) {
  1641. int spaces = max_width - std::to_string(i).size();
  1642. ss << std::string(spaces, ' ') << std::to_string(i);
  1643. if(i == lineno)
  1644. ss << " -> ";
  1645. else
  1646. ss << " ";
  1647. ss << frame_0->co->src->get_line(i) << '\n';
  1648. }
  1649. stdout_write(ss.str());
  1650. continue;
  1651. }
  1652. int space = line.find_first_of(' ');
  1653. if(space != -1) {
  1654. std::string cmd = line.substr(0, space);
  1655. std::string arg = line.substr(space + 1);
  1656. if(arg.empty()) continue; // ignore empty command
  1657. if(cmd == "p" || cmd == "print") {
  1658. CodeObject_ code = compile(arg, "<stdin>", EVAL_MODE, true);
  1659. PyVar retval = vm->_exec(code.get(), frame_0->_module, frame_0->_callable, frame_0->_locals);
  1660. stdout_write(vm->py_repr(retval));
  1661. stdout_write("\n");
  1662. } else if(cmd == "!") {
  1663. CodeObject_ code = compile(arg, "<stdin>", EXEC_MODE, true);
  1664. vm->_exec(code.get(), frame_0->_module, frame_0->_callable, frame_0->_locals);
  1665. }
  1666. continue;
  1667. }
  1668. }
  1669. #endif
  1670. }
  1671. /**************************************************************************/
  1672. void Function::_gc_mark(VM* vm) const {
  1673. decl->_gc_mark(vm);
  1674. if(_closure) {
  1675. _closure->apply([](StrName _, PyVar obj, void* userdata) {
  1676. VM* vm = (VM*)userdata;
  1677. vm->obj_gc_mark(obj);
  1678. }, vm);
  1679. }
  1680. }
  1681. void NativeFunc::_gc_mark(VM* vm) const {
  1682. if(decl) decl->_gc_mark(vm);
  1683. }
  1684. void FuncDecl::_gc_mark(VM* vm) const {
  1685. code->_gc_mark(vm);
  1686. for(int i = 0; i < kwargs.size(); i++)
  1687. vm->obj_gc_mark(kwargs[i].value);
  1688. }
  1689. void List::_gc_mark(VM* vm) const {
  1690. for(PyVar obj: *this)
  1691. vm->obj_gc_mark(obj);
  1692. }
  1693. void Tuple::_gc_mark(VM* vm) const {
  1694. for(PyVar obj: *this)
  1695. vm->obj_gc_mark(obj);
  1696. }
  1697. void MappingProxy::_gc_mark(VM* vm) const { vm->__obj_gc_mark(obj); }
  1698. void BoundMethod::_gc_mark(VM* vm) const {
  1699. vm->obj_gc_mark(func);
  1700. vm->obj_gc_mark(self);
  1701. }
  1702. void StarWrapper::_gc_mark(VM* vm) const { vm->obj_gc_mark(obj); }
  1703. void StaticMethod::_gc_mark(VM* vm) const { vm->obj_gc_mark(func); }
  1704. void ClassMethod::_gc_mark(VM* vm) const { vm->obj_gc_mark(func); }
  1705. void Property::_gc_mark(VM* vm) const {
  1706. vm->obj_gc_mark(getter);
  1707. vm->obj_gc_mark(setter);
  1708. }
  1709. void Slice::_gc_mark(VM* vm) const {
  1710. vm->obj_gc_mark(start);
  1711. vm->obj_gc_mark(stop);
  1712. vm->obj_gc_mark(step);
  1713. }
  1714. void Super::_gc_mark(VM* vm) const { vm->obj_gc_mark(first); }
  1715. void Frame::_gc_mark(VM* vm) const {
  1716. vm->obj_gc_mark(_module);
  1717. co->_gc_mark(vm);
  1718. // Frame could be stored in a generator, so mark _callable for safety
  1719. vm->obj_gc_mark(_callable);
  1720. }
  1721. void ManagedHeap::mark() {
  1722. for(PyObject* obj: _no_gc)
  1723. vm->__obj_gc_mark(obj);
  1724. vm->callstack.apply([this](Frame& frame) {
  1725. frame._gc_mark(vm);
  1726. });
  1727. for(auto [_, co]: vm->__cached_codes)
  1728. co->_gc_mark(vm);
  1729. vm->obj_gc_mark(vm->__last_exception);
  1730. vm->obj_gc_mark(vm->__curr_class);
  1731. vm->obj_gc_mark(vm->__c.error);
  1732. vm->__stack_gc_mark(vm->s_data.begin(), vm->s_data.end());
  1733. if(_gc_marker_ex) _gc_marker_ex(vm);
  1734. }
  1735. void ManagedHeap::_delete(PyObject* obj) {
  1736. const PyTypeInfo* ti = vm->_tp_info(obj->type);
  1737. if(ti->vt._dtor) ti->vt._dtor(obj->_value_ptr());
  1738. delete obj->_attr; // delete __dict__ if exists
  1739. PoolObject_dealloc(obj);
  1740. }
  1741. void Dict::_gc_mark(VM* vm) const {
  1742. apply([vm](PyVar k, PyVar v) {
  1743. vm->obj_gc_mark(k);
  1744. vm->obj_gc_mark(v);
  1745. });
  1746. }
  1747. void CodeObject::_gc_mark(VM* vm) const {
  1748. for(PyVar v: consts)
  1749. vm->obj_gc_mark(v);
  1750. for(auto& decl: func_decls)
  1751. decl->_gc_mark(vm);
  1752. }
  1753. } // namespace pkpy