tile38/vendor/github.com/yuin/gopher-lua/debuglib.go

163 lines
3.2 KiB
Go

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 := L.OptString(1, "")
level := L.OptInt(2, 1)
traceback := strings.TrimSpace(L.stackTrace(level))
if len(msg) > 0 {
traceback = fmt.Sprintf("%s\n%s", msg, traceback)
}
L.Push(LString(traceback))
return 1
}