ensure funcs get unique pointer

This commit is contained in:
Sky Johnson 2025-05-22 10:31:00 -05:00
parent 6a2eb9df63
commit 7a9dfd47d3

View File

@ -40,31 +40,30 @@ var (
func goFunctionWrapper(L *C.lua_State) C.int { func goFunctionWrapper(L *C.lua_State) C.int {
state := &State{L: L} state := &State{L: L}
// Get function pointer from the first upvalue
ptr := C.lua_touserdata(L, C.get_upvalue_index(1)) ptr := C.lua_touserdata(L, C.get_upvalue_index(1))
if ptr == nil { if ptr == nil {
state.PushString("error: function pointer not found") state.PushString("error: function pointer not found")
return -1 return -1
} }
// Use read-lock for better concurrency
functionRegistry.RLock() functionRegistry.RLock()
fn, ok := functionRegistry.funcs[ptr] fn, ok := functionRegistry.funcs[ptr]
functionRegistry.RUnlock() functionRegistry.RUnlock()
if !ok { if !ok {
// Debug logging
fmt.Printf("Function not found for pointer %p\n", ptr)
state.PushString("error: function not found in registry") state.PushString("error: function not found in registry")
return -1 return -1
} }
// Call the Go function
return C.int(fn(state)) return C.int(fn(state))
} }
// PushGoFunction wraps a Go function and pushes it onto the Lua stack // PushGoFunction wraps a Go function and pushes it onto the Lua stack
func (s *State) PushGoFunction(fn GoFunction) error { func (s *State) PushGoFunction(fn GoFunction) error {
// Allocate a pointer to use as the function key // Allocate unique memory for each function
ptr := C.malloc(1) ptr := C.malloc(C.size_t(unsafe.Sizeof(uintptr(0))))
if ptr == nil { if ptr == nil {
return fmt.Errorf("failed to allocate memory for function pointer") return fmt.Errorf("failed to allocate memory for function pointer")
} }
@ -74,10 +73,8 @@ func (s *State) PushGoFunction(fn GoFunction) error {
functionRegistry.funcs[ptr] = fn functionRegistry.funcs[ptr] = fn
functionRegistry.Unlock() functionRegistry.Unlock()
// Push the pointer as lightuserdata (first upvalue) // Push the pointer as lightuserdata
C.lua_pushlightuserdata(s.L, ptr) C.lua_pushlightuserdata(s.L, ptr)
// Create closure with the C wrapper and the upvalue
C.lua_pushcclosure(s.L, (*[0]byte)(C.goFunctionWrapper), 1) C.lua_pushcclosure(s.L, (*[0]byte)(C.goFunctionWrapper), 1)
return nil return nil