feat: complete lua.h debug bindings

This commit is contained in:
Erica Marigold 2024-07-19 22:31:54 +05:30
parent ba0fb22db0
commit 2829fa5c31
No known key found for this signature in database
GPG key ID: 2768CC0C23D245D1
4 changed files with 138 additions and 4 deletions

View file

@ -28,4 +28,8 @@ void* clua_newuserdatadtor(lua_State* L, size_t sz, void* dtor) {
void clua_setuserdatadtor(lua_State* L, int tag, void* dtor) { void clua_setuserdatadtor(lua_State* L, int tag, void* dtor) {
return lua_setuserdatadtor(L, tag, (lua_Destructor)dtor); return lua_setuserdatadtor(L, tag, (lua_Destructor)dtor);
}
void clua_getcoverage(lua_State* L, int funcindex, void* context, void* callback) {
return lua_getcoverage(L, funcindex, context, (lua_Coverage)callback);
} }

View file

@ -5,4 +5,5 @@ lua_State* clua_newstate(void* f, void* ud);
l_noret cluaL_errorL(lua_State* L, char* msg); l_noret cluaL_errorL(lua_State* L, char* msg);
void clua_pushcclosurek(lua_State* L, void* f, char* debugname, int nup, void* cont); void clua_pushcclosurek(lua_State* L, void* f, char* debugname, int nup, void* cont);
void* clua_newuserdatadtor(lua_State* L, size_t sz, void* dtor); void* clua_newuserdatadtor(lua_State* L, size_t sz, void* dtor);
void clua_setuserdatadtor(lua_State* L, int tag, void* dtor); void clua_setuserdatadtor(lua_State* L, int tag, void* dtor);
void clua_getcoverage(lua_State* L, int funcindex, void* context, void* callback);

View file

@ -9,7 +9,11 @@ package internal
#include "clua.h" #include "clua.h"
*/ */
import "C" import "C"
import "unsafe" import (
"errors"
"strconv"
"unsafe"
)
const ( const (
LUA_OK = iota + 1 LUA_OK = iota + 1
@ -679,5 +683,128 @@ func Unref(L *LuaState, ref int32) {
C.lua_unref(L, C.int(ref)) C.lua_unref(L, C.int(ref))
} }
// TODO: Free udtor's after func //
// TODO: Rest of it // ==================
// Debug API
// ==================
//
const LUA_IDSIZE = 256
type LuaDebug struct {
Name string
What string
Source string
ShortSrc string
LineDefined int8
CurrentLine int8
NUpVals uint8
NParams uint8
IsVarArg int8
Userdata unsafe.Pointer
SSbuf string // size = LUA_IDSIZE
}
type LuaHook = func(L *LuaState, ar *LuaDebug)
type LuaCoverage = func(
context unsafe.Pointer,
function string,
linedefined int32,
depth int32,
hits *int32,
size uint64,
)
func StackDepth(L *LuaState) int32 {
return int32(C.lua_stackdepth(L))
}
// Errors if invalid LuaDebug provided, returns -1
func GetInfo(L *LuaState, level int32, what string, ar *LuaDebug) (int32, error) {
cwhat := C.CString(what)
defer C.free(unsafe.Pointer(cwhat))
car := C.malloc(C.size_t(unsafe.Sizeof(*ar)))
defer C.free(car)
cname := C.CString(ar.Name)
defer C.free(unsafe.Pointer(cname))
carwhat := C.CString(ar.What)
defer C.free(unsafe.Pointer(carwhat))
csource := C.CString(ar.Source)
defer C.free(unsafe.Pointer(csource))
cshortsrc := C.CString(ar.ShortSrc)
defer C.free(unsafe.Pointer(cshortsrc))
if len(ar.SSbuf)+1 != LUA_IDSIZE { // contains null delimeter, so LUA_IDSIZE is one greater than the string len
return -1, errors.New("lua.GetInfo: SSbuf must be exactly " + strconv.Itoa(LUA_IDSIZE) + " bytes long")
}
cssbuf := C.CString(ar.SSbuf)
defer C.free(unsafe.Pointer(cssbuf))
*(**C.lua_Debug)(car) = &C.lua_Debug{
name: cname,
what: carwhat,
source: csource,
short_src: cshortsrc,
linedefined: C.int(ar.LineDefined),
currentline: C.int(ar.CurrentLine),
nupvals: C.uchar(ar.NUpVals),
nparams: C.uchar(ar.NParams),
isvararg: C.char(ar.IsVarArg),
userdata: ar.Userdata,
ssbuf: *(*[LUA_IDSIZE]C.char)(unsafe.Pointer(cssbuf)),
}
return int32(C.lua_getinfo(L, C.int(level), cwhat, (*C.lua_Debug)(car))), nil
}
func GetArgument(L *LuaState, level int32, n int32) int32 {
return int32(C.lua_getargument(L, C.int(level), C.int(n)))
}
func GetLocal(L *LuaState, level int32, n int32) string {
return C.GoString(C.lua_getlocal(L, C.int(level), C.int(n)))
}
func SetLocal(L *LuaState, level int32, n int32) string {
return C.GoString(C.lua_setlocal(L, C.int(level), C.int(n)))
}
func GetUpvalue(L *LuaState, funcindex int32, n int32) string {
return C.GoString(C.lua_getupvalue(L, C.int(funcindex), C.int(n)))
}
func SetUpvalue(L *LuaState, funcindex int32, n int32) string {
return C.GoString(C.lua_setupvalue(L, C.int(funcindex), C.int(n)))
}
func SingleStep(L *LuaState, enabled bool) {
cenabled := C.int(0)
if enabled {
cenabled = C.int(1)
}
C.lua_singlestep(L, cenabled)
}
func Breakpoint(L *LuaState, funcindex int32, line int32, enabled bool) int32 {
cenabled := C.int(0)
if enabled {
cenabled = C.int(1)
}
return int32(C.lua_breakpoint(L, C.int(funcindex), C.int(line), cenabled))
}
func GetCoverage(L *LuaState, funcindex int32, context unsafe.Pointer, callback LuaCoverage) {
ccallback := C.malloc(C.size_t(unsafe.Sizeof(callback)))
defer C.free(ccallback)
*(*LuaCoverage)(ccallback) = callback
C.clua_getcoverage(L, C.int(funcindex), context, ccallback)
}
func DebugTrace(L *LuaState) string {
return C.GoString(C.lua_debugtrace(L))
}
// TODO: Implement "useful macros" section as Go functions
// TODO: lua_Callbacks and related stuff

View file

@ -11,6 +11,8 @@ func main() {
return 0 return 0
}, "test", 0, nil) }, "test", 0, nil)
lualib.GetInfo(lua, 1, "str", &lualib.LuaDebug{ssbuf: n})
if !lualib.IsCFunction(lua, 1) { if !lualib.IsCFunction(lua, 1) {
panic("CFunction was not correctly pushed onto stack") panic("CFunction was not correctly pushed onto stack")
} }