///|
priv type Ref
///|
fn Ref::lua(self : Ref) -> Lua {
@c.with_unsafe_borrowed(self, ptr => {
let ptr : @c.Pointer[Byte] = ptr.cast()
let state_ptr = (ptr.cast() : @c.Pointer[@c.Pointer[Unit]]).load()
@c.unsafe_return(state_ptr)
})
}
///|
fn Ref::int(self : Ref) -> Int {
@c.with_unsafe_borrowed(self, ptr => {
let ptr : @c.Pointer[Byte] = ptr.cast()
ptr.add(@c.sizeof((ignore : (@c.Pointer[Unit]) -> Unit))).cast().load()
})
}
///|
fn Lua::new_ref(lua : Lua) -> Ref {
// ptr -> +---------+
// | lua ptr |
// +---------+
// | ref int |
// +---------+
// Incref lua
let lua_ptr = @c.unsafe_borrow(lua)
// Creates reference
let ref_int = @aux.ref_(@lua.State::of_pointer(lua_ptr), @lua.registry_index)
let ptr = @moonbit.make_external_object(
ptr => {
let ptr : @c.Pointer[Byte] = ptr.cast()
let state = (ptr.cast() : @c.Pointer[@c.Pointer[Unit]]).load()
let ref_int : Int = ptr
.add(@c.sizeof((ignore : (@c.Pointer[Unit]) -> Unit)))
.cast()
.load()
// Release the reference
@aux.unref(@lua.State::of_pointer(state), @lua.registry_index, ref_int)
// Decref lua
let lua : Lua = @c.unsafe_return(state)
ignore(lua)
},
@c.sizeof((ignore : (@c.Pointer[Unit]) -> Unit)) +
@c.sizeof((ignore : (Int) -> Unit)),
)
// Convert to char * for pointer arithmetic
let ptr : @c.Pointer[Byte] = ptr.cast()
// Store lua pointer
(ptr.cast() : @c.Pointer[@c.Pointer[Unit]]).store(lua_ptr)
// Store reference integer after the pointer
ptr
.add(@c.sizeof((ignore : (@c.Pointer[Unit]) -> Unit)))
.cast()
.store(ref_int)
@c.unsafe_return(ptr.cast())
}