pocketpy_c.cpp 15 KB

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