From 4976e82f0f7224243eaf09d29d2993391fe8a8f4 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 3 Oct 2024 21:02:20 +0800 Subject: [PATCH 1/2] c/lua:debug --- c/lua/_demo/debug/debug.go | 48 ++++++++++++++++ c/lua/lua.go | 110 +++++++++++++++++++++++++------------ c/lua/luaconf.go | 9 +++ 3 files changed, 132 insertions(+), 35 deletions(-) create mode 100644 c/lua/_demo/debug/debug.go diff --git a/c/lua/_demo/debug/debug.go b/c/lua/_demo/debug/debug.go new file mode 100644 index 00000000..5604a76d --- /dev/null +++ b/c/lua/_demo/debug/debug.go @@ -0,0 +1,48 @@ +package main + +import ( + "unsafe" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +func Hook(L *lua.State, ar *lua.Debug) { + L.Getinfo(c.Str("nSl"), ar) + c.Printf(c.Str("Hook called:")) + if name := ar.Name; name != nil { + c.Printf(c.Str("name: %s,"), name) + } + if what := ar.What; what != nil { + c.Printf(c.Str("what: %s,"), what) + } + c.Printf(c.Str("source: %s,"), c.Pointer(unsafe.SliceData(ar.ShortSrc[:]))) + c.Printf(c.Str("line: %d\n"), ar.Currentline) +} + +func main() { + L := lua.Newstate__1() + defer L.Close() + L.Openlibs() + + L.Sethook(Hook, lua.MASKLINE, 0) + + code := + `function hello(name) + print('Hello, ' .. name .. '!') + end + hello('llgo')` + if res := L.Dostring(c.Str(code)); res != lua.OK { + c.Printf(c.Str("error: %s\n"), L.Tostring(-1)) + } + +} + +/* Expected output: +Hook called:what: main,source: [string "function hello(name) ..."],line: 3 +Hook called:what: main,source: [string "function hello(name) ..."],line: 1 +Hook called:what: main,source: [string "function hello(name) ..."],line: 4 +Hook called:name: hello,what: Lua,source: [string "function hello(name) ..."],line: 2 +Hello, llgo! +Hook called:name: hello,what: Lua,source: [string "function hello(name) ..."],line: 3 +*/ diff --git a/c/lua/lua.go b/c/lua/lua.go index 6c64b5b9..acbf69d1 100644 --- a/c/lua/lua.go +++ b/c/lua/lua.go @@ -59,7 +59,7 @@ const ( FUNCTION c.Int = 6 USERDATA c.Int = 7 THREAD c.Int = 8 - UMTYPES c.Int = 9 + NUMTYPES c.Int = 9 ) /* minimum Lua stack available to a C function */ @@ -121,27 +121,15 @@ type Alloc func(ud c.Pointer, ptr c.Pointer, osize c.Ulong, nsize c.Ulong) c.Poi * Type for warning functions */ -// typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont); - -/* - * Type used by the debug API to collect debug information - */ - -// typedef struct lua_Debug lua_Debug; +// llgo:type C +type WarnFunction func(ud c.Pointer, msg c.Char, tocont c.Int) /* * Functions to be called by the debugger in specific events */ -// typedef void (*lua_Hook) (State *L, lua_Debug *ar); - -/* - * generic extra include file - */ - -// #if defined(LUA_USER_H) -// #include LUA_USER_H -// #endif +// llgo:type C +type Hook func(L *State, ar *Debug) /* * RCS ident string @@ -408,8 +396,11 @@ func (L *State) Yield(nresults c.Int) c.Int { return * Warning-related functions */ -//void (lua_setwarnf) (State *L, lua_WarnFunction f, void *ud); -//void (lua_warning) (State *L, const char *msg, int tocont); +// llgo:link (*State).Setwarnf C.lua_setwarnf +func (L *State) Setwarnf(f WarnFunction, ud c.Pointer) {} + +// llgo:link (*State).Warning C.lua_warning +func (L *State) Warning(msg *c.Char, tocont c.Int) {} /* * garbage-collection function and options @@ -429,7 +420,8 @@ const ( GCINC = 11 ) -// LUA_API int (lua_gc) (State *L, int what, ...); +// llgo:link (*State).Gc C.lua_gc +func (L *State) Gc(what c.Int, __llgo_va_list ...any) c.Int { return 0 } /* * miscellaneous functions @@ -531,7 +523,9 @@ func (L *State) Setuservalue(idx c.Int) c.Int { return L.Setiuservalue(idx, 1) } -// #define LUA_NUMTAGS LUA_NUMTYPES +const ( + NUMTAGS = NUMTYPES +) /* }============================================================== */ @@ -564,22 +558,68 @@ const ( MASKCOUNT = 1 << HOOKCOUNT ) -// LUA_API int (lua_getstack) (State *L, int level, lua_Debug *ar); -// LUA_API int (lua_getinfo) (State *L, const char *what, lua_Debug *ar); -// LUA_API const char *(lua_getlocal) (State *L, const lua_Debug *ar, int n); -// LUA_API const char *(lua_setlocal) (State *L, const lua_Debug *ar, int n); -// LUA_API const char *(lua_getupvalue) (State *L, int funcindex, int n); -// LUA_API const char *(lua_setupvalue) (State *L, int funcindex, int n); +// llgo:link (*State).Getstack C.lua_getstack +func (L *State) Getstack(level c.Int, ar *Debug) c.Int { return 0 } -// LUA_API void *(lua_upvalueid) (State *L, int fidx, int n); -// LUA_API void (lua_upvaluejoin) (State *L, int fidx1, int n1, int fidx2, int n2); +// llgo:link (*State).Getinfo C.lua_getinfo +func (L *State) Getinfo(what *c.Char, ar *Debug) c.Int { return 0 } -// LUA_API void (lua_sethook) (State *L, lua_Hook func, int mask, int count); -// LUA_API lua_Hook (lua_gethook) (State *L); -// LUA_API int (lua_gethookmask) (State *L); -// LUA_API int (lua_gethookcount) (State *L); +// llgo:link (*State).Getlocal C.lua_getlocal +func (L *State) Getlocal(ar *Debug, n c.Int) *c.Char { return nil } -// LUA_API int (lua_setcstacklimit) (State *L, unsigned int limit); +// llgo:link (*State).Setlocal C.lua_setlocal +func (L *State) Setlocal(ar *Debug, n c.Int) *c.Char { return nil } + +// llgo:link (*State).Getupvalue C.lua_getupvalue +func (L *State) Getupvalue(funcindex c.Int, n c.Int) *c.Char { return nil } + +// llgo:link (*State).Setupvalue C.lua_setupvalue +func (L *State) Setupvalue(funcindex c.Int, n c.Int) *c.Char { return nil } + +// llgo:link (*State).Upvalueid C.lua_upvalueid +func (L *State) Upvalueid(fidx c.Int, n c.Int) c.Pointer { return nil } + +// llgo:link (*State).Upvaluejoin C.lua_upvaluejoin +func (L *State) Upvaluejoin(fidx1 c.Int, n1 c.Int, fidx2 c.Int, n2 c.Int) {} + +// llgo:link (*State).Sethook C.lua_sethook +func (L *State) Sethook(fn Hook, mask c.Int, count c.Int) {} + +// llgo:link (*State).Gethook C.lua_gethook +func (L *State) Gethook() Hook { return nil } + +// llgo:link (*State).Gethookmask C.lua_gethookmask +func (L *State) Gethookmask() c.Int { return 0 } + +// llgo:link (*State).Gethookcount C.lua_gethookcount +func (L *State) Gethookcount() c.Int { return 0 } + +// llgo:link (*State).Setcstacklimit C.lua_setcstacklimit +func (L *State) Setcstacklimit(limit c.Uint) c.Int { return 0 } + +type CallInfo struct { + Unused [8]byte +} + +type Debug struct { + Event c.Int + Name *c.Char /* (n) */ + Namewhat *c.Char /* (n) 'global', 'local', 'field', 'method' */ + What *c.Char /* (S) 'Lua', 'C', 'main', 'tail' */ + Source *c.Char /* (S) */ + Srclen uintptr /* (S) */ + Currentline c.Int /* (l) */ + Linedefined c.Int /* (S) */ + Lastlinedefined c.Int /* (S) */ + Nups byte /* (u) number of upvalues */ + Nparams byte /* (u) number of parameters */ + Isvararg c.Char /* (u) */ + Istailcall c.Char /* (t) */ + Ftransfer uint16 /* (r) index of first value transferred */ + Ntransfer uint16 /* (r) number of transferred values */ + ShortSrc [IDSIZE]c.Char /* (S) */ + /* private part */ + ICi *CallInfo +} -// struct lua_Debug /* }====================================================================== */ diff --git a/c/lua/luaconf.go b/c/lua/luaconf.go index 3d995ba6..65b37f68 100644 --- a/c/lua/luaconf.go +++ b/c/lua/luaconf.go @@ -19,3 +19,12 @@ package lua const ( MAXSTACK = 1000000 ) + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +** of a function in debug information. +** CHANGE it if you want a different size. +*/ +const ( + IDSIZE = 60 +) From e2091413eac334161462cb82aab90bcfd535df3d Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Fri, 4 Oct 2024 15:02:18 +0800 Subject: [PATCH 2/2] c/lua:extraspace --- c/lua/_demo/extraspace/extraspace.go | 42 ++++++++++++++++++++++++++++ c/lua/lua.go | 4 ++- c/lua/luaconf.go | 11 ++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 c/lua/_demo/extraspace/extraspace.go diff --git a/c/lua/_demo/extraspace/extraspace.go b/c/lua/_demo/extraspace/extraspace.go new file mode 100644 index 00000000..75089a0c --- /dev/null +++ b/c/lua/_demo/extraspace/extraspace.go @@ -0,0 +1,42 @@ +package main + +import ( + "unsafe" + _ "unsafe" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +func GetData(L *lua.State) c.Int { + extra := (*int)(L.Getextraspace()) + L.Pushfstring(c.Str("Stored integer is: %d"), *extra) + return 1 +} + +func main() { + L := lua.Newstate__1() + defer L.Close() + + L.Openlibs() + + extra := (*int)(L.Getextraspace()) + *extra = 42 + + difference := uintptr(unsafe.Pointer(L)) - uintptr(L.Getextraspace()) + if difference == unsafe.Sizeof(uintptr(0)) { + c.Printf(c.Str("Extra space is pointer size\n"), unsafe.Sizeof(uintptr(0))) + } + + L.Pushcfunction(GetData) + L.Setglobal(c.Str("GetData")) + + if L.Dostring(c.Str("print(GetData())")) != lua.OK { + c.Printf(c.Str("Error: %s\n"), L.Tostring(-1)) + } +} + +/* Expected output: +Extra space is pointer size +Stored integer is: 42 +*/ diff --git a/c/lua/lua.go b/c/lua/lua.go index acbf69d1..c5e35da5 100644 --- a/c/lua/lua.go +++ b/c/lua/lua.go @@ -460,7 +460,9 @@ func (L *State) Closeslot(idx c.Int) {} ** =============================================================== */ -// #define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE)) +func (L *State) Getextraspace() c.Pointer { + return c.Pointer(uintptr(c.Pointer(L)) - EXTRASPACE) +} func (L *State) Tonumber(idx c.Int) Number { return L.Tonumberx(idx, nil) } func (L *State) Tostring(idx c.Int) *c.Char { return L.Tolstring(idx, nil) } func (L *State) Tointeger(idx c.Int) Integer { return L.Tointegerx(idx, nil) } diff --git a/c/lua/luaconf.go b/c/lua/luaconf.go index 65b37f68..03bac83c 100644 --- a/c/lua/luaconf.go +++ b/c/lua/luaconf.go @@ -1,5 +1,7 @@ package lua +import "unsafe" + /* ** {================================================================== ** Macros that affect the API and must be stable (that is, must be the @@ -20,6 +22,15 @@ const ( MAXSTACK = 1000000 ) +/* +@@ LUA_EXTRASPACE defines the size of a raw memory area associated with +** a Lua state with very fast access. +** CHANGE it if you need a different size. +*/ +const ( + EXTRASPACE = unsafe.Sizeof(uintptr(0)) +) + /* @@ LUA_IDSIZE gives the maximum size for the description of the source ** of a function in debug information.