123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- package lua
- import (
- "fmt"
- "strings"
- )
- func OpenDebug(L *LState) int {
- dbgmod := L.RegisterModule(DebugLibName, debugFuncs)
- L.Push(dbgmod)
- return 1
- }
- var debugFuncs = map[string]LGFunction{
- "getfenv": debugGetFEnv,
- "getinfo": debugGetInfo,
- "getlocal": debugGetLocal,
- "getmetatable": debugGetMetatable,
- "getupvalue": debugGetUpvalue,
- "setfenv": debugSetFEnv,
- "setlocal": debugSetLocal,
- "setmetatable": debugSetMetatable,
- "setupvalue": debugSetUpvalue,
- "traceback": debugTraceback,
- }
- func debugGetFEnv(L *LState) int {
- L.Push(L.GetFEnv(L.CheckAny(1)))
- return 1
- }
- func debugGetInfo(L *LState) int {
- L.CheckTypes(1, LTFunction, LTNumber)
- arg1 := L.Get(1)
- what := L.OptString(2, "Slunf")
- var dbg *Debug
- var fn LValue
- var err error
- var ok bool
- switch lv := arg1.(type) {
- case *LFunction:
- dbg = &Debug{}
- fn, err = L.GetInfo(">"+what, dbg, lv)
- case LNumber:
- dbg, ok = L.GetStack(int(lv))
- if !ok {
- L.Push(LNil)
- return 1
- }
- fn, err = L.GetInfo(what, dbg, LNil)
- }
- if err != nil {
- L.Push(LNil)
- return 1
- }
- tbl := L.NewTable()
- if len(dbg.Name) > 0 {
- tbl.RawSetString("name", LString(dbg.Name))
- } else {
- tbl.RawSetString("name", LNil)
- }
- tbl.RawSetString("what", LString(dbg.What))
- tbl.RawSetString("source", LString(dbg.Source))
- tbl.RawSetString("currentline", LNumber(dbg.CurrentLine))
- tbl.RawSetString("nups", LNumber(dbg.NUpvalues))
- tbl.RawSetString("linedefined", LNumber(dbg.LineDefined))
- tbl.RawSetString("lastlinedefined", LNumber(dbg.LastLineDefined))
- tbl.RawSetString("func", fn)
- L.Push(tbl)
- return 1
- }
- func debugGetLocal(L *LState) int {
- level := L.CheckInt(1)
- idx := L.CheckInt(2)
- dbg, ok := L.GetStack(level)
- if !ok {
- L.ArgError(1, "level out of range")
- }
- name, value := L.GetLocal(dbg, idx)
- if len(name) > 0 {
- L.Push(LString(name))
- L.Push(value)
- return 2
- }
- L.Push(LNil)
- return 1
- }
- func debugGetMetatable(L *LState) int {
- L.Push(L.GetMetatable(L.CheckAny(1)))
- return 1
- }
- func debugGetUpvalue(L *LState) int {
- fn := L.CheckFunction(1)
- idx := L.CheckInt(2)
- name, value := L.GetUpvalue(fn, idx)
- if len(name) > 0 {
- L.Push(LString(name))
- L.Push(value)
- return 2
- }
- L.Push(LNil)
- return 1
- }
- func debugSetFEnv(L *LState) int {
- L.SetFEnv(L.CheckAny(1), L.CheckAny(2))
- return 0
- }
- func debugSetLocal(L *LState) int {
- level := L.CheckInt(1)
- idx := L.CheckInt(2)
- value := L.CheckAny(3)
- dbg, ok := L.GetStack(level)
- if !ok {
- L.ArgError(1, "level out of range")
- }
- name := L.SetLocal(dbg, idx, value)
- if len(name) > 0 {
- L.Push(LString(name))
- } else {
- L.Push(LNil)
- }
- return 1
- }
- func debugSetMetatable(L *LState) int {
- L.CheckTypes(2, LTNil, LTTable)
- obj := L.Get(1)
- mt := L.Get(2)
- L.SetMetatable(obj, mt)
- L.SetTop(1)
- return 1
- }
- func debugSetUpvalue(L *LState) int {
- fn := L.CheckFunction(1)
- idx := L.CheckInt(2)
- value := L.CheckAny(3)
- name := L.SetUpvalue(fn, idx, value)
- if len(name) > 0 {
- L.Push(LString(name))
- } else {
- L.Push(LNil)
- }
- return 1
- }
- func debugTraceback(L *LState) int {
- msg := ""
- level := L.OptInt(2, 1)
- ls := L
- if L.GetTop() > 0 {
- if s, ok := L.Get(1).(LString); ok {
- msg = string(s)
- }
- if l, ok := L.Get(1).(*LState); ok {
- ls = l
- msg = ""
- }
- }
- traceback := strings.TrimSpace(ls.stackTrace(level))
- if len(msg) > 0 {
- traceback = fmt.Sprintf("%s\n%s", msg, traceback)
- }
- L.Push(LString(traceback))
- return 1
- }
|