diff --git a/docs/bindings.md b/docs/bindings.md index bf15982b..eefd1dd9 100644 --- a/docs/bindings.md +++ b/docs/bindings.md @@ -80,7 +80,7 @@ int main(){ } ``` -The 2nd way is to use `vm->bind`'s last parameter `userdata`, you can store a POD type smaller than 8 bytes. +The 2nd way is to use `vm->bind`'s last parameter `userdata`, you can store an `pkpy::any` object. And use `lambda_get_userdata(args.begin())` to get it inside the lambda body. ```cpp diff --git a/include/pocketpy/any.h b/include/pocketpy/any.h index 464c6627..ac4800c1 100644 --- a/include/pocketpy/any.h +++ b/include/pocketpy/any.h @@ -66,6 +66,4 @@ bool any_cast(const any& a, T** out){ return true; } -using UserData = any; - } // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/codeobject.h b/include/pocketpy/codeobject.h index ac3ef81e..48d3184f 100644 --- a/include/pocketpy/codeobject.h +++ b/include/pocketpy/codeobject.h @@ -130,9 +130,9 @@ struct NativeFunc { // new style decl-based call FuncDecl_ decl; - UserData _userdata; + any _userdata; - void set_userdata(UserData&& data) { + void set_userdata(any&& data) { if(_userdata){ throw std::runtime_error("NativeFunc userdata already set"); } @@ -186,7 +186,7 @@ struct Py_ final: PyObject { template T& lambda_get_userdata(PyObject** p){ static_assert(std::is_same_v>); - UserData* ud; + any* ud; if(p[-1] != PY_NULL) ud = &PK_OBJ_GET(NativeFunc, p[-1])._userdata; else ud = &PK_OBJ_GET(NativeFunc, p[-2])._userdata; T* out; diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index de960d02..3f79a2ac 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -306,21 +306,21 @@ public: #endif #if PK_REGION("General Bindings") - PyObject* bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, UserData userdata={}, BindType bt=BindType::DEFAULT); - PyObject* bind_func(Type type, StrName name, int argc, NativeFuncC fn, UserData userdata={}, BindType bt=BindType::DEFAULT){ + PyObject* bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT); + PyObject* bind_func(Type type, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT){ return bind_func(_t(type), name, argc, fn, std::move(userdata), bt); } PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr); template PyObject* bind_field(PyObject*, const char*, F T::*); - PyObject* bind(PyObject*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT); + PyObject* bind(PyObject*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT); template PyObject* bind(PyObject*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT); template PyObject* bind(PyObject*, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT); - PyObject* bind(PyObject*, const char*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT); + PyObject* bind(PyObject*, const char*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT); template PyObject* bind(PyObject*, const char*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT); template diff --git a/src/vm.cpp b/src/vm.cpp index 1f3e5a66..5c23521d 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -1227,7 +1227,7 @@ void VM::setattr(PyObject* obj, StrName name, PyObject* value){ obj->attr().set(name, value); } -PyObject* VM::bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, UserData userdata, BindType bt) { +PyObject* VM::bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, any userdata, BindType bt) { PyObject* nf = VAR(NativeFunc(fn, argc)); PK_OBJ_GET(NativeFunc, nf).set_userdata(std::move(userdata)); switch(bt){ @@ -1239,11 +1239,11 @@ PyObject* VM::bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, U return nf; } -PyObject* VM::bind(PyObject* obj, const char* sig, NativeFuncC fn, UserData userdata, BindType bt){ +PyObject* VM::bind(PyObject* obj, const char* sig, NativeFuncC fn, any userdata, BindType bt){ return bind(obj, sig, nullptr, fn, std::move(userdata), bt); } -PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, NativeFuncC fn, UserData userdata, BindType bt){ +PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, NativeFuncC fn, any userdata, BindType bt){ CodeObject_ co; try{ // fn(a, b, *c, d=1) -> None