modules.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881
  1. #include "pocketpy/common/str.h"
  2. #include "pocketpy/objects/base.h"
  3. #include "pocketpy/objects/codeobject.h"
  4. #include "pocketpy/pocketpy.h"
  5. #include "pocketpy/common/utils.h"
  6. #include "pocketpy/objects/object.h"
  7. #include "pocketpy/common/sstream.h"
  8. #include "pocketpy/interpreter/vm.h"
  9. #include "pocketpy/common/_generated.h"
  10. #include <ctype.h>
  11. #include <math.h>
  12. py_Ref py_getmodule(const char* path) {
  13. VM* vm = pk_current_vm;
  14. return ModuleDict__try_get(&vm->modules, path);
  15. }
  16. py_Ref py_getbuiltin(py_Name name) { return py_getdict(&pk_current_vm->builtins, name); }
  17. py_Ref py_getglobal(py_Name name) { return py_getdict(&pk_current_vm->main, name); }
  18. void py_setglobal(py_Name name, py_Ref val) { py_setdict(&pk_current_vm->main, name, val); }
  19. py_Ref py_newmodule(const char* path) {
  20. ManagedHeap* heap = &pk_current_vm->heap;
  21. if(strlen(path) > PK_MAX_MODULE_PATH_LEN) c11__abort("module path too long: %s", path);
  22. py_Ref r0 = py_pushtmp();
  23. py_Ref r1 = py_pushtmp();
  24. *r0 = (py_TValue){
  25. .type = tp_module,
  26. .is_ptr = true,
  27. ._obj = ManagedHeap__new(heap, tp_module, -1, 0),
  28. };
  29. int last_dot = c11_sv__rindex((c11_sv){path, strlen(path)}, '.');
  30. if(last_dot == -1) {
  31. py_newstr(r1, path);
  32. py_setdict(r0, __name__, r1);
  33. py_newstr(r1, "");
  34. py_setdict(r0, __package__, r1);
  35. } else {
  36. const char* start = path + last_dot + 1;
  37. py_newstr(r1, start);
  38. py_setdict(r0, __name__, r1);
  39. py_newstrv(r1, (c11_sv){path, last_dot});
  40. py_setdict(r0, __package__, r1);
  41. }
  42. py_newstr(r1, path);
  43. py_setdict(r0, __path__, r1);
  44. // we do not allow override in order to avoid memory leak
  45. // it is because Module objects are not garbage collected
  46. bool exists = ModuleDict__contains(&pk_current_vm->modules, path);
  47. if(exists) c11__abort("module '%s' already exists", path);
  48. // convert to a weak (const char*)
  49. path = py_tostr(py_getdict(r0, __path__));
  50. ModuleDict__set(&pk_current_vm->modules, path, *r0);
  51. py_shrink(2);
  52. return py_getmodule(path);
  53. }
  54. int load_module_from_dll_desktop_only(const char* path) PY_RAISE PY_RETURN;
  55. int py_import(const char* path_cstr) {
  56. VM* vm = pk_current_vm;
  57. c11_sv path = {path_cstr, strlen(path_cstr)};
  58. if(path.size == 0) return ValueError("empty module name");
  59. if(path.data[0] == '.') {
  60. // try relative import
  61. int dot_count = 1;
  62. while(dot_count < path.size && path.data[dot_count] == '.')
  63. dot_count++;
  64. c11_sv top_filename = c11_string__sv(vm->top_frame->co->src->filename);
  65. int is_init = c11_sv__endswith(top_filename, (c11_sv){"__init__.py", 11});
  66. py_Ref package = py_getdict(vm->top_frame->module, __path__);
  67. c11_sv package_sv = py_tosv(package);
  68. if(package_sv.size == 0) {
  69. return ImportError("attempted relative import with no known parent package");
  70. }
  71. c11_vector /* T=c11_sv */ cpnts = c11_sv__split(package_sv, '.');
  72. for(int i = is_init; i < dot_count; i++) {
  73. if(cpnts.length == 0)
  74. return ImportError("attempted relative import beyond top-level package");
  75. c11_vector__pop(&cpnts);
  76. }
  77. if(dot_count < path.size) {
  78. c11_sv last_cpnt = c11_sv__slice(path, dot_count);
  79. c11_vector__push(c11_sv, &cpnts, last_cpnt);
  80. }
  81. // join cpnts
  82. c11_sbuf buf;
  83. c11_sbuf__ctor(&buf);
  84. for(int i = 0; i < cpnts.length; i++) {
  85. if(i > 0) c11_sbuf__write_char(&buf, '.');
  86. c11_sbuf__write_sv(&buf, c11__getitem(c11_sv, &cpnts, i));
  87. }
  88. c11_vector__dtor(&cpnts);
  89. c11_string* new_path = c11_sbuf__submit(&buf);
  90. int res = py_import(new_path->data);
  91. c11_string__delete(new_path);
  92. return res;
  93. }
  94. assert(path.data[0] != '.' && path.data[path.size - 1] != '.');
  95. // check existing module
  96. py_GlobalRef ext_mod = py_getmodule(path.data);
  97. if(ext_mod) {
  98. py_assign(py_retval(), ext_mod);
  99. return true;
  100. }
  101. // try import
  102. c11_string* slashed_path = c11_sv__replace(path, '.', PK_PLATFORM_SEP);
  103. c11_string* filename = c11_string__new3("%s.py", slashed_path->data);
  104. bool need_free = true;
  105. const char* data = load_kPythonLib(path_cstr);
  106. if(data != NULL) {
  107. need_free = false;
  108. goto __SUCCESS;
  109. }
  110. data = vm->callbacks.importfile(filename->data);
  111. if(data != NULL) goto __SUCCESS;
  112. c11_string__delete(filename);
  113. filename = c11_string__new3("%s%c__init__.py", slashed_path->data, PK_PLATFORM_SEP);
  114. data = vm->callbacks.importfile(filename->data);
  115. if(data != NULL) goto __SUCCESS;
  116. c11_string__delete(filename);
  117. c11_string__delete(slashed_path);
  118. // not found
  119. return load_module_from_dll_desktop_only(path_cstr);
  120. __SUCCESS:
  121. do {
  122. } while(0);
  123. py_GlobalRef mod = py_newmodule(path_cstr);
  124. bool ok = py_exec((const char*)data, filename->data, EXEC_MODE, mod);
  125. py_assign(py_retval(), mod);
  126. c11_string__delete(filename);
  127. c11_string__delete(slashed_path);
  128. if(need_free) PK_FREE((void*)data);
  129. return ok ? 1 : -1;
  130. }
  131. bool py_importlib_reload(py_GlobalRef module) {
  132. VM* vm = pk_current_vm;
  133. c11_sv path = py_tosv(py_getdict(module, __path__));
  134. c11_string* slashed_path = c11_sv__replace(path, '.', PK_PLATFORM_SEP);
  135. c11_string* filename = c11_string__new3("%s.py", slashed_path->data);
  136. char* data = vm->callbacks.importfile(filename->data);
  137. if(data == NULL) {
  138. c11_string__delete(filename);
  139. filename = c11_string__new3("%s%c__init__.py", slashed_path->data, PK_PLATFORM_SEP);
  140. data = vm->callbacks.importfile(filename->data);
  141. }
  142. c11_string__delete(slashed_path);
  143. if(data == NULL) return ImportError("module '%v' not found", path);
  144. bool ok = py_exec(data, filename->data, EXEC_MODE, module);
  145. c11_string__delete(filename);
  146. PK_FREE(data);
  147. py_assign(py_retval(), module);
  148. return ok;
  149. }
  150. //////////////////////////
  151. static bool builtins_exit(int argc, py_Ref argv) {
  152. int code = 0;
  153. if(argc > 1) return TypeError("exit() takes at most 1 argument");
  154. if(argc == 1) {
  155. PY_CHECK_ARG_TYPE(0, tp_int);
  156. code = py_toint(argv);
  157. }
  158. exit(code);
  159. return false;
  160. }
  161. static bool builtins_input(int argc, py_Ref argv) {
  162. if(argc > 1) return TypeError("input() takes at most 1 argument");
  163. const char* prompt = "";
  164. if(argc == 1) {
  165. if(!py_checkstr(argv)) return false;
  166. prompt = py_tostr(argv);
  167. }
  168. py_callbacks()->print(prompt);
  169. c11_sbuf buf;
  170. c11_sbuf__ctor(&buf);
  171. while(true) {
  172. int c = py_callbacks()->getchar();
  173. if(c == '\n' || c == '\r') break;
  174. if(c == EOF) break;
  175. c11_sbuf__write_char(&buf, c);
  176. }
  177. c11_sbuf__py_submit(&buf, py_retval());
  178. return true;
  179. }
  180. static bool builtins_repr(int argc, py_Ref argv) {
  181. PY_CHECK_ARGC(1);
  182. return py_repr(argv);
  183. }
  184. static bool builtins_len(int argc, py_Ref argv) {
  185. PY_CHECK_ARGC(1);
  186. return py_len(argv);
  187. }
  188. static bool builtins_hex(int argc, py_Ref argv) {
  189. PY_CHECK_ARGC(1);
  190. PY_CHECK_ARG_TYPE(0, tp_int);
  191. py_i64 val = py_toint(argv);
  192. if(val == 0) {
  193. py_newstr(py_retval(), "0x0");
  194. return true;
  195. }
  196. c11_sbuf ss;
  197. c11_sbuf__ctor(&ss);
  198. if(val < 0) {
  199. c11_sbuf__write_char(&ss, '-');
  200. val = -val;
  201. }
  202. c11_sbuf__write_cstr(&ss, "0x");
  203. bool non_zero = true;
  204. for(int i = 56; i >= 0; i -= 8) {
  205. unsigned char cpnt = (val >> i) & 0xff;
  206. c11_sbuf__write_hex(&ss, cpnt, non_zero);
  207. if(cpnt != 0) non_zero = false;
  208. }
  209. c11_sbuf__py_submit(&ss, py_retval());
  210. return true;
  211. }
  212. static bool builtins_iter(int argc, py_Ref argv) {
  213. PY_CHECK_ARGC(1);
  214. return py_iter(argv);
  215. }
  216. static bool builtins_next(int argc, py_Ref argv) {
  217. if(argc == 0 || argc > 2) return TypeError("next() takes 1 or 2 arguments");
  218. int res = py_next(argv);
  219. if(res == -1) return false;
  220. if(res) return true;
  221. if(argc == 1) {
  222. // StopIteration stored in py_retval()
  223. return py_raise(py_retval());
  224. } else {
  225. py_assign(py_retval(), py_arg(1));
  226. return true;
  227. }
  228. }
  229. static bool builtins_hash(int argc, py_Ref argv) {
  230. PY_CHECK_ARGC(1);
  231. py_i64 val;
  232. if(!py_hash(argv, &val)) return false;
  233. py_newint(py_retval(), val);
  234. return true;
  235. }
  236. static bool builtins_abs(int argc, py_Ref argv) {
  237. PY_CHECK_ARGC(1);
  238. return pk_callmagic(__abs__, 1, argv);
  239. }
  240. static bool builtins_divmod(int argc, py_Ref argv) {
  241. PY_CHECK_ARGC(2);
  242. return pk_callmagic(__divmod__, 2, argv);
  243. }
  244. static bool builtins_round(int argc, py_Ref argv) {
  245. py_i64 ndigits;
  246. if(argc == 1) {
  247. ndigits = -1;
  248. } else if(argc == 2) {
  249. PY_CHECK_ARG_TYPE(1, tp_int);
  250. ndigits = py_toint(py_arg(1));
  251. if(ndigits < 0) return ValueError("ndigits should be non-negative");
  252. } else {
  253. return TypeError("round() takes 1 or 2 arguments");
  254. }
  255. if(argv->type == tp_int) {
  256. py_assign(py_retval(), py_arg(0));
  257. return true;
  258. } else if(argv->type == tp_float) {
  259. py_f64 x = py_tofloat(py_arg(0));
  260. py_f64 offset = x >= 0 ? 0.5 : -0.5;
  261. if(ndigits == -1) {
  262. py_newint(py_retval(), (py_i64)(x + offset));
  263. return true;
  264. }
  265. py_f64 factor = pow(10, ndigits);
  266. py_newfloat(py_retval(), (py_i64)(x * factor + offset) / factor);
  267. return true;
  268. }
  269. return pk_callmagic(__round__, argc, argv);
  270. }
  271. static bool builtins_print(int argc, py_Ref argv) {
  272. // print(*args, sep=' ', end='\n', flush=False)
  273. py_TValue* args = py_tuple_data(argv);
  274. int length = py_tuple_len(argv);
  275. PY_CHECK_ARG_TYPE(1, tp_str);
  276. PY_CHECK_ARG_TYPE(2, tp_str);
  277. PY_CHECK_ARG_TYPE(3, tp_bool);
  278. c11_sv sep = py_tosv(py_arg(1));
  279. c11_sv end = py_tosv(py_arg(2));
  280. bool flush = py_tobool(py_arg(3));
  281. c11_sbuf buf;
  282. c11_sbuf__ctor(&buf);
  283. for(int i = 0; i < length; i++) {
  284. if(i > 0) c11_sbuf__write_sv(&buf, sep);
  285. if(!py_str(&args[i])) {
  286. c11_sbuf__dtor(&buf);
  287. return false;
  288. }
  289. c11_sbuf__write_sv(&buf, py_tosv(py_retval()));
  290. }
  291. c11_sbuf__write_sv(&buf, end);
  292. c11_string* res = c11_sbuf__submit(&buf);
  293. py_callbacks()->print(res->data);
  294. if(flush) py_callbacks()->flush();
  295. c11_string__delete(res);
  296. py_newnone(py_retval());
  297. return true;
  298. }
  299. static bool builtins_isinstance(int argc, py_Ref argv) {
  300. PY_CHECK_ARGC(2);
  301. if(py_istuple(py_arg(1))) {
  302. int length = py_tuple_len(py_arg(1));
  303. for(int i = 0; i < length; i++) {
  304. py_Ref item = py_tuple_getitem(py_arg(1), i);
  305. if(!py_checktype(item, tp_type)) return false;
  306. if(py_isinstance(py_arg(0), py_totype(item))) {
  307. py_newbool(py_retval(), true);
  308. return true;
  309. }
  310. }
  311. py_newbool(py_retval(), false);
  312. return true;
  313. }
  314. if(!py_checktype(py_arg(1), tp_type)) return false;
  315. py_newbool(py_retval(), py_isinstance(py_arg(0), py_totype(py_arg(1))));
  316. return true;
  317. }
  318. static bool builtins_issubclass(int argc, py_Ref argv) {
  319. PY_CHECK_ARGC(2);
  320. if(!py_checktype(py_arg(0), tp_type)) return false;
  321. if(!py_checktype(py_arg(1), tp_type)) return false;
  322. py_newbool(py_retval(), py_issubclass(py_totype(py_arg(0)), py_totype(py_arg(1))));
  323. return true;
  324. }
  325. bool py_callable(py_Ref val) {
  326. switch(val->type) {
  327. case tp_nativefunc: return true;
  328. case tp_function: return true;
  329. case tp_type: return true;
  330. case tp_boundmethod: return true;
  331. case tp_staticmethod: return true;
  332. case tp_classmethod: return true;
  333. default: return py_tpfindmagic(val->type, __call__);
  334. }
  335. }
  336. static bool builtins_callable(int argc, py_Ref argv) {
  337. PY_CHECK_ARGC(1);
  338. bool res = py_callable(py_arg(0));
  339. py_newbool(py_retval(), res);
  340. return true;
  341. }
  342. static bool builtins_getattr(int argc, py_Ref argv) {
  343. PY_CHECK_ARG_TYPE(1, tp_str);
  344. py_Name name = py_namev(py_tosv(py_arg(1)));
  345. if(argc == 2) {
  346. return py_getattr(py_arg(0), name);
  347. } else if(argc == 3) {
  348. bool ok = py_getattr(py_arg(0), name);
  349. if(!ok && py_matchexc(tp_AttributeError)) {
  350. py_clearexc(NULL);
  351. py_assign(py_retval(), py_arg(2));
  352. return true; // default value
  353. }
  354. return ok;
  355. } else {
  356. return TypeError("getattr() expected 2 or 3 arguments");
  357. }
  358. return true;
  359. }
  360. static bool builtins_setattr(int argc, py_Ref argv) {
  361. PY_CHECK_ARGC(3);
  362. PY_CHECK_ARG_TYPE(1, tp_str);
  363. py_Name name = py_namev(py_tosv(py_arg(1)));
  364. py_newnone(py_retval());
  365. return py_setattr(py_arg(0), name, py_arg(2));
  366. }
  367. static bool builtins_hasattr(int argc, py_Ref argv) {
  368. PY_CHECK_ARGC(2);
  369. PY_CHECK_ARG_TYPE(1, tp_str);
  370. py_Name name = py_namev(py_tosv(py_arg(1)));
  371. bool ok = py_getattr(py_arg(0), name);
  372. if(ok) {
  373. py_newbool(py_retval(), true);
  374. return true;
  375. }
  376. if(py_matchexc(tp_AttributeError)) {
  377. py_clearexc(NULL);
  378. py_newbool(py_retval(), false);
  379. return true;
  380. }
  381. return false;
  382. }
  383. static bool builtins_delattr(int argc, py_Ref argv) {
  384. PY_CHECK_ARGC(2);
  385. PY_CHECK_ARG_TYPE(1, tp_str);
  386. py_Name name = py_namev(py_tosv(py_arg(1)));
  387. py_newnone(py_retval());
  388. return py_delattr(py_arg(0), name);
  389. }
  390. static bool builtins_chr(int argc, py_Ref argv) {
  391. PY_CHECK_ARGC(1);
  392. PY_CHECK_ARG_TYPE(0, tp_int);
  393. uint32_t val = py_toint(py_arg(0));
  394. // convert to utf-8
  395. char utf8[4];
  396. int len = c11__u32_to_u8(val, utf8);
  397. if(len == -1) return ValueError("invalid unicode code point: %d", val);
  398. py_newstrv(py_retval(), (c11_sv){utf8, len});
  399. return true;
  400. }
  401. static bool builtins_ord(int argc, py_Ref argv) {
  402. PY_CHECK_ARGC(1);
  403. PY_CHECK_ARG_TYPE(0, tp_str);
  404. c11_sv sv = py_tosv(py_arg(0));
  405. if(c11_sv__u8_length(sv) != 1) {
  406. return TypeError("ord() expected a character, but string of length %d found",
  407. c11_sv__u8_length(sv));
  408. }
  409. int u8bytes = c11__u8_header(sv.data[0], true);
  410. if(u8bytes == 0) return ValueError("invalid utf-8 char: %c", sv.data[0]);
  411. int value = c11__u8_value(u8bytes, sv.data);
  412. py_newint(py_retval(), value);
  413. return true;
  414. }
  415. static bool builtins_id(int argc, py_Ref argv) {
  416. PY_CHECK_ARGC(1);
  417. if(argv->is_ptr) {
  418. py_newint(py_retval(), (intptr_t)argv->_obj);
  419. } else {
  420. py_newnone(py_retval());
  421. }
  422. return true;
  423. }
  424. static bool builtins_globals(int argc, py_Ref argv) {
  425. PY_CHECK_ARGC(0);
  426. py_newglobals(py_retval());
  427. return true;
  428. }
  429. static bool builtins_locals(int argc, py_Ref argv) {
  430. PY_CHECK_ARGC(0);
  431. py_newlocals(py_retval());
  432. return true;
  433. }
  434. void py_newglobals(py_OutRef out) {
  435. py_Frame* frame = pk_current_vm->top_frame;
  436. py_Frame_newglobals(frame, out);
  437. }
  438. void py_newlocals(py_OutRef out) {
  439. py_Frame* frame = pk_current_vm->top_frame;
  440. py_Frame_newlocals(frame, out);
  441. }
  442. static void pk_push_special_locals() {
  443. py_Frame* frame = pk_current_vm->top_frame;
  444. if(!frame) {
  445. py_pushnil();
  446. return;
  447. }
  448. if(frame->is_locals_special) {
  449. py_push(frame->locals);
  450. } else {
  451. py_StackRef out = py_pushtmp();
  452. out->type = tp_locals;
  453. out->is_ptr = false;
  454. out->extra = 0;
  455. // this is a weak reference
  456. // which will expire when the frame is destroyed
  457. out->_ptr = frame;
  458. }
  459. }
  460. static bool _builtins_execdyn(const char* title, int argc, py_Ref argv, enum py_CompileMode mode) {
  461. switch(argc) {
  462. case 1: {
  463. py_newglobals(py_pushtmp());
  464. pk_push_special_locals();
  465. break;
  466. }
  467. case 2: {
  468. // globals
  469. if(py_isnone(py_arg(1))) {
  470. py_newglobals(py_pushtmp());
  471. } else {
  472. py_push(py_arg(1));
  473. }
  474. // locals
  475. py_pushnil();
  476. break;
  477. }
  478. case 3: {
  479. // globals
  480. if(py_isnone(py_arg(1))) {
  481. py_newglobals(py_pushtmp());
  482. } else {
  483. py_push(py_arg(1));
  484. }
  485. // locals
  486. if(py_isnone(py_arg(2))) {
  487. py_pushnil();
  488. } else {
  489. py_push(py_arg(2));
  490. }
  491. break;
  492. }
  493. default: return TypeError("%s() takes at most 3 arguments", title);
  494. }
  495. if(py_isstr(argv)) {
  496. bool ok = py_compile(py_tostr(argv), "<string>", mode, true);
  497. if(!ok) return false;
  498. py_push(py_retval());
  499. } else if(py_istype(argv, tp_code)) {
  500. py_push(argv);
  501. } else {
  502. return TypeError("%s() expected 'str' or 'code', got '%t'", title, argv->type);
  503. }
  504. py_Frame* frame = pk_current_vm->top_frame;
  505. // [globals, locals, code]
  506. CodeObject* code = py_touserdata(py_peek(-1));
  507. if(code->src->is_dynamic) {
  508. bool ok = pk_execdyn(code, frame ? frame->module : NULL, py_peek(-3), py_peek(-2));
  509. py_shrink(3);
  510. return ok;
  511. } else {
  512. if(argc != 1) {
  513. return ValueError(
  514. "code object is not dynamic, `globals` and `locals` must not be specified");
  515. }
  516. bool ok = pk_exec(code, frame ? frame->module : NULL);
  517. py_shrink(3);
  518. return ok;
  519. }
  520. }
  521. static bool builtins_exec(int argc, py_Ref argv) {
  522. bool ok = _builtins_execdyn("exec", argc, argv, EXEC_MODE);
  523. py_newnone(py_retval());
  524. return ok;
  525. }
  526. static bool builtins_eval(int argc, py_Ref argv) {
  527. return _builtins_execdyn("eval", argc, argv, EVAL_MODE);
  528. }
  529. static bool
  530. pk_smartexec(const char* source, py_Ref module, enum py_CompileMode mode, va_list args) {
  531. if(module == NULL) module = &pk_current_vm->main;
  532. pk_mappingproxy__namedict(py_pushtmp(), module); // globals
  533. py_newdict(py_pushtmp()); // locals
  534. bool ok = py_compile(source, "<string>", mode, true);
  535. if(!ok) return false;
  536. py_push(py_retval());
  537. // [globals, locals, code]
  538. CodeObject* co = py_touserdata(py_peek(-1));
  539. py_StackRef locals = py_peek(-2);
  540. int max_index = -1;
  541. c11__foreach(Bytecode, &co->codes, bc) {
  542. if(bc->op == OP_LOAD_NAME) {
  543. c11_sv name = py_name2sv(c11__getitem(py_Name, &co->names, bc->arg));
  544. if(name.data[0] != '_') continue;
  545. int index;
  546. if(name.size == 1) {
  547. index = 0;
  548. } else if(name.size == 2 && isdigit(name.data[1])) {
  549. index = name.data[1] - '0';
  550. } else {
  551. continue;
  552. }
  553. max_index = c11__max(max_index, index);
  554. }
  555. }
  556. if(max_index == -1) return ValueError("no placeholder found in the source");
  557. for(int i = 0; i <= max_index; i++) {
  558. py_Ref val = va_arg(args, py_Ref);
  559. char buf[3];
  560. buf[0] = '_';
  561. buf[1] = '0' + i;
  562. buf[2] = '\0';
  563. py_dict_setitem_by_str(locals, buf, val);
  564. if(i == 0) {
  565. // _ => _0
  566. py_dict_setitem_by_str(locals, "_", val);
  567. }
  568. }
  569. ok = pk_execdyn(co, module, py_peek(-3), locals);
  570. if(!ok) return false;
  571. py_shrink(3);
  572. return true;
  573. }
  574. bool py_smartexec(const char* source, py_Ref module, ...) {
  575. va_list args;
  576. va_start(args, module);
  577. bool ok = pk_smartexec(source, module, EXEC_MODE, args);
  578. va_end(args);
  579. return ok;
  580. }
  581. bool py_smarteval(const char* source, py_Ref module, ...) {
  582. va_list args;
  583. va_start(args, module);
  584. bool ok = pk_smartexec(source, module, EVAL_MODE, args);
  585. va_end(args);
  586. return ok;
  587. }
  588. static bool builtins_compile(int argc, py_Ref argv) {
  589. PY_CHECK_ARGC(3);
  590. for(int i = 0; i < 3; i++) {
  591. if(!py_checktype(py_arg(i), tp_str)) return false;
  592. }
  593. const char* source = py_tostr(py_arg(0));
  594. const char* filename = py_tostr(py_arg(1));
  595. const char* mode = py_tostr(py_arg(2));
  596. enum py_CompileMode compile_mode;
  597. if(strcmp(mode, "exec") == 0) {
  598. compile_mode = EXEC_MODE;
  599. } else if(strcmp(mode, "eval") == 0) {
  600. compile_mode = EVAL_MODE;
  601. } else if(strcmp(mode, "single") == 0) {
  602. compile_mode = SINGLE_MODE;
  603. } else {
  604. return ValueError("compile() mode must be 'exec', 'eval', or 'single'");
  605. }
  606. return py_compile(source, filename, compile_mode, true);
  607. }
  608. static bool builtins__import__(int argc, py_Ref argv) {
  609. PY_CHECK_ARGC(1);
  610. PY_CHECK_ARG_TYPE(0, tp_str);
  611. int res = py_import(py_tostr(argv));
  612. if(res == -1) return false;
  613. if(res) return true;
  614. return ImportError("module '%s' not found", py_tostr(argv));
  615. }
  616. static bool NoneType__repr__(int argc, py_Ref argv) {
  617. py_newstr(py_retval(), "None");
  618. return true;
  619. }
  620. static bool ellipsis__repr__(int argc, py_Ref argv) {
  621. py_newstr(py_retval(), "...");
  622. return true;
  623. }
  624. static bool NotImplementedType__repr__(int argc, py_Ref argv) {
  625. py_newstr(py_retval(), "NotImplemented");
  626. return true;
  627. }
  628. py_TValue pk_builtins__register() {
  629. py_Ref builtins = py_newmodule("builtins");
  630. py_bindfunc(builtins, "exit", builtins_exit);
  631. py_bindfunc(builtins, "input", builtins_input);
  632. py_bindfunc(builtins, "repr", builtins_repr);
  633. py_bindfunc(builtins, "len", builtins_len);
  634. py_bindfunc(builtins, "hex", builtins_hex);
  635. py_bindfunc(builtins, "iter", builtins_iter);
  636. py_bindfunc(builtins, "next", builtins_next);
  637. py_bindfunc(builtins, "hash", builtins_hash);
  638. py_bindfunc(builtins, "abs", builtins_abs);
  639. py_bindfunc(builtins, "divmod", builtins_divmod);
  640. py_bindfunc(builtins, "round", builtins_round);
  641. py_bind(builtins, "print(*args, sep=' ', end='\\n', flush=False)", builtins_print);
  642. py_bindfunc(builtins, "isinstance", builtins_isinstance);
  643. py_bindfunc(builtins, "issubclass", builtins_issubclass);
  644. py_bindfunc(builtins, "callable", builtins_callable);
  645. py_bindfunc(builtins, "getattr", builtins_getattr);
  646. py_bindfunc(builtins, "setattr", builtins_setattr);
  647. py_bindfunc(builtins, "hasattr", builtins_hasattr);
  648. py_bindfunc(builtins, "delattr", builtins_delattr);
  649. py_bindfunc(builtins, "chr", builtins_chr);
  650. py_bindfunc(builtins, "ord", builtins_ord);
  651. py_bindfunc(builtins, "id", builtins_id);
  652. py_bindfunc(builtins, "globals", builtins_globals);
  653. py_bindfunc(builtins, "locals", builtins_locals);
  654. py_bindfunc(builtins, "exec", builtins_exec);
  655. py_bindfunc(builtins, "eval", builtins_eval);
  656. py_bindfunc(builtins, "compile", builtins_compile);
  657. py_bindfunc(builtins, "__import__", builtins__import__);
  658. // some patches
  659. py_bindmagic(tp_NoneType, __repr__, NoneType__repr__);
  660. py_setdict(py_tpobject(tp_NoneType), __hash__, py_None());
  661. py_bindmagic(tp_ellipsis, __repr__, ellipsis__repr__);
  662. py_setdict(py_tpobject(tp_ellipsis), __hash__, py_None());
  663. py_bindmagic(tp_NotImplementedType, __repr__, NotImplementedType__repr__);
  664. py_setdict(py_tpobject(tp_NotImplementedType), __hash__, py_None());
  665. return *builtins;
  666. }
  667. void function__gc_mark(void* ud, c11_vector* p_stack) {
  668. Function* func = ud;
  669. if(func->globals) pk__mark_value(func->globals);
  670. if(func->closure) {
  671. NameDict* dict = func->closure;
  672. for(int i = 0; i < dict->capacity; i++) {
  673. NameDict_KV* kv = &dict->items[i];
  674. if(kv->key == NULL) continue;
  675. pk__mark_value(&kv->value);
  676. }
  677. }
  678. FuncDecl__gc_mark(func->decl, p_stack);
  679. }
  680. static bool function__doc__(int argc, py_Ref argv) {
  681. PY_CHECK_ARGC(1);
  682. Function* func = py_touserdata(py_arg(0));
  683. if(func->decl->docstring) {
  684. py_newstr(py_retval(), func->decl->docstring);
  685. } else {
  686. py_newnone(py_retval());
  687. }
  688. return true;
  689. }
  690. static bool function__name__(int argc, py_Ref argv) {
  691. PY_CHECK_ARGC(1);
  692. Function* func = py_touserdata(py_arg(0));
  693. py_newstr(py_retval(), func->decl->code.name->data);
  694. return true;
  695. }
  696. static bool function__repr__(int argc, py_Ref argv) {
  697. // <function f at 0x10365b9c0>
  698. PY_CHECK_ARGC(1);
  699. Function* func = py_touserdata(py_arg(0));
  700. c11_sbuf buf;
  701. c11_sbuf__ctor(&buf);
  702. c11_sbuf__write_cstr(&buf, "<function ");
  703. c11_sbuf__write_cstr(&buf, func->decl->code.name->data);
  704. c11_sbuf__write_cstr(&buf, " at ");
  705. c11_sbuf__write_ptr(&buf, func);
  706. c11_sbuf__write_char(&buf, '>');
  707. c11_sbuf__py_submit(&buf, py_retval());
  708. return true;
  709. }
  710. py_Type pk_function__register() {
  711. py_Type type =
  712. pk_newtype("function", tp_object, NULL, (void (*)(void*))Function__dtor, false, true);
  713. py_bindproperty(type, "__doc__", function__doc__, NULL);
  714. py_bindproperty(type, "__name__", function__name__, NULL);
  715. py_bindmagic(type, __repr__, function__repr__);
  716. return type;
  717. }
  718. static bool nativefunc__repr__(int argc, py_Ref argv) {
  719. PY_CHECK_ARGC(1);
  720. py_newstr(py_retval(), "<nativefunc object>");
  721. return true;
  722. }
  723. py_Type pk_nativefunc__register() {
  724. py_Type type = pk_newtype("nativefunc", tp_object, NULL, NULL, false, true);
  725. py_bindmagic(type, __repr__, nativefunc__repr__);
  726. return type;
  727. }
  728. static bool super__new__(int argc, py_Ref argv) {
  729. py_Type class_arg = 0;
  730. py_Frame* frame = pk_current_vm->top_frame;
  731. py_Ref self_arg = NULL;
  732. if(argc == 1) {
  733. // super()
  734. if(!frame->is_locals_special) {
  735. py_TValue* callable = frame->p0;
  736. if(callable->type == tp_boundmethod) callable = py_getslot(frame->p0, 1);
  737. if(callable->type == tp_function) {
  738. Function* func = py_touserdata(callable);
  739. if(func->clazz != NULL) {
  740. class_arg = *(py_Type*)PyObject__userdata(func->clazz);
  741. if(frame->co->nlocals > 0) { self_arg = &frame->locals[0]; }
  742. }
  743. }
  744. }
  745. if(class_arg == 0 || self_arg == NULL) return RuntimeError("super(): no arguments");
  746. if(self_arg->type == tp_type) {
  747. // f(cls, ...)
  748. class_arg = pk__type_info(class_arg)->base;
  749. if(class_arg == 0) return RuntimeError("super(): base class is invalid");
  750. py_assign(py_retval(), py_tpobject(class_arg));
  751. return true;
  752. }
  753. } else if(argc == 3) {
  754. // super(type[T], obj)
  755. PY_CHECK_ARG_TYPE(1, tp_type);
  756. class_arg = py_totype(py_arg(1));
  757. self_arg = py_arg(2);
  758. if(!py_isinstance(self_arg, class_arg)) {
  759. return TypeError("super(type, obj): obj must be an instance of type");
  760. }
  761. } else {
  762. return TypeError("super() takes 0 or 2 arguments");
  763. }
  764. class_arg = pk__type_info(class_arg)->base;
  765. if(class_arg == 0) return RuntimeError("super(): base class is invalid");
  766. py_Type* p_class_arg = py_newobject(py_retval(), tp_super, 1, sizeof(py_Type));
  767. *p_class_arg = class_arg;
  768. py_setslot(py_retval(), 0, self_arg);
  769. return true;
  770. }
  771. py_Type pk_super__register() {
  772. py_Type type = pk_newtype("super", tp_object, NULL, NULL, false, true);
  773. py_bindmagic(type, __new__, super__new__);
  774. return type;
  775. }