vm.h 24 KB

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