123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- package lua
- import (
- "fmt"
- "strings"
- )
- const (
- VarArgHasArg uint8 = 1
- VarArgIsVarArg uint8 = 2
- VarArgNeedsArg uint8 = 4
- )
- type DbgLocalInfo struct {
- Name string
- StartPc int
- EndPc int
- }
- type DbgCall struct {
- Name string
- Pc int
- }
- type FunctionProto struct {
- SourceName string
- LineDefined int
- LastLineDefined int
- NumUpvalues uint8
- NumParameters uint8
- IsVarArg uint8
- NumUsedRegisters uint8
- Code []uint32
- Constants []LValue
- FunctionPrototypes []*FunctionProto
- DbgSourcePositions []int
- DbgLocals []*DbgLocalInfo
- DbgCalls []DbgCall
- DbgUpvalues []string
- stringConstants []string
- }
- /* Upvalue {{{ */
- type Upvalue struct {
- next *Upvalue
- reg *registry
- index int
- value LValue
- closed bool
- }
- func (uv *Upvalue) Value() LValue {
- //if uv.IsClosed() {
- if uv.closed || uv.reg == nil {
- return uv.value
- }
- //return uv.reg.Get(uv.index)
- return uv.reg.array[uv.index]
- }
- func (uv *Upvalue) SetValue(value LValue) {
- if uv.IsClosed() {
- uv.value = value
- } else {
- uv.reg.Set(uv.index, value)
- }
- }
- func (uv *Upvalue) Close() {
- value := uv.Value()
- uv.closed = true
- uv.value = value
- }
- func (uv *Upvalue) IsClosed() bool {
- return uv.closed || uv.reg == nil
- }
- func UpvalueIndex(i int) int {
- return GlobalsIndex - i
- }
- /* }}} */
- /* FunctionProto {{{ */
- func newFunctionProto(name string) *FunctionProto {
- return &FunctionProto{
- SourceName: name,
- LineDefined: 0,
- LastLineDefined: 0,
- NumUpvalues: 0,
- NumParameters: 0,
- IsVarArg: 0,
- NumUsedRegisters: 2,
- Code: make([]uint32, 0, 128),
- Constants: make([]LValue, 0, 32),
- FunctionPrototypes: make([]*FunctionProto, 0, 16),
- DbgSourcePositions: make([]int, 0, 128),
- DbgLocals: make([]*DbgLocalInfo, 0, 16),
- DbgCalls: make([]DbgCall, 0, 128),
- DbgUpvalues: make([]string, 0, 16),
- stringConstants: make([]string, 0, 32),
- }
- }
- func (fp *FunctionProto) String() string {
- return fp.str(1, 0)
- }
- func (fp *FunctionProto) str(level int, count int) string {
- indent := strings.Repeat(" ", level-1)
- buf := []string{}
- buf = append(buf, fmt.Sprintf("%v; function [%v] definition (level %v)\n",
- indent, count, level))
- buf = append(buf, fmt.Sprintf("%v; %v upvalues, %v params, %v stacks\n",
- indent, fp.NumUpvalues, fp.NumParameters, fp.NumUsedRegisters))
- for reg, linfo := range fp.DbgLocals {
- buf = append(buf, fmt.Sprintf("%v.local %v ; %v\n", indent, linfo.Name, reg))
- }
- for reg, upvalue := range fp.DbgUpvalues {
- buf = append(buf, fmt.Sprintf("%v.upvalue %v ; %v\n", indent, upvalue, reg))
- }
- for reg, conzt := range fp.Constants {
- buf = append(buf, fmt.Sprintf("%v.const %v ; %v\n", indent, conzt.String(), reg))
- }
- buf = append(buf, "\n")
- protono := 0
- for no, code := range fp.Code {
- inst := opGetOpCode(code)
- if inst == OP_CLOSURE {
- buf = append(buf, "\n")
- buf = append(buf, fp.FunctionPrototypes[protono].str(level+1, protono))
- buf = append(buf, "\n")
- protono++
- }
- buf = append(buf, fmt.Sprintf("%v[%03d] %v (line:%v)\n",
- indent, no+1, opToString(code), fp.DbgSourcePositions[no]))
- }
- buf = append(buf, fmt.Sprintf("%v; end of function\n", indent))
- return strings.Join(buf, "")
- }
- /* }}} */
- /* LFunction {{{ */
- func newLFunctionL(proto *FunctionProto, env *LTable, nupvalue int) *LFunction {
- return &LFunction{
- IsG: false,
- Env: env,
- Proto: proto,
- GFunction: nil,
- Upvalues: make([]*Upvalue, nupvalue),
- }
- }
- func newLFunctionG(gfunc LGFunction, env *LTable, nupvalue int) *LFunction {
- return &LFunction{
- IsG: true,
- Env: env,
- Proto: nil,
- GFunction: gfunc,
- Upvalues: make([]*Upvalue, nupvalue),
- }
- }
- func (fn *LFunction) LocalName(regno, pc int) (string, bool) {
- if fn.IsG {
- return "", false
- }
- p := fn.Proto
- for i := 0; i < len(p.DbgLocals) && p.DbgLocals[i].StartPc < pc; i++ {
- if pc < p.DbgLocals[i].EndPc {
- regno--
- if regno == 0 {
- return p.DbgLocals[i].Name, true
- }
- }
- }
- return "", false
- }
- /* }}} */
|