pocketpy_c.cpp 14 KB

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