pocketpy_c.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. #ifndef PK_NO_EXPORT_C_API
  2. #include "pocketpy/pocketpy.hpp"
  3. #include "pocketpy/pocketpy_c.h"
  4. #include <iostream>
  5. namespace pkpy{
  6. #define PK_ASSERT_N_EXTRA_ELEMENTS(n) \
  7. int __ex_count = count_extra_elements(vm, n); \
  8. if(__ex_count < n) { \
  9. Str msg = _S("expected at least ", n, " elements, got ", __ex_count); \
  10. pkpy_error(vm_handle, "StackError", pkpy_string(msg.c_str())); \
  11. return false; \
  12. }
  13. #define PK_ASSERT_NO_ERROR() \
  14. if(vm->__c.error != nullptr) return false;
  15. static int count_extra_elements(VM* vm, int n) {
  16. if(vm->callstack.empty()) { return vm->s_data.size(); }
  17. assert(!vm->__c.s_view.empty());
  18. return vm->s_data._sp - vm->__c.s_view.back().end();
  19. }
  20. static PyVar stack_item(VM* vm, int index) {
  21. PyVar* begin;
  22. PyVar* end = vm->s_data.end();
  23. if(vm->callstack.empty()) {
  24. begin = vm->s_data.begin();
  25. } else {
  26. assert(!vm->__c.s_view.empty());
  27. begin = vm->__c.s_view.back().begin();
  28. }
  29. int size = end - begin;
  30. if(index < 0) index += size;
  31. assert(index >= 0 && index < size);
  32. return begin[index];
  33. }
  34. #define PK_PROTECTED(__B) \
  35. try { \
  36. __B \
  37. } catch(TopLevelException e) { \
  38. vm->__c.error = (PyObject*)e.ptr->self; \
  39. return false; \
  40. } catch(const std::exception& re) { \
  41. PyObject* e_t = vm->_t(vm->tp_exception); \
  42. vm->__c.error = vm->call(e_t, VAR(re.what())).get(); \
  43. return false; \
  44. }
  45. pkpy_vm* pkpy_new_vm(bool enable_os) { return (pkpy_vm*)new VM(enable_os); }
  46. void pkpy_delete_vm(pkpy_vm* vm) { return delete (VM*)vm; }
  47. bool pkpy_exec(pkpy_vm* vm_handle, const char* source) {
  48. VM* vm = (VM*)vm_handle;
  49. PK_ASSERT_NO_ERROR()
  50. PyVar res;
  51. PK_PROTECTED(
  52. CodeObject_ code = vm->compile(source, "main.py", EXEC_MODE);
  53. res = vm->_exec(code, vm->_main);
  54. )
  55. return res != nullptr;
  56. }
  57. bool pkpy_exec_2(pkpy_vm* vm_handle, const char* source, const char* filename, int mode, const char* module) {
  58. VM* vm = (VM*)vm_handle;
  59. PK_ASSERT_NO_ERROR()
  60. PyVar res;
  61. PyObject* mod;
  62. PK_PROTECTED(
  63. if(module == nullptr){ mod = vm->_main;
  64. }else{
  65. mod = vm->_modules[module].get(); // may raise
  66. }
  67. CodeObject_ code = vm->compile(source, filename, (CompileMode)mode);
  68. res = vm->_exec(code, mod);
  69. )
  70. return res != nullptr;
  71. }
  72. void pkpy_set_main_argv(pkpy_vm* vm_handle, int argc, char** argv) {
  73. VM* vm = (VM*)vm_handle;
  74. vm->set_main_argv(argc, argv);
  75. }
  76. bool pkpy_dup(pkpy_vm* vm_handle, int n) {
  77. VM* vm = (VM*)vm_handle;
  78. PK_ASSERT_NO_ERROR()
  79. PK_PROTECTED(
  80. PyVar item = stack_item(vm, n);
  81. vm->s_data.push(item);
  82. )
  83. return true;
  84. }
  85. bool pkpy_pop(pkpy_vm* vm_handle, int n) {
  86. VM* vm = (VM*)vm_handle;
  87. PK_ASSERT_NO_ERROR()
  88. PK_ASSERT_N_EXTRA_ELEMENTS(n)
  89. vm->s_data.shrink(n);
  90. return true;
  91. }
  92. bool pkpy_pop_top(pkpy_vm* vm_handle) {
  93. VM* vm = (VM*)vm_handle;
  94. PK_ASSERT_NO_ERROR()
  95. PK_ASSERT_N_EXTRA_ELEMENTS(1)
  96. vm->s_data.pop();
  97. return true;
  98. }
  99. bool pkpy_dup_top(pkpy_vm* vm_handle) {
  100. VM* vm = (VM*)vm_handle;
  101. PK_ASSERT_NO_ERROR()
  102. PK_ASSERT_N_EXTRA_ELEMENTS(1)
  103. vm->s_data.push(vm->s_data.top());
  104. return true;
  105. }
  106. bool pkpy_rot_two(pkpy_vm* vm_handle) {
  107. VM* vm = (VM*)vm_handle;
  108. PK_ASSERT_NO_ERROR()
  109. PK_ASSERT_N_EXTRA_ELEMENTS(2)
  110. std::swap(vm->s_data.top(), vm->s_data.second());
  111. return true;
  112. }
  113. int pkpy_stack_size(pkpy_vm* vm_handle) {
  114. VM* vm = (VM*)vm_handle;
  115. PK_ASSERT_NO_ERROR()
  116. if(vm->callstack.empty()) { return vm->s_data.size(); }
  117. if(vm->__c.s_view.empty()) exit(127);
  118. return vm->s_data._sp - vm->__c.s_view.back().begin();
  119. }
  120. // int
  121. bool pkpy_push_int(pkpy_vm* vm_handle, int value) {
  122. VM* vm = (VM*)vm_handle;
  123. PK_ASSERT_NO_ERROR()
  124. PyVar res;
  125. PK_PROTECTED(
  126. // int may overflow so we should protect it
  127. res = py_var(vm, value);
  128. )
  129. vm->s_data.push(res);
  130. return true;
  131. }
  132. bool pkpy_is_int(pkpy_vm* vm_handle, int i) {
  133. VM* vm = (VM*)vm_handle;
  134. PK_ASSERT_NO_ERROR()
  135. PK_PROTECTED(
  136. return is_int(stack_item(vm, i));
  137. )
  138. }
  139. bool pkpy_to_int(pkpy_vm* vm_handle, int i, int* out) {
  140. VM* vm = (VM*)vm_handle;
  141. PK_ASSERT_NO_ERROR()
  142. PK_PROTECTED(
  143. PyVar item = stack_item(vm, i);
  144. *out = py_cast<int>(vm, item);
  145. )
  146. return true;
  147. }
  148. // float
  149. bool pkpy_push_float(pkpy_vm* vm_handle, double value) {
  150. VM* vm = (VM*)vm_handle;
  151. PK_ASSERT_NO_ERROR()
  152. PyVar res = py_var(vm, value);
  153. vm->s_data.push(res);
  154. return true;
  155. }
  156. bool pkpy_is_float(pkpy_vm* vm_handle, int i) {
  157. VM* vm = (VM*)vm_handle;
  158. PK_ASSERT_NO_ERROR()
  159. PK_PROTECTED(
  160. PyVar item = stack_item(vm, i);
  161. return is_float(item);
  162. )
  163. }
  164. bool pkpy_to_float(pkpy_vm* vm_handle, int i, double* out) {
  165. VM* vm = (VM*)vm_handle;
  166. PK_ASSERT_NO_ERROR()
  167. PK_PROTECTED(
  168. PyVar item = stack_item(vm, i);
  169. *out = py_cast<double>(vm, item);
  170. )
  171. return true;
  172. }
  173. // bool
  174. bool pkpy_push_bool(pkpy_vm* vm_handle, bool value) {
  175. VM* vm = (VM*)vm_handle;
  176. PK_ASSERT_NO_ERROR()
  177. vm->s_data.push(value ? vm->True : vm->False);
  178. return true;
  179. }
  180. bool pkpy_is_bool(pkpy_vm* vm_handle, int i) {
  181. VM* vm = (VM*)vm_handle;
  182. PK_ASSERT_NO_ERROR()
  183. PK_PROTECTED(
  184. PyVar item = stack_item(vm, i);
  185. return is_type(item, vm->tp_bool);
  186. )
  187. }
  188. bool pkpy_to_bool(pkpy_vm* vm_handle, int i, bool* out) {
  189. VM* vm = (VM*)vm_handle;
  190. PK_ASSERT_NO_ERROR()
  191. PK_PROTECTED(
  192. PyVar item = stack_item(vm, i);
  193. *out = py_cast<bool>(vm, item);
  194. )
  195. return true;
  196. }
  197. // string
  198. bool pkpy_push_string(pkpy_vm* vm_handle, pkpy_CString value) {
  199. VM* vm = (VM*)vm_handle;
  200. PK_ASSERT_NO_ERROR()
  201. PyVar res = py_var(vm, value);
  202. vm->s_data.push(res);
  203. return true;
  204. }
  205. bool pkpy_is_string(pkpy_vm* vm_handle, int i) {
  206. VM* vm = (VM*)vm_handle;
  207. PK_ASSERT_NO_ERROR()
  208. PK_PROTECTED(
  209. PyVar item = stack_item(vm, i);
  210. return is_type(item, vm->tp_str);
  211. )
  212. }
  213. bool pkpy_to_string(pkpy_vm* vm_handle, int i, pkpy_CString* out) {
  214. VM* vm = (VM*)vm_handle;
  215. PK_ASSERT_NO_ERROR()
  216. PK_PROTECTED(
  217. PyVar item = stack_item(vm, i);
  218. const Str& s = py_cast<Str&>(vm, item);
  219. *out = s.c_str();
  220. )
  221. return true;
  222. }
  223. // void_p
  224. bool pkpy_push_voidp(pkpy_vm* vm_handle, void* value) {
  225. VM* vm = (VM*)vm_handle;
  226. PK_ASSERT_NO_ERROR()
  227. PyVar res = py_var(vm, value);
  228. vm->s_data.push(res);
  229. return true;
  230. }
  231. bool pkpy_is_voidp(pkpy_vm* vm_handle, int i) {
  232. VM* vm = (VM*)vm_handle;
  233. PK_ASSERT_NO_ERROR()
  234. PK_PROTECTED(
  235. PyVar item = stack_item(vm, i);
  236. return vm->is_user_type<VoidP>(item);
  237. )
  238. }
  239. bool pkpy_to_voidp(pkpy_vm* vm_handle, int i, void** out) {
  240. VM* vm = (VM*)vm_handle;
  241. PK_ASSERT_NO_ERROR()
  242. PK_PROTECTED(
  243. PyVar item = stack_item(vm, i);
  244. VoidP& vp = py_cast<VoidP&>(vm, item);
  245. *out = vp.ptr;
  246. )
  247. return true;
  248. }
  249. // none
  250. bool pkpy_push_none(pkpy_vm* vm_handle) {
  251. VM* vm = (VM*)vm_handle;
  252. PK_ASSERT_NO_ERROR()
  253. vm->s_data.push(vm->None);
  254. return true;
  255. }
  256. bool pkpy_is_none(pkpy_vm* vm_handle, int i) {
  257. VM* vm = (VM*)vm_handle;
  258. PK_ASSERT_NO_ERROR()
  259. PK_PROTECTED(
  260. PyVar item = stack_item(vm, i);
  261. return is_none(item);
  262. )
  263. }
  264. // null
  265. bool pkpy_push_null(pkpy_vm* vm_handle) {
  266. VM* vm = (VM*)vm_handle;
  267. PK_ASSERT_NO_ERROR()
  268. vm->s_data.push(PY_NULL);
  269. return true;
  270. }
  271. struct TempViewPopper {
  272. VM* vm;
  273. bool used;
  274. TempViewPopper(VM* vm) : vm(vm), used(false) {}
  275. void restore() noexcept {
  276. if(used) return;
  277. vm->__c.s_view.pop_back();
  278. used = true;
  279. }
  280. ~TempViewPopper() { restore(); }
  281. };
  282. // function
  283. static PyVar c_function_wrapper(VM* vm, ArgsView args) {
  284. pkpy_CFunction f = lambda_get_userdata<pkpy_CFunction>(args.begin());
  285. PyVar* curr_sp = vm->s_data._sp;
  286. vm->__c.s_view.push_back(args);
  287. TempViewPopper _tvp(vm);
  288. int retc = f((pkpy_vm*)vm); // may raise, _tvp will handle this via RAII
  289. _tvp.restore();
  290. // propagate_if_errored
  291. if(vm->__c.error != nullptr) {
  292. PyObject* e_obj = vm->__c.error;
  293. vm->__c.error = nullptr;
  294. vm->_error(e_obj);
  295. return nullptr;
  296. }
  297. assert(retc == vm->s_data._sp - curr_sp);
  298. if(retc == 0) return vm->None;
  299. if(retc == 1) return vm->s_data.popx();
  300. ArgsView ret_view(curr_sp, vm->s_data._sp);
  301. return py_var(vm, ret_view.to_tuple());
  302. }
  303. bool pkpy_push_function(pkpy_vm* vm_handle, const char* sig, pkpy_CFunction f) {
  304. VM* vm = (VM*)vm_handle;
  305. PK_ASSERT_NO_ERROR()
  306. PyVar f_obj;
  307. PK_PROTECTED(
  308. f_obj = vm->bind(nullptr, sig, c_function_wrapper, f);
  309. )
  310. vm->s_data.push(f_obj);
  311. return true;
  312. }
  313. // special push
  314. bool pkpy_push_module(pkpy_vm* vm_handle, const char* name) {
  315. VM* vm = (VM*)vm_handle;
  316. PK_ASSERT_NO_ERROR()
  317. PK_PROTECTED(
  318. PyObject* module = vm->new_module(name);
  319. vm->s_data.emplace(module);
  320. )
  321. return true;
  322. }
  323. // some opt
  324. bool pkpy_getattr(pkpy_vm* vm_handle, pkpy_CName name) {
  325. VM* vm = (VM*)vm_handle;
  326. PK_ASSERT_NO_ERROR()
  327. PK_ASSERT_N_EXTRA_ELEMENTS(1)
  328. PyVar o = vm->s_data.top();
  329. o = vm->getattr(o, StrName(name), false);
  330. if(o == nullptr) return false;
  331. vm->s_data.top() = o;
  332. return true;
  333. }
  334. bool pkpy_setattr(pkpy_vm* vm_handle, pkpy_CName name) {
  335. VM* vm = (VM*)vm_handle;
  336. PK_ASSERT_NO_ERROR()
  337. PK_ASSERT_N_EXTRA_ELEMENTS(2)
  338. PyVar a = vm->s_data.top();
  339. PyVar val = vm->s_data.second();
  340. PK_PROTECTED(
  341. vm->setattr(a, StrName(name), val);
  342. )
  343. vm->s_data.shrink(2);
  344. return true;
  345. }
  346. // get global will also get bulitins
  347. bool pkpy_getglobal(pkpy_vm* vm_handle, pkpy_CName name) {
  348. VM* vm = (VM*)vm_handle;
  349. PK_ASSERT_NO_ERROR()
  350. PyVar o = vm->_main->attr().try_get(StrName(name));
  351. if(o == nullptr) {
  352. o = vm->builtins->attr().try_get(StrName(name));
  353. if(o == nullptr) return false;
  354. }
  355. vm->s_data.push(o);
  356. return true;
  357. }
  358. bool pkpy_setglobal(pkpy_vm* vm_handle, pkpy_CName name) {
  359. VM* vm = (VM*)vm_handle;
  360. PK_ASSERT_NO_ERROR()
  361. PK_ASSERT_N_EXTRA_ELEMENTS(1)
  362. vm->_main->attr().set(StrName(name), vm->s_data.popx());
  363. return true;
  364. }
  365. bool pkpy_eval(pkpy_vm* vm_handle, const char* source) {
  366. VM* vm = (VM*)vm_handle;
  367. PK_ASSERT_NO_ERROR()
  368. PK_PROTECTED(
  369. CodeObject_ co = vm->compile(source, "<eval>", EVAL_MODE);
  370. PyVar ret = vm->_exec(co, vm->_main);
  371. vm->s_data.push(ret);
  372. )
  373. return true;
  374. }
  375. bool pkpy_unpack_sequence(pkpy_vm* vm_handle, int n) {
  376. VM* vm = (VM*)vm_handle;
  377. PK_ASSERT_NO_ERROR()
  378. PK_ASSERT_N_EXTRA_ELEMENTS(1)
  379. auto _lock = vm->heap.gc_scope_lock();
  380. PK_PROTECTED(
  381. PyVar _0 = vm->py_iter(vm->s_data.popx());
  382. for(int i=0; i<n; i++){
  383. PyVar _1 = vm->py_next(_0);
  384. if(_1 == vm->StopIteration) vm->ValueError("not enough values to unpack");
  385. vm->s_data.push(_1);
  386. }
  387. if(vm->py_next(_0) != vm->StopIteration) vm->ValueError("too many values to unpack");
  388. )
  389. return true;
  390. }
  391. bool pkpy_get_unbound_method(pkpy_vm* vm_handle, pkpy_CName name) {
  392. VM* vm = (VM*)vm_handle;
  393. PK_ASSERT_NO_ERROR()
  394. PK_ASSERT_N_EXTRA_ELEMENTS(1)
  395. PyVar o = vm->s_data.top();
  396. PyVar self;
  397. PK_PROTECTED(
  398. o = vm->get_unbound_method(o, StrName(name), &self);
  399. )
  400. vm->s_data.pop();
  401. vm->s_data.push(o);
  402. vm->s_data.push(self);
  403. return true;
  404. }
  405. bool pkpy_py_repr(pkpy_vm* vm_handle) {
  406. VM* vm = (VM*)vm_handle;
  407. PK_ASSERT_NO_ERROR()
  408. PK_ASSERT_N_EXTRA_ELEMENTS(1)
  409. PyVar item = vm->s_data.top();
  410. PK_PROTECTED(
  411. item = VAR(vm->py_repr(item));
  412. )
  413. vm->s_data.top() = item;
  414. return true;
  415. }
  416. bool pkpy_py_str(pkpy_vm* vm_handle) {
  417. VM* vm = (VM*)vm_handle;
  418. PK_ASSERT_NO_ERROR()
  419. PK_ASSERT_N_EXTRA_ELEMENTS(1)
  420. PyVar item = vm->s_data.top();
  421. PK_PROTECTED(
  422. item = VAR(vm->py_str(item));
  423. )
  424. vm->s_data.top() = item;
  425. return true;
  426. }
  427. bool pkpy_py_import(pkpy_vm* vm_handle, pkpy_CString name) {
  428. VM* vm = (VM*)vm_handle;
  429. PK_ASSERT_NO_ERROR()
  430. PK_PROTECTED(
  431. PyVar module = vm->py_import(name);
  432. vm->s_data.push(module);
  433. )
  434. return true;
  435. }
  436. /* Error Handling */
  437. bool pkpy_error(pkpy_vm* vm_handle, const char* name, pkpy_CString message) {
  438. VM* vm = (VM*)vm_handle;
  439. PK_ASSERT_NO_ERROR()
  440. PyVar e_t = vm->_main->attr().try_get_likely_found(name);
  441. if(e_t == nullptr) {
  442. e_t = vm->builtins->attr().try_get_likely_found(name);
  443. if(e_t == nullptr) {
  444. e_t = vm->_t(vm->tp_exception);
  445. std::cerr << "[warning] pkpy_error(): " << Str(name).escape() << " not found, fallback to 'Exception'"
  446. << std::endl;
  447. }
  448. }
  449. vm->__c.error = vm->call(e_t, VAR(message)).get();
  450. return false;
  451. }
  452. bool pkpy_check_error(pkpy_vm* vm_handle) {
  453. VM* vm = (VM*)vm_handle;
  454. return vm->__c.error != nullptr;
  455. }
  456. bool pkpy_clear_error(pkpy_vm* vm_handle, char** message) {
  457. VM* vm = (VM*)vm_handle;
  458. // no error
  459. if(vm->__c.error == nullptr) return false;
  460. Exception& e = vm->__c.error->as<Exception>();
  461. if(message != nullptr)
  462. *message = strdup(e.summary().c_str());
  463. else
  464. std::cout << e.summary() << std::endl;
  465. vm->__c.error = nullptr;
  466. if(vm->callstack.empty()) {
  467. vm->s_data.clear();
  468. } else {
  469. if(vm->__c.s_view.empty()) exit(127);
  470. vm->s_data.reset(vm->__c.s_view.back().end());
  471. }
  472. return true;
  473. }
  474. bool pkpy_vectorcall(pkpy_vm* vm_handle, int argc) {
  475. VM* vm = (VM*)vm_handle;
  476. PK_ASSERT_NO_ERROR()
  477. PK_ASSERT_N_EXTRA_ELEMENTS(argc + 2)
  478. PyVar res;
  479. PK_PROTECTED(
  480. res = vm->vectorcall(argc);
  481. )
  482. vm->s_data.push(res);
  483. return true;
  484. }
  485. /*****************************************************************/
  486. void pkpy_free(void* p) { std::free(p); }
  487. pkpy_CName pkpy_name(const char* name) { return StrName(name).index; }
  488. pkpy_CString pkpy_name_to_string(pkpy_CName name) { return StrName(name).c_str(); }
  489. void pkpy_set_output_handler(pkpy_vm* vm_handle, pkpy_COutputHandler handler) {
  490. VM* vm = (VM*)vm_handle;
  491. vm->_stdout = handler;
  492. }
  493. void pkpy_set_import_handler(pkpy_vm* vm_handle, pkpy_CImportHandler handler) {
  494. VM* vm = (VM*)vm_handle;
  495. vm->_import_handler = handler;
  496. }
  497. void* pkpy_new_repl(pkpy_vm* vm_handle) { return new REPL((VM*)vm_handle); }
  498. bool pkpy_repl_input(void* r, const char* line) { return ((REPL*)r)->input(line); }
  499. void pkpy_delete_repl(void* repl) { delete (REPL*)repl; }
  500. #endif // PK_NO_EXPORT_C_API
  501. } // namespace pkpy