From d3fd70a98dda53b7c9923f3fe3569bce41fe21f5 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 13 May 2024 23:34:05 +0800 Subject: [PATCH] some fix --- include/pocketpy/bindings.h | 73 ++++++++++++++++++------------------ include/pocketpy/common.h | 19 ++++++---- include/pocketpy/obj.h | 14 ++++--- include/pocketpy/tuplelist.h | 2 +- include/pocketpy/vm.h | 6 ++- src/linalg.cpp | 2 - 6 files changed, 62 insertions(+), 54 deletions(-) diff --git a/include/pocketpy/bindings.h b/include/pocketpy/bindings.h index bb4c9d6f..566d3599 100644 --- a/include/pocketpy/bindings.h +++ b/include/pocketpy/bindings.h @@ -123,43 +123,44 @@ template return vm->bind(obj, sig, func); } /*****************************************************************/ -#define PY_FIELD(T, NAME, EXPR) \ + +#define PY_FIELD(T, NAME, EXPR) \ vm->bind_property(type, NAME, \ [](VM* vm, ArgsView args){ \ - T& self = PK_OBJ_GET(T, args[0]); \ - return VAR(self.EXPR); \ + obj_get_t self = PK_OBJ_GET(T, args[0]); \ + return VAR(self.EXPR); \ }, \ [](VM* vm, ArgsView args){ \ - T& self = PK_OBJ_GET(T, args[0]); \ - self.EXPR = CAST(decltype(self.EXPR), args[1]); \ + obj_get_t self = PK_OBJ_GET(T, args[0]); \ + self.EXPR = CAST(decltype(self.EXPR), args[1]); \ return vm->None; \ }); -#define PY_READONLY_FIELD(T, NAME, EXPR) \ +#define PY_READONLY_FIELD(T, NAME, EXPR) \ vm->bind_property(type, NAME, \ [](VM* vm, ArgsView args){ \ - T& self = PK_OBJ_GET(T, args[0]); \ - return VAR(self.EXPR); \ + obj_get_t self = PK_OBJ_GET(T, args[0]); \ + return VAR(self.EXPR); \ }); -#define PY_PROPERTY(T, NAME, FGET, FSET) \ - vm->bind_property(type, NAME, \ - [](VM* vm, ArgsView args){ \ - T& self = PK_OBJ_GET(T, args[0]); \ - return VAR(self.FGET()); \ - }, \ - [](VM* vm, ArgsView args){ \ - T& self = _CAST(T&, args[0]); \ - using __NT = decltype(self.FGET()); \ - self.FSET(CAST(__NT, args[1])); \ +#define PY_PROPERTY(T, NAME, FGET, FSET) \ + vm->bind_property(type, NAME, \ + [](VM* vm, ArgsView args){ \ + obj_get_t self = PK_OBJ_GET(T, args[0]); \ + return VAR(self.FGET()); \ + }, \ + [](VM* vm, ArgsView args){ \ + obj_get_t self = PK_OBJ_GET(T, args[0]); \ + using __NT = decltype(self.FGET()); \ + self.FSET(CAST(__NT, args[1])); \ return vm->None; \ }); -#define PY_READONLY_PROPERTY(T, NAME, FGET) \ - vm->bind_property(type, NAME, \ - [](VM* vm, ArgsView args){ \ - T& self = PK_OBJ_GET(T, args[0]); \ - return VAR(self.FGET()); \ +#define PY_READONLY_PROPERTY(T, NAME, FGET) \ + vm->bind_property(type, NAME, \ + [](VM* vm, ArgsView args){ \ + obj_get_t self = PK_OBJ_GET(T, args[0]); \ + return VAR(self.FGET()); \ }); /*****************************************************************/ #define PY_STRUCT_LIKE(wT) \ @@ -173,22 +174,22 @@ template memcpy(&_CAST(wT&, obj), s.p, sizeof(wT)); \ return obj; \ }, {}, BindType::STATICMETHOD); \ - vm->bind_func(type, "tostruct", 1, [](VM* vm, ArgsView args){ \ + vm->bind_func(type, "tostruct", 1, [](VM* vm, ArgsView args){ \ wT& self = _CAST(wT&, args[0]); \ return vm->new_user_object(&self, sizeof(wT)); \ }); \ - vm->bind_func(type, "addr", 1, [](VM* vm, ArgsView args){ \ + vm->bind_func(type, "addr", 1, [](VM* vm, ArgsView args){ \ wT& self = _CAST(wT&, args[0]); \ return vm->new_user_object(&self); \ }); \ - vm->bind_func(type, "copy", 1, [](VM* vm, ArgsView args){ \ + vm->bind_func(type, "copy", 1, [](VM* vm, ArgsView args){ \ wT& self = _CAST(wT&, args[0]); \ return vm->new_user_object(self); \ }); \ - vm->bind_func(type, "sizeof", 1, [](VM* vm, ArgsView args){ \ + vm->bind_func(type, "sizeof", 1, [](VM* vm, ArgsView args){ \ return VAR(sizeof(wT)); \ }); \ - vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){ \ + vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){ \ wT& self = _CAST(wT&, _0); \ if(!vm->isinstance(_1, vm->_tp_user())) return vm->NotImplemented; \ wT& other = _CAST(wT&, _1); \ @@ -196,17 +197,17 @@ template }); \ #define PY_POINTER_SETGETITEM(T) \ - vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){ \ - VoidP& self = PK_OBJ_GET(VoidP, _0); \ + vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){ \ + VoidP& self = PK_OBJ_GET(VoidP, _0); \ i64 i = CAST(i64, _1); \ T* tgt = reinterpret_cast(self.ptr); \ return VAR(tgt[i]); \ }); \ - vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1, PyVar _2){ \ - VoidP& self = PK_OBJ_GET(VoidP, _0); \ - i64 i = CAST(i64, _1); \ - T* tgt = reinterpret_cast(self.ptr); \ - tgt[i] = CAST(T, _2); \ - }); \ + vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1, PyVar _2){ \ + VoidP& self = PK_OBJ_GET(VoidP, _0); \ + i64 i = CAST(i64, _1); \ + T* tgt = reinterpret_cast(self.ptr); \ + tgt[i] = CAST(T, _2); \ + }); \ } // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/common.h b/include/pocketpy/common.h index 3770fbd5..4bb4be47 100644 --- a/include/pocketpy/common.h +++ b/include/pocketpy/common.h @@ -166,7 +166,16 @@ inline constexpr bool is_floating_point_v = std::is_same_v || std::is_ inline const char* PK_HEX_TABLE = "0123456789abcdef"; struct PyObject; -// using PyVar = PyObject *; + +// by default, only `int` and `float` enable SSO +// users can specialize this template to enable SSO for other types +// SSO types cannot have instance dict +template +inline constexpr bool is_sso_v = is_integral_v || is_floating_point_v; + +// make a obj_get_t for a given type T, if is_sso_v is true, return T, else return T& +template +using obj_get_t = std::conditional_t, T, T&>; struct PyVar final{ Type type; @@ -224,17 +233,11 @@ struct PyVar final{ i64 hash() const { return _1; } template - T& obj_get(); + obj_get_t obj_get(); }; static_assert(sizeof(PyVar) == 16 && is_pod_v); -// by default, only `int` and `float` enable SSO -// users can specialize this template to enable SSO for other types -// SSO types cannot have instance dict -template -inline constexpr bool is_sso_v = is_integral_v || is_floating_point_v; - } // namespace pkpy diff --git a/include/pocketpy/obj.h b/include/pocketpy/obj.h index 65cf31ba..026eb7ed 100644 --- a/include/pocketpy/obj.h +++ b/include/pocketpy/obj.h @@ -141,7 +141,8 @@ template struct has_gc_marker struct Py_ final: PyObject { - static_assert(!std::is_reference_v, "T must not be a reference type. Are you using `PK_OBJ_GET(T&, ...)`?"); + static_assert(!std::is_reference_v); + static_assert(!is_sso_v); T _value; void _obj_gc_mark() override { @@ -165,11 +166,14 @@ StrName _type_name(VM* vm, Type type); template T to_void_p(VM*, PyVar); PyVar from_void_p(VM*, void*); + template -T& PyVar::obj_get(){ - static_assert(!std::is_reference_v); - if(is_sso) return as(); - return ((Py_*)(get()))->_value; +obj_get_t PyVar::obj_get(){ + if constexpr(is_sso_v){ + return as(); + }else{ + return ((Py_*)(get()))->_value; + } } #define PK_OBJ_GET(T, obj) (obj).obj_get() diff --git a/include/pocketpy/tuplelist.h b/include/pocketpy/tuplelist.h index b3b5afda..e8fd5779 100644 --- a/include/pocketpy/tuplelist.h +++ b/include/pocketpy/tuplelist.h @@ -49,7 +49,7 @@ struct ArgsView{ PyVar* end() const { return _end; } int size() const { return _end - _begin; } bool empty() const { return _begin == _end; } - PyVar& operator[](int i) const { return _begin[i]; } + PyVar operator[](int i) const { return _begin[i]; } List to_list() const; Tuple to_tuple() const; diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index 0f204cb5..8bf0e53d 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -562,8 +562,10 @@ __T _py_cast__internal(VM* vm, PyVar obj) { return PK_OBJ_GET(T, obj); } } - Type type = vm->_find_type_in_cxx_typeid_map(); - if constexpr(with_check) vm->check_compatible_type(obj, type); + if constexpr(with_check){ + Type type = vm->_find_type_in_cxx_typeid_map(); + vm->check_compatible_type(obj, type); + } return PK_OBJ_GET(T, obj); } diff --git a/src/linalg.cpp b/src/linalg.cpp index 3de8bb90..4a3b6835 100644 --- a/src/linalg.cpp +++ b/src/linalg.cpp @@ -34,8 +34,6 @@ namespace pkpy{ Vec##D self = _CAST(Vec##D, _0); \ if(vm->is_user_type(_1)){ \ Vec##D other = _CAST(Vec##D, _1); \ - std::cout << self.x << ',' << self.y << '\n';\ - std::cout << other.x << ',' << other.y << '\n';\ return VAR(self * other); \ } \ f64 other = CAST(f64, _1); \