Replies: 2 comments 8 replies
-
There is a
Could you provide more detail please what is |
Beta Was this translation helpful? Give feedback.
-
Unfortunately, scoped userdata is destroyed when the scope ends making it not fit for my usecase of having long lived dynamic userdata that can be returned from FFI to Go. It also doesn't allow for selectively sharing metatables which is useful to reduce memory usage. Lastly, it's much harder implementation wise coupled with worse performance for my use case (even if it could be used out of scope by e.g. storing a permanent heap allocated scope) as there's more synchronization and FFI calls+callbacks neeeded between the Rust+Go layer mostly (but not fully) due to the use of UserDataRegistry (function callbacks from Rust to Go are hard to get right) Basically, I'd like for a way to make a userdata using a normal table to act as the userdatas metatable and get stored data (like a cgo handle) from the userdata Associated data is effectively the data stored with the dynamic userdata and can be fetched by Rust after creation from the AnyUserData. The associated data is static as it must be able to live for the lifetime of the program and should have a type id If implemented, this should probably be a Luau specific feature as I don't know how to make it safe outside of Luau BTW, gluau uses my dynamic userdata proposal right now if it'd help to see an actual use case for this. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Note: I've already implemented this in a fork and it seems really useful as a feature so I wanted to pitch it to mlua upstream
Note 2: All code snippets below are merely illustrative of one possible way of doing this that is already implemented and working
The Problem
Currently, mlua's support for userdata is mostly generic and compile time oriented. While it's super ergonomic when all userdata is defined at compile time (admittedly, most use cases), its not very helpful if the userdata is defined at runtime. While mlua does have some support for runtime defined userdata (e.g.
create_any_userdata
), these methods are still semigeneric and require all userdata's of type T to share the same metatable. These limitations caused me problems with one of my hobby projects, gluau, in which the userdata is not known at compile time to Rust.Proposed Solution
To solve this, I propose the addition of another way of creating userdata in mlua called dynamic userdata. A dynamic userdata is a special type of userdata that is fully defined at runtime through the use of a associated data and a metatable that is used to create/define the dynamic userdata and its properties. For example, using the below function signature:
In short, a dynamic userdata takes an associated data of type T and a metatable (on non-Luau, mlua can add a constraint/error if this metatable contains
__gc
). Both of these things can be defined at runtime trivially (for an example, see gluau which already uses this to implement userdata). An example implementation of how mlua could interally make a dynamic userdata with a given metatable could look like:where
DynamicUserDataPtr
is:Users can then pass this dynamically created userdata to Lua code etc. To retrieve the stored 'associated data', I propose the addition of a new
dynamic_data
method toAnyUserData
which could look like:Of note here is that a dynamic userdata, unlike normal userdata, cannot be borrowed, taken, compared with
is
(at least without changes tois
) or destroyed (outside of GC by Lua/Luau). The job of doing this would fall on the user.Beta Was this translation helpful? Give feedback.
All reactions