vm.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. #pragma once
  2. #include "codeobject.h"
  3. #include "common.h"
  4. #include "frame.h"
  5. #include "error.h"
  6. #include "gc.h"
  7. #include "memory.h"
  8. #include "obj.h"
  9. #include "str.h"
  10. #include "tuplelist.h"
  11. #include "dict.h"
  12. namespace pkpy{
  13. /* Stack manipulation macros */
  14. // https://github.com/python/cpython/blob/3.9/Python/ceval.c#L1123
  15. #define TOP() (s_data.top())
  16. #define SECOND() (s_data.second())
  17. #define THIRD() (s_data.third())
  18. #define PEEK(n) (s_data.peek(n))
  19. #define STACK_SHRINK(n) (s_data.shrink(n))
  20. #define PUSH(v) (s_data.push(v))
  21. #define POP() (s_data.pop())
  22. #define POPX() (s_data.popx())
  23. #define STACK_VIEW(n) (s_data.view(n))
  24. #define DEF_NATIVE_2(ctype, ptype) \
  25. template<> inline ctype py_cast<ctype>(VM* vm, PyObject* obj) { \
  26. vm->check_non_tagged_type(obj, vm->ptype); \
  27. return PK_OBJ_GET(ctype, obj); \
  28. } \
  29. template<> inline ctype _py_cast<ctype>(VM* vm, PyObject* obj) { \
  30. PK_UNUSED(vm); \
  31. return PK_OBJ_GET(ctype, obj); \
  32. } \
  33. template<> inline ctype& py_cast<ctype&>(VM* vm, PyObject* obj) { \
  34. vm->check_non_tagged_type(obj, vm->ptype); \
  35. return PK_OBJ_GET(ctype, obj); \
  36. } \
  37. template<> inline ctype& _py_cast<ctype&>(VM* vm, PyObject* obj) { \
  38. PK_UNUSED(vm); \
  39. return PK_OBJ_GET(ctype, obj); \
  40. } \
  41. inline PyObject* py_var(VM* vm, const ctype& value) { return vm->heap.gcnew<ctype>(vm->ptype, value);} \
  42. inline PyObject* py_var(VM* vm, ctype&& value) { return vm->heap.gcnew<ctype>(vm->ptype, std::move(value));}
  43. typedef PyObject* (*BinaryFuncC)(VM*, PyObject*, PyObject*);
  44. struct PyTypeInfo{
  45. PyObject* obj;
  46. Type base;
  47. Str name;
  48. bool subclass_enabled;
  49. // cached special methods
  50. // unary operators
  51. PyObject* (*m__repr__)(VM* vm, PyObject*) = nullptr;
  52. PyObject* (*m__str__)(VM* vm, PyObject*) = nullptr;
  53. i64 (*m__hash__)(VM* vm, PyObject*) = nullptr;
  54. i64 (*m__len__)(VM* vm, PyObject*) = nullptr;
  55. PyObject* (*m__iter__)(VM* vm, PyObject*) = nullptr;
  56. PyObject* (*m__next__)(VM* vm, PyObject*) = nullptr;
  57. PyObject* (*m__json__)(VM* vm, PyObject*) = nullptr;
  58. PyObject* (*m__neg__)(VM* vm, PyObject*) = nullptr;
  59. PyObject* (*m__bool__)(VM* vm, PyObject*) = nullptr;
  60. PyObject* (*m__invert__)(VM* vm, PyObject*) = nullptr;
  61. BinaryFuncC m__eq__ = nullptr;
  62. BinaryFuncC m__lt__ = nullptr;
  63. BinaryFuncC m__le__ = nullptr;
  64. BinaryFuncC m__gt__ = nullptr;
  65. BinaryFuncC m__ge__ = nullptr;
  66. BinaryFuncC m__contains__ = nullptr;
  67. // binary operators
  68. BinaryFuncC m__add__ = nullptr;
  69. BinaryFuncC m__sub__ = nullptr;
  70. BinaryFuncC m__mul__ = nullptr;
  71. BinaryFuncC m__truediv__ = nullptr;
  72. BinaryFuncC m__floordiv__ = nullptr;
  73. BinaryFuncC m__mod__ = nullptr;
  74. BinaryFuncC m__pow__ = nullptr;
  75. BinaryFuncC m__matmul__ = nullptr;
  76. BinaryFuncC m__lshift__ = nullptr;
  77. BinaryFuncC m__rshift__ = nullptr;
  78. BinaryFuncC m__and__ = nullptr;
  79. BinaryFuncC m__or__ = nullptr;
  80. BinaryFuncC m__xor__ = nullptr;
  81. // indexer
  82. PyObject* (*m__getitem__)(VM* vm, PyObject*, PyObject*) = nullptr;
  83. void (*m__setitem__)(VM* vm, PyObject*, PyObject*, PyObject*) = nullptr;
  84. void (*m__delitem__)(VM* vm, PyObject*, PyObject*) = nullptr;
  85. };
  86. struct FrameId{
  87. std::vector<pkpy::Frame>* data;
  88. int index;
  89. FrameId(std::vector<pkpy::Frame>* data, int index) : data(data), index(index) {}
  90. Frame* operator->() const { return &data->operator[](index); }
  91. Frame* get() const { return &data->operator[](index); }
  92. };
  93. typedef void(*PrintFunc)(VM*, const Str&);
  94. class VM {
  95. PK_ALWAYS_PASS_BY_POINTER(VM)
  96. VM* vm; // self reference for simplify code
  97. public:
  98. ManagedHeap heap;
  99. ValueStack s_data;
  100. stack< Frame > callstack;
  101. std::vector<PyTypeInfo> _all_types;
  102. NameDict _modules; // loaded modules
  103. std::map<StrName, Str> _lazy_modules; // lazy loaded modules
  104. struct{
  105. PyObject* error;
  106. stack<ArgsView> s_view;
  107. } _c;
  108. PyObject* None;
  109. PyObject* True;
  110. PyObject* False;
  111. PyObject* NotImplemented; // unused
  112. PyObject* Ellipsis;
  113. PyObject* builtins; // builtins module
  114. PyObject* StopIteration;
  115. PyObject* _main; // __main__ module
  116. PyObject* _last_exception;
  117. #if PK_ENABLE_CEVAL_CALLBACK
  118. void (*_ceval_on_step)(VM*, Frame*, Bytecode bc) = nullptr;
  119. #endif
  120. PrintFunc _stdout;
  121. PrintFunc _stderr;
  122. Bytes (*_import_handler)(const Str& name);
  123. // for quick access
  124. Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str;
  125. Type tp_list, tp_tuple;
  126. Type tp_function, tp_native_func, tp_bound_method;
  127. Type tp_slice, tp_range, tp_module;
  128. Type tp_super, tp_exception, tp_bytes, tp_mappingproxy;
  129. Type tp_dict, tp_property, tp_star_wrapper;
  130. PyObject* cached_object__new__;
  131. const bool enable_os;
  132. VM(bool enable_os=true);
  133. FrameId top_frame();
  134. void _pop_frame();
  135. PyObject* py_str(PyObject* obj);
  136. PyObject* py_repr(PyObject* obj);
  137. PyObject* py_json(PyObject* obj);
  138. PyObject* py_iter(PyObject* obj);
  139. PyObject* find_name_in_mro(PyObject* cls, StrName name);
  140. bool isinstance(PyObject* obj, Type cls_t);
  141. PyObject* exec(Str source, Str filename, CompileMode mode, PyObject* _module=nullptr);
  142. template<typename ...Args>
  143. PyObject* _exec(Args&&... args){
  144. callstack.emplace(&s_data, s_data._sp, std::forward<Args>(args)...);
  145. return _run_top_frame();
  146. }
  147. void _push_varargs(){ }
  148. void _push_varargs(PyObject* _0){ PUSH(_0); }
  149. void _push_varargs(PyObject* _0, PyObject* _1){ PUSH(_0); PUSH(_1); }
  150. void _push_varargs(PyObject* _0, PyObject* _1, PyObject* _2){ PUSH(_0); PUSH(_1); PUSH(_2); }
  151. void _push_varargs(PyObject* _0, PyObject* _1, PyObject* _2, PyObject* _3){ PUSH(_0); PUSH(_1); PUSH(_2); PUSH(_3); }
  152. template<typename... Args>
  153. PyObject* call(PyObject* callable, Args&&... args){
  154. PUSH(callable);
  155. PUSH(PY_NULL);
  156. _push_varargs(args...);
  157. return vectorcall(sizeof...(args));
  158. }
  159. template<typename... Args>
  160. PyObject* call_method(PyObject* self, PyObject* callable, Args&&... args){
  161. PUSH(callable);
  162. PUSH(self);
  163. _push_varargs(args...);
  164. return vectorcall(sizeof...(args));
  165. }
  166. template<typename... Args>
  167. PyObject* call_method(PyObject* self, StrName name, Args&&... args){
  168. PyObject* callable = get_unbound_method(self, name, &self);
  169. return call_method(self, callable, args...);
  170. }
  171. PyObject* property(NativeFuncC fget, NativeFuncC fset=nullptr, const char* type_hint=nullptr);
  172. PyObject* new_type_object(PyObject* mod, StrName name, Type base, bool subclass_enabled=true);
  173. Type _new_type_object(StrName name, Type base=0);
  174. PyObject* _find_type_object(const Str& type);
  175. Type _type(const Str& type);
  176. PyTypeInfo* _type_info(const Str& type);
  177. PyTypeInfo* _type_info(Type type);
  178. const PyTypeInfo* _inst_type_info(PyObject* obj);
  179. #define BIND_UNARY_SPECIAL(name) \
  180. void bind##name(Type type, PyObject* (*f)(VM*, PyObject*)){ \
  181. _all_types[type].m##name = f; \
  182. PyObject* nf = bind_method<0>(_t(type), #name, [](VM* vm, ArgsView args){ \
  183. return lambda_get_userdata<PyObject*(*)(VM*, PyObject*)>(args.begin())(vm, args[0]);\
  184. }); \
  185. PK_OBJ_GET(NativeFunc, nf).set_userdata(f); \
  186. }
  187. BIND_UNARY_SPECIAL(__repr__)
  188. BIND_UNARY_SPECIAL(__str__)
  189. BIND_UNARY_SPECIAL(__iter__)
  190. BIND_UNARY_SPECIAL(__next__)
  191. BIND_UNARY_SPECIAL(__json__)
  192. BIND_UNARY_SPECIAL(__neg__)
  193. BIND_UNARY_SPECIAL(__bool__)
  194. BIND_UNARY_SPECIAL(__invert__)
  195. void bind__hash__(Type type, i64 (*f)(VM* vm, PyObject*));
  196. void bind__len__(Type type, i64 (*f)(VM* vm, PyObject*));
  197. #undef BIND_UNARY_SPECIAL
  198. #define BIND_BINARY_SPECIAL(name) \
  199. void bind##name(Type type, BinaryFuncC f){ \
  200. PyObject* obj = _t(type); \
  201. _all_types[type].m##name = f; \
  202. PyObject* nf = bind_method<1>(obj, #name, [](VM* vm, ArgsView args){ \
  203. return lambda_get_userdata<BinaryFuncC>(args.begin())(vm, args[0], args[1]); \
  204. }); \
  205. PK_OBJ_GET(NativeFunc, nf).set_userdata(f); \
  206. }
  207. BIND_BINARY_SPECIAL(__eq__)
  208. BIND_BINARY_SPECIAL(__lt__)
  209. BIND_BINARY_SPECIAL(__le__)
  210. BIND_BINARY_SPECIAL(__gt__)
  211. BIND_BINARY_SPECIAL(__ge__)
  212. BIND_BINARY_SPECIAL(__contains__)
  213. BIND_BINARY_SPECIAL(__add__)
  214. BIND_BINARY_SPECIAL(__sub__)
  215. BIND_BINARY_SPECIAL(__mul__)
  216. BIND_BINARY_SPECIAL(__truediv__)
  217. BIND_BINARY_SPECIAL(__floordiv__)
  218. BIND_BINARY_SPECIAL(__mod__)
  219. BIND_BINARY_SPECIAL(__pow__)
  220. BIND_BINARY_SPECIAL(__matmul__)
  221. BIND_BINARY_SPECIAL(__lshift__)
  222. BIND_BINARY_SPECIAL(__rshift__)
  223. BIND_BINARY_SPECIAL(__and__)
  224. BIND_BINARY_SPECIAL(__or__)
  225. BIND_BINARY_SPECIAL(__xor__)
  226. #undef BIND_BINARY_SPECIAL
  227. void bind__getitem__(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*)){
  228. PyObject* obj = _t(type);
  229. _all_types[type].m__getitem__ = f;
  230. PyObject* nf = bind_method<1>(obj, "__getitem__", [](VM* vm, ArgsView args){
  231. return lambda_get_userdata<PyObject*(*)(VM*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1]);
  232. });
  233. PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
  234. }
  235. void bind__setitem__(Type type, void (*f)(VM*, PyObject*, PyObject*, PyObject*)){
  236. PyObject* obj = _t(type);
  237. _all_types[type].m__setitem__ = f;
  238. PyObject* nf = bind_method<2>(obj, "__setitem__", [](VM* vm, ArgsView args){
  239. lambda_get_userdata<void(*)(VM* vm, PyObject*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1], args[2]);
  240. return vm->None;
  241. });
  242. PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
  243. }
  244. void bind__delitem__(Type type, void (*f)(VM*, PyObject*, PyObject*)){
  245. PyObject* obj = _t(type);
  246. _all_types[type].m__delitem__ = f;
  247. PyObject* nf = bind_method<1>(obj, "__delitem__", [](VM* vm, ArgsView args){
  248. lambda_get_userdata<void(*)(VM*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1]);
  249. return vm->None;
  250. });
  251. PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
  252. }
  253. bool py_equals(PyObject* lhs, PyObject* rhs);
  254. template<int ARGC>
  255. PyObject* bind_func(Str type, Str name, NativeFuncC fn) {
  256. return bind_func<ARGC>(_find_type_object(type), name, fn);
  257. }
  258. template<int ARGC>
  259. PyObject* bind_method(Str type, Str name, NativeFuncC fn) {
  260. return bind_method<ARGC>(_find_type_object(type), name, fn);
  261. }
  262. template<int ARGC, typename __T>
  263. PyObject* bind_constructor(__T&& type, NativeFuncC fn) {
  264. static_assert(ARGC==-1 || ARGC>=1);
  265. return bind_func<ARGC>(std::forward<__T>(type), "__new__", fn);
  266. }
  267. template<typename T, typename __T>
  268. PyObject* bind_default_constructor(__T&& type) {
  269. return bind_constructor<1>(std::forward<__T>(type), [](VM* vm, ArgsView args){
  270. Type t = PK_OBJ_GET(Type, args[0]);
  271. return vm->heap.gcnew<T>(t, T());
  272. });
  273. }
  274. template<typename T, typename __T>
  275. PyObject* bind_notimplemented_constructor(__T&& type) {
  276. return bind_constructor<-1>(std::forward<__T>(type), [](VM* vm, ArgsView args){
  277. PK_UNUSED(args);
  278. vm->NotImplementedError();
  279. return vm->None;
  280. });
  281. }
  282. template<int ARGC>
  283. PyObject* bind_builtin_func(Str name, NativeFuncC fn) {
  284. return bind_func<ARGC>(builtins, name, fn);
  285. }
  286. int normalized_index(int index, int size);
  287. PyObject* py_next(PyObject* obj);
  288. /***** Error Reporter *****/
  289. void _error(StrName name, const Str& msg){
  290. _error(Exception(name, msg));
  291. }
  292. void _raise(){
  293. bool ok = top_frame()->jump_to_exception_handler();
  294. if(ok) throw HandledException();
  295. else throw UnhandledException();
  296. }
  297. void StackOverflowError() { _error("StackOverflowError", ""); }
  298. void IOError(const Str& msg) { _error("IOError", msg); }
  299. void NotImplementedError(){ _error("NotImplementedError", ""); }
  300. void TypeError(const Str& msg){ _error("TypeError", msg); }
  301. void IndexError(const Str& msg){ _error("IndexError", msg); }
  302. void ValueError(const Str& msg){ _error("ValueError", msg); }
  303. void NameError(StrName name){ _error("NameError", fmt("name ", name.escape() + " is not defined")); }
  304. void UnboundLocalError(StrName name){ _error("UnboundLocalError", fmt("local variable ", name.escape() + " referenced before assignment")); }
  305. void KeyError(PyObject* obj){ _error("KeyError", PK_OBJ_GET(Str, py_repr(obj))); }
  306. void BinaryOptError(const char* op) { TypeError(fmt("unsupported operand type(s) for ", op)); }
  307. void AttributeError(PyObject* obj, StrName name){
  308. // OBJ_NAME calls getattr, which may lead to a infinite recursion
  309. _error("AttributeError", fmt("type ", OBJ_NAME(_t(obj)).escape(), " has no attribute ", name.escape()));
  310. }
  311. void AttributeError(Str msg){ _error("AttributeError", msg); }
  312. void check_type(PyObject* obj, Type type){
  313. if(is_type(obj, type)) return;
  314. TypeError("expected " + OBJ_NAME(_t(type)).escape() + ", got " + OBJ_NAME(_t(obj)).escape());
  315. }
  316. void check_args_size(int size, int min_size, int max_size){
  317. if(size >= min_size && size <= max_size) return;
  318. TypeError(fmt("expected ", min_size, "-", max_size, " arguments, got ", size));
  319. }
  320. void check_non_tagged_type(PyObject* obj, Type type){
  321. if(is_non_tagged_type(obj, type)) return;
  322. TypeError("expected " + OBJ_NAME(_t(type)).escape() + ", got " + OBJ_NAME(_t(obj)).escape());
  323. }
  324. void check_int(PyObject* obj){
  325. if(is_int(obj)) return;
  326. check_type(obj, tp_int); // if failed, redirect to check_type to raise TypeError
  327. }
  328. void check_int_or_float(PyObject* obj);
  329. PyObject* _t(Type t){
  330. return _all_types[t.index].obj;
  331. }
  332. PyObject* _t(PyObject* obj){
  333. if(is_int(obj)) return _t(tp_int);
  334. if(is_float(obj)) return _t(tp_float);
  335. return _all_types[obj->type].obj;
  336. }
  337. struct ImportContext{
  338. // 0: normal; 1: __init__.py; 2: relative
  339. std::vector<std::pair<StrName, int>> pending;
  340. struct Temp{
  341. VM* vm;
  342. StrName name;
  343. Temp(VM* vm, StrName name, int type): vm(vm), name(name){
  344. ImportContext* ctx = &vm->_import_context;
  345. ctx->pending.emplace_back(name, type);
  346. }
  347. ~Temp(){
  348. ImportContext* ctx = &vm->_import_context;
  349. ctx->pending.pop_back();
  350. }
  351. };
  352. Temp temp(VM* vm, StrName name, int type){
  353. return Temp(vm, name, type);
  354. }
  355. };
  356. ImportContext _import_context;
  357. PyObject* py_import(StrName name, bool relative=false);
  358. ~VM();
  359. #if PK_DEBUG_CEVAL_STEP
  360. void _log_s_data(const char* title = nullptr);
  361. #endif
  362. void _unpack_as_list(ArgsView args, List& list);
  363. void _unpack_as_dict(ArgsView args, Dict& dict);
  364. PyObject* vectorcall(int ARGC, int KWARGC=0, bool op_call=false);
  365. CodeObject_ compile(Str source, Str filename, CompileMode mode, bool unknown_global_scope=false);
  366. PyObject* py_negate(PyObject* obj);
  367. bool py_bool(PyObject* obj);
  368. i64 py_hash(PyObject* obj);
  369. PyObject* py_list(PyObject*);
  370. PyObject* new_module(StrName name);
  371. Str disassemble(CodeObject_ co);
  372. void init_builtin_types();
  373. PyObject* getattr(PyObject* obj, StrName name, bool throw_err=true);
  374. PyObject* get_unbound_method(PyObject* obj, StrName name, PyObject** self, bool throw_err=true, bool fallback=false);
  375. void parse_int_slice(const Slice& s, int length, int& start, int& stop, int& step);
  376. PyObject* format(Str, PyObject*);
  377. void setattr(PyObject* obj, StrName name, PyObject* value);
  378. template<int ARGC>
  379. PyObject* bind_method(PyObject*, Str, NativeFuncC);
  380. template<int ARGC>
  381. PyObject* bind_func(PyObject*, Str, NativeFuncC);
  382. void _error(Exception);
  383. PyObject* _run_top_frame();
  384. void post_init();
  385. PyObject* _py_generator(Frame&& frame, ArgsView buffer);
  386. void _prepare_py_call(PyObject**, ArgsView, ArgsView, const FuncDecl_&);
  387. // new style binding api
  388. PyObject* bind(PyObject*, const char*, const char*, NativeFuncC, UserData userdata={});
  389. PyObject* bind(PyObject*, const char*, NativeFuncC, UserData userdata={});
  390. PyObject* bind_property(PyObject*, StrName name, const char* type_hint, NativeFuncC fget, NativeFuncC fset=nullptr);
  391. };
  392. DEF_NATIVE_2(Str, tp_str)
  393. DEF_NATIVE_2(List, tp_list)
  394. DEF_NATIVE_2(Tuple, tp_tuple)
  395. DEF_NATIVE_2(Function, tp_function)
  396. DEF_NATIVE_2(NativeFunc, tp_native_func)
  397. DEF_NATIVE_2(BoundMethod, tp_bound_method)
  398. DEF_NATIVE_2(Range, tp_range)
  399. DEF_NATIVE_2(Slice, tp_slice)
  400. DEF_NATIVE_2(Exception, tp_exception)
  401. DEF_NATIVE_2(Bytes, tp_bytes)
  402. DEF_NATIVE_2(MappingProxy, tp_mappingproxy)
  403. DEF_NATIVE_2(Dict, tp_dict)
  404. DEF_NATIVE_2(Property, tp_property)
  405. DEF_NATIVE_2(StarWrapper, tp_star_wrapper)
  406. #undef DEF_NATIVE_2
  407. #define PY_CAST_INT(T) \
  408. template<> inline T py_cast<T>(VM* vm, PyObject* obj){ \
  409. vm->check_int(obj); \
  410. return (T)(PK_BITS(obj) >> 2); \
  411. } \
  412. template<> inline T _py_cast<T>(VM* vm, PyObject* obj){ \
  413. PK_UNUSED(vm); \
  414. return (T)(PK_BITS(obj) >> 2); \
  415. }
  416. PY_CAST_INT(char)
  417. PY_CAST_INT(short)
  418. PY_CAST_INT(int)
  419. PY_CAST_INT(long)
  420. PY_CAST_INT(long long)
  421. PY_CAST_INT(unsigned char)
  422. PY_CAST_INT(unsigned short)
  423. PY_CAST_INT(unsigned int)
  424. PY_CAST_INT(unsigned long)
  425. PY_CAST_INT(unsigned long long)
  426. template<> inline float py_cast<float>(VM* vm, PyObject* obj){
  427. if(is_float(obj)){
  428. i64 bits = PK_BITS(obj) & Number::c1;
  429. return BitsCvt(bits)._float;
  430. }
  431. if(is_int(obj)){
  432. return (float)_py_cast<i64>(vm, obj);
  433. }
  434. vm->check_int_or_float(obj); // error!
  435. return 0;
  436. }
  437. template<> inline float _py_cast<float>(VM* vm, PyObject* obj){
  438. return py_cast<float>(vm, obj);
  439. }
  440. template<> inline double py_cast<double>(VM* vm, PyObject* obj){
  441. if(is_float(obj)){
  442. i64 bits = PK_BITS(obj) & Number::c1;
  443. return BitsCvt(bits)._float;
  444. }
  445. if(is_int(obj)){
  446. return (float)_py_cast<i64>(vm, obj);
  447. }
  448. vm->check_int_or_float(obj); // error!
  449. return 0;
  450. }
  451. template<> inline double _py_cast<double>(VM* vm, PyObject* obj){
  452. return py_cast<double>(vm, obj);
  453. }
  454. #define PY_VAR_INT(T) \
  455. inline PyObject* py_var(VM* vm, T _val){ \
  456. i64 val = static_cast<i64>(_val); \
  457. if(((val << 2) >> 2) != val){ \
  458. vm->_error("OverflowError", std::to_string(val) + " is out of range"); \
  459. } \
  460. val = (val << 2) | 0b01; \
  461. return reinterpret_cast<PyObject*>(val); \
  462. }
  463. PY_VAR_INT(char)
  464. PY_VAR_INT(short)
  465. PY_VAR_INT(int)
  466. PY_VAR_INT(long)
  467. PY_VAR_INT(long long)
  468. PY_VAR_INT(unsigned char)
  469. PY_VAR_INT(unsigned short)
  470. PY_VAR_INT(unsigned int)
  471. PY_VAR_INT(unsigned long)
  472. PY_VAR_INT(unsigned long long)
  473. #define PY_VAR_FLOAT(T) \
  474. inline PyObject* py_var(VM* vm, T _val){ \
  475. PK_UNUSED(vm); \
  476. BitsCvt val(static_cast<f64>(_val)); \
  477. i64 bits = val._int & Number::c1; \
  478. i64 tail = val._int & Number::c2; \
  479. if(tail == 0b10){ \
  480. if(bits&0b100) bits += 0b100; \
  481. }else if(tail == 0b11){ \
  482. bits += 0b100; \
  483. } \
  484. bits |= 0b10; \
  485. return reinterpret_cast<PyObject*>(bits); \
  486. }
  487. PY_VAR_FLOAT(float)
  488. PY_VAR_FLOAT(double)
  489. #undef PY_VAR_INT
  490. #undef PY_VAR_FLOAT
  491. inline PyObject* py_var(VM* vm, bool val){
  492. return val ? vm->True : vm->False;
  493. }
  494. template<> inline bool py_cast<bool>(VM* vm, PyObject* obj){
  495. if(obj == vm->True) return true;
  496. if(obj == vm->False) return false;
  497. vm->check_non_tagged_type(obj, vm->tp_bool);
  498. return false;
  499. }
  500. template<> inline bool _py_cast<bool>(VM* vm, PyObject* obj){
  501. return obj == vm->True;
  502. }
  503. template<> inline CString py_cast<CString>(VM* vm, PyObject* obj){
  504. vm->check_non_tagged_type(obj, vm->tp_str);
  505. return PK_OBJ_GET(Str, obj).c_str();
  506. }
  507. template<> inline CString _py_cast<CString>(VM* vm, PyObject* obj){
  508. return PK_OBJ_GET(Str, obj).c_str();
  509. }
  510. inline PyObject* py_var(VM* vm, const char val[]){
  511. return VAR(Str(val));
  512. }
  513. inline PyObject* py_var(VM* vm, std::string val){
  514. return VAR(Str(std::move(val)));
  515. }
  516. inline PyObject* py_var(VM* vm, std::string_view val){
  517. return VAR(Str(val));
  518. }
  519. inline PyObject* py_var(VM* vm, NoReturn val){
  520. PK_UNUSED(val);
  521. return vm->None;
  522. }
  523. inline PyObject* py_var(VM* vm, PyObject* val){
  524. PK_UNUSED(vm);
  525. return val;
  526. }
  527. template<int ARGC>
  528. PyObject* VM::bind_method(PyObject* obj, Str name, NativeFuncC fn) {
  529. check_non_tagged_type(obj, tp_type);
  530. PyObject* nf = VAR(NativeFunc(fn, ARGC, true));
  531. obj->attr().set(name, nf);
  532. return nf;
  533. }
  534. template<int ARGC>
  535. PyObject* VM::bind_func(PyObject* obj, Str name, NativeFuncC fn) {
  536. PyObject* nf = VAR(NativeFunc(fn, ARGC, false));
  537. obj->attr().set(name, nf);
  538. return nf;
  539. }
  540. /***************************************************/
  541. template<typename T>
  542. PyObject* PyArrayGetItem(VM* vm, PyObject* obj, PyObject* index){
  543. static_assert(std::is_same_v<T, List> || std::is_same_v<T, Tuple>);
  544. const T& self = _CAST(T&, obj);
  545. if(is_non_tagged_type(index, vm->tp_slice)){
  546. const Slice& s = _CAST(Slice&, index);
  547. int start, stop, step;
  548. vm->parse_int_slice(s, self.size(), start, stop, step);
  549. List new_list;
  550. for(int i=start; step>0?i<stop:i>stop; i+=step) new_list.push_back(self[i]);
  551. return VAR(T(std::move(new_list)));
  552. }
  553. int i = CAST(int, index);
  554. i = vm->normalized_index(i, self.size());
  555. return self[i];
  556. }
  557. } // namespace pkpy