github.com/bitxmesh/gopher-lua@v0.0.0-20190327085718-93c344ef97a4/state.go (about)

     1  package lua
     2  
     3  ////////////////////////////////////////////////////////
     4  // This file was generated by go-inline. DO NOT EDIT. //
     5  ////////////////////////////////////////////////////////
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  	"github.com/yuin/gopher-lua/parse"
    11  	"io"
    12  	"math"
    13  	"os"
    14  	"runtime"
    15  	"strings"
    16  	"sync/atomic"
    17  	"time"
    18  )
    19  
    20  const MultRet = -1
    21  const RegistryIndex = -10000
    22  const EnvironIndex = -10001
    23  const GlobalsIndex = -10002
    24  
    25  /* ApiError {{{ */
    26  
    27  type ApiError struct {
    28  	Type       ApiErrorType
    29  	Object     LValue
    30  	StackTrace string
    31  	// Underlying error. This attribute is set only if the Type is ApiErrorFile or ApiErrorSyntax
    32  	Cause error
    33  }
    34  
    35  func newApiError(code ApiErrorType, object LValue) *ApiError {
    36  	return &ApiError{code, object, "", nil}
    37  }
    38  
    39  func newApiErrorS(code ApiErrorType, message string) *ApiError {
    40  	return newApiError(code, LString(message))
    41  }
    42  
    43  func newApiErrorE(code ApiErrorType, err error) *ApiError {
    44  	return &ApiError{code, LString(err.Error()), "", err}
    45  }
    46  
    47  func (e *ApiError) Error() string {
    48  	if len(e.StackTrace) > 0 {
    49  		return fmt.Sprintf("%s\n%s", e.Object.String(), e.StackTrace)
    50  	}
    51  	return e.Object.String()
    52  }
    53  
    54  type ApiErrorType int
    55  
    56  const (
    57  	ApiErrorSyntax ApiErrorType = iota
    58  	ApiErrorFile
    59  	ApiErrorRun
    60  	ApiErrorError
    61  	ApiErrorPanic
    62  )
    63  
    64  /* }}} */
    65  
    66  /* ResumeState {{{ */
    67  
    68  type ResumeState int
    69  
    70  const (
    71  	ResumeOK ResumeState = iota
    72  	ResumeYield
    73  	ResumeError
    74  )
    75  
    76  /* }}} */
    77  
    78  /* P {{{ */
    79  
    80  type P struct {
    81  	Fn      LValue
    82  	NRet    int
    83  	Protect bool
    84  	Handler *LFunction
    85  }
    86  
    87  /* }}} */
    88  
    89  /* Options {{{ */
    90  
    91  // Options is a configuration that is used to create a new LState.
    92  type Options struct {
    93  	// Call stack size. This defaults to `lua.CallStackSize`.
    94  	CallStackSize int
    95  	// Data stack size. This defaults to `lua.RegistrySize`.
    96  	RegistrySize int
    97  	// Controls whether or not libraries are opened by default
    98  	SkipOpenLibs bool
    99  	// Tells whether a Go stacktrace should be included in a Lua stacktrace when panics occur.
   100  	IncludeGoStackTrace bool
   101  }
   102  
   103  /* }}} */
   104  
   105  /* Debug {{{ */
   106  
   107  type Debug struct {
   108  	frame           *callFrame
   109  	Name            string
   110  	What            string
   111  	Source          string
   112  	CurrentLine     int
   113  	NUpvalues       int
   114  	LineDefined     int
   115  	LastLineDefined int
   116  }
   117  
   118  /* }}} */
   119  
   120  /* callFrame {{{ */
   121  
   122  type callFrame struct {
   123  	Idx        int
   124  	Fn         *LFunction
   125  	Parent     *callFrame
   126  	Pc         int
   127  	Base       int
   128  	LocalBase  int
   129  	ReturnBase int
   130  	NArgs      int
   131  	NRet       int
   132  	TailCall   int
   133  }
   134  
   135  type callFrameStack struct {
   136  	array []callFrame
   137  	sp    int
   138  }
   139  
   140  func newCallFrameStack(size int) *callFrameStack {
   141  	return &callFrameStack{
   142  		array: make([]callFrame, size),
   143  		sp:    0,
   144  	}
   145  }
   146  
   147  func (cs *callFrameStack) IsEmpty() bool { return cs.sp == 0 }
   148  
   149  func (cs *callFrameStack) Clear() {
   150  	cs.sp = 0
   151  }
   152  
   153  func (cs *callFrameStack) Push(v callFrame) { // +inline-start
   154  	cs.array[cs.sp] = v
   155  	cs.array[cs.sp].Idx = cs.sp
   156  	cs.sp++
   157  } // +inline-end
   158  
   159  func (cs *callFrameStack) Remove(sp int) {
   160  	psp := sp - 1
   161  	nsp := sp + 1
   162  	var pre *callFrame
   163  	var next *callFrame
   164  	if psp > 0 {
   165  		pre = &cs.array[psp]
   166  	}
   167  	if nsp < cs.sp {
   168  		next = &cs.array[nsp]
   169  	}
   170  	if next != nil {
   171  		next.Parent = pre
   172  	}
   173  	for i := sp; i+1 < cs.sp; i++ {
   174  		cs.array[i] = cs.array[i+1]
   175  		cs.array[i].Idx = i
   176  		cs.sp = i
   177  	}
   178  	cs.sp++
   179  }
   180  
   181  func (cs *callFrameStack) Sp() int {
   182  	return cs.sp
   183  }
   184  
   185  func (cs *callFrameStack) SetSp(sp int) {
   186  	cs.sp = sp
   187  }
   188  
   189  func (cs *callFrameStack) Last() *callFrame {
   190  	if cs.sp == 0 {
   191  		return nil
   192  	}
   193  	return &cs.array[cs.sp-1]
   194  }
   195  
   196  func (cs *callFrameStack) At(sp int) *callFrame {
   197  	return &cs.array[sp]
   198  }
   199  
   200  func (cs *callFrameStack) Pop() *callFrame {
   201  	cs.sp--
   202  	return &cs.array[cs.sp]
   203  }
   204  
   205  /* }}} */
   206  
   207  /* registry {{{ */
   208  
   209  type registry struct {
   210  	array []LValue
   211  	top   int
   212  	alloc *allocator
   213  }
   214  
   215  func newRegistry(size int, alloc *allocator) *registry {
   216  	return &registry{make([]LValue, size), 0, alloc}
   217  }
   218  
   219  func (rg *registry) SetTop(top int) {
   220  	oldtop := rg.top
   221  	rg.top = top
   222  	for i := oldtop; i < rg.top; i++ {
   223  		rg.array[i] = LNil
   224  	}
   225  	for i := rg.top; i < oldtop; i++ {
   226  		rg.array[i] = LNil
   227  	}
   228  }
   229  
   230  func (rg *registry) Top() int {
   231  	return rg.top
   232  }
   233  
   234  func (rg *registry) Push(v LValue) {
   235  	rg.array[rg.top] = v
   236  	rg.top++
   237  }
   238  
   239  func (rg *registry) Pop() LValue {
   240  	v := rg.array[rg.top-1]
   241  	rg.array[rg.top-1] = LNil
   242  	rg.top--
   243  	return v
   244  }
   245  
   246  func (rg *registry) Get(reg int) LValue {
   247  	return rg.array[reg]
   248  }
   249  
   250  func (rg *registry) CopyRange(regv, start, limit, n int) { // +inline-start
   251  	for i := 0; i < n; i++ {
   252  		if tidx := start + i; tidx >= rg.top || limit > -1 && tidx >= limit || tidx < 0 {
   253  			rg.array[regv+i] = LNil
   254  		} else {
   255  			rg.array[regv+i] = rg.array[tidx]
   256  		}
   257  	}
   258  	rg.top = regv + n
   259  } // +inline-end
   260  
   261  func (rg *registry) FillNil(regm, n int) { // +inline-start
   262  	for i := 0; i < n; i++ {
   263  		rg.array[regm+i] = LNil
   264  	}
   265  	rg.top = regm + n
   266  } // +inline-end
   267  
   268  func (rg *registry) Insert(value LValue, reg int) {
   269  	top := rg.Top()
   270  	if reg >= top {
   271  		rg.Set(reg, value)
   272  		return
   273  	}
   274  	top--
   275  	for ; top >= reg; top-- {
   276  		rg.Set(top+1, rg.Get(top))
   277  	}
   278  	rg.Set(reg, value)
   279  }
   280  
   281  func (rg *registry) Set(reg int, val LValue) {
   282  	rg.array[reg] = val
   283  	if reg >= rg.top {
   284  		rg.top = reg + 1
   285  	}
   286  }
   287  
   288  func (rg *registry) SetNumber(reg int, val LNumber) {
   289  	rg.array[reg] = rg.alloc.LNumber2I(val)
   290  	if reg >= rg.top {
   291  		rg.top = reg + 1
   292  	}
   293  } /* }}} */
   294  
   295  /* Global {{{ */
   296  
   297  func newGlobal() *Global {
   298  	return &Global{
   299  		MainThread: nil,
   300  		Registry:   newLTable(0, 32),
   301  		Global:     newLTable(0, 64),
   302  		builtinMts: make(map[int]LValue),
   303  		tempFiles:  make([]*os.File, 0, 10),
   304  	}
   305  }
   306  
   307  /* }}} */
   308  
   309  /* package local methods {{{ */
   310  
   311  func panicWithTraceback(L *LState) {
   312  	err := newApiError(ApiErrorRun, L.Get(-1))
   313  	err.StackTrace = L.stackTrace(0)
   314  	panic(err)
   315  }
   316  
   317  func panicWithoutTraceback(L *LState) {
   318  	err := newApiError(ApiErrorRun, L.Get(-1))
   319  	panic(err)
   320  }
   321  
   322  func newLState(options Options) *LState {
   323  	al := newAllocator(32)
   324  	ls := &LState{
   325  		G:       newGlobal(),
   326  		Parent:  nil,
   327  		Panic:   panicWithTraceback,
   328  		Dead:    false,
   329  		Options: options,
   330  
   331  		stop:         0,
   332  		reg:          newRegistry(options.RegistrySize, al),
   333  		stack:        newCallFrameStack(options.CallStackSize),
   334  		alloc:        al,
   335  		currentFrame: nil,
   336  		wrapped:      false,
   337  		uvcache:      nil,
   338  		hasErrorFunc: false,
   339  		mainLoop:     mainLoop,
   340  		ctx:          nil,
   341  	}
   342  	ls.Env = ls.G.Global
   343  	return ls
   344  }
   345  
   346  func (ls *LState) printReg() {
   347  	println("-------------------------")
   348  	println("thread:", ls)
   349  	println("top:", ls.reg.Top())
   350  	if ls.currentFrame != nil {
   351  		println("function base:", ls.currentFrame.Base)
   352  		println("return base:", ls.currentFrame.ReturnBase)
   353  	} else {
   354  		println("(vm not started)")
   355  	}
   356  	println("local base:", ls.currentLocalBase())
   357  	for i := 0; i < ls.reg.Top(); i++ {
   358  		println(i, ls.reg.Get(i).String())
   359  	}
   360  	println("-------------------------")
   361  }
   362  
   363  func (ls *LState) printCallStack() {
   364  	println("-------------------------")
   365  	for i := 0; i < ls.stack.Sp(); i++ {
   366  		print(i)
   367  		print(" ")
   368  		frame := ls.stack.At(i)
   369  		if frame == nil {
   370  			break
   371  		}
   372  		if frame.Fn.IsG {
   373  			println("IsG:", true, "Frame:", frame, "Fn:", frame.Fn)
   374  		} else {
   375  			println("IsG:", false, "Frame:", frame, "Fn:", frame.Fn, "pc:", frame.Pc)
   376  		}
   377  	}
   378  	println("-------------------------")
   379  }
   380  
   381  func (ls *LState) closeAllUpvalues() { // +inline-start
   382  	for cf := ls.currentFrame; cf != nil; cf = cf.Parent {
   383  		if !cf.Fn.IsG {
   384  			ls.closeUpvalues(cf.LocalBase)
   385  		}
   386  	}
   387  } // +inline-end
   388  
   389  func (ls *LState) raiseError(level int, format string, args ...interface{}) {
   390  	if !ls.hasErrorFunc {
   391  		ls.closeAllUpvalues()
   392  	}
   393  	message := format
   394  	if len(args) > 0 {
   395  		message = fmt.Sprintf(format, args...)
   396  	}
   397  	if level > 0 {
   398  		message = fmt.Sprintf("%v %v", ls.where(level-1, true), message)
   399  	}
   400  	ls.reg.Push(LString(message))
   401  	ls.Panic(ls)
   402  }
   403  
   404  func (ls *LState) findLocal(frame *callFrame, no int) string {
   405  	fn := frame.Fn
   406  	if !fn.IsG {
   407  		if name, ok := fn.LocalName(no, frame.Pc-1); ok {
   408  			return name
   409  		}
   410  	}
   411  	var top int
   412  	if ls.currentFrame == frame {
   413  		top = ls.reg.Top()
   414  	} else if frame.Idx+1 < ls.stack.Sp() {
   415  		top = ls.stack.At(frame.Idx + 1).Base
   416  	} else {
   417  		return ""
   418  	}
   419  	if top-frame.LocalBase >= no {
   420  		return "(*temporary)"
   421  	}
   422  	return ""
   423  }
   424  
   425  func (ls *LState) where(level int, skipg bool) string {
   426  	dbg, ok := ls.GetStack(level)
   427  	if !ok {
   428  		return ""
   429  	}
   430  	cf := dbg.frame
   431  	proto := cf.Fn.Proto
   432  	sourcename := "[G]"
   433  	if proto != nil {
   434  		sourcename = proto.SourceName
   435  	} else if skipg {
   436  		return ls.where(level+1, skipg)
   437  	}
   438  	line := ""
   439  	if proto != nil {
   440  		line = fmt.Sprintf("%v:", proto.DbgSourcePositions[cf.Pc-1])
   441  	}
   442  	return fmt.Sprintf("%v:%v", sourcename, line)
   443  }
   444  
   445  func (ls *LState) stackTrace(level int) string {
   446  	buf := []string{}
   447  	header := "stack traceback:"
   448  	if ls.currentFrame != nil {
   449  		i := 0
   450  		for dbg, ok := ls.GetStack(i); ok; dbg, ok = ls.GetStack(i) {
   451  			cf := dbg.frame
   452  			buf = append(buf, fmt.Sprintf("\t%v in %v", ls.Where(i), ls.formattedFrameFuncName(cf)))
   453  			if !cf.Fn.IsG && cf.TailCall > 0 {
   454  				for tc := cf.TailCall; tc > 0; tc-- {
   455  					buf = append(buf, "\t(tailcall): ?")
   456  					i++
   457  				}
   458  			}
   459  			i++
   460  		}
   461  	}
   462  	buf = append(buf, fmt.Sprintf("\t%v: %v", "[G]", "?"))
   463  	buf = buf[intMax(0, intMin(level, len(buf))):len(buf)]
   464  	if len(buf) > 20 {
   465  		newbuf := make([]string, 0, 20)
   466  		newbuf = append(newbuf, buf[0:7]...)
   467  		newbuf = append(newbuf, "\t...")
   468  		newbuf = append(newbuf, buf[len(buf)-7:len(buf)]...)
   469  		buf = newbuf
   470  	}
   471  	return fmt.Sprintf("%s\n%s", header, strings.Join(buf, "\n"))
   472  }
   473  
   474  func (ls *LState) formattedFrameFuncName(fr *callFrame) string {
   475  	name, ischunk := ls.frameFuncName(fr)
   476  	if ischunk {
   477  		return name
   478  	}
   479  	if name[0] != '(' && name[0] != '<' {
   480  		return fmt.Sprintf("function '%s'", name)
   481  	}
   482  	return fmt.Sprintf("function %s", name)
   483  }
   484  
   485  func (ls *LState) rawFrameFuncName(fr *callFrame) string {
   486  	name, _ := ls.frameFuncName(fr)
   487  	return name
   488  }
   489  
   490  func (ls *LState) frameFuncName(fr *callFrame) (string, bool) {
   491  	frame := fr.Parent
   492  	if frame == nil {
   493  		if ls.Parent == nil {
   494  			return "main chunk", true
   495  		} else {
   496  			return "corountine", true
   497  		}
   498  	}
   499  	if !frame.Fn.IsG {
   500  		pc := frame.Pc - 1
   501  		for _, call := range frame.Fn.Proto.DbgCalls {
   502  			if call.Pc == pc {
   503  				name := call.Name
   504  				if (name == "?" || fr.TailCall > 0) && !fr.Fn.IsG {
   505  					name = fmt.Sprintf("<%v:%v>", fr.Fn.Proto.SourceName, fr.Fn.Proto.LineDefined)
   506  				}
   507  				return name, false
   508  			}
   509  		}
   510  	}
   511  	if !fr.Fn.IsG {
   512  		return fmt.Sprintf("<%v:%v>", fr.Fn.Proto.SourceName, fr.Fn.Proto.LineDefined), false
   513  	}
   514  	return "(anonymous)", false
   515  }
   516  
   517  func (ls *LState) isStarted() bool {
   518  	return ls.currentFrame != nil
   519  }
   520  
   521  func (ls *LState) kill() {
   522  	ls.Dead = true
   523  }
   524  
   525  func (ls *LState) indexToReg(idx int) int {
   526  	base := ls.currentLocalBase()
   527  	if idx > 0 {
   528  		return base + idx - 1
   529  	} else if idx == 0 {
   530  		return -1
   531  	} else {
   532  		tidx := ls.reg.Top() + idx
   533  		if tidx < base {
   534  			return -1
   535  		}
   536  		return tidx
   537  	}
   538  }
   539  
   540  func (ls *LState) currentLocalBase() int {
   541  	base := 0
   542  	if ls.currentFrame != nil {
   543  		base = ls.currentFrame.LocalBase
   544  	}
   545  	return base
   546  }
   547  
   548  func (ls *LState) currentEnv() *LTable {
   549  	return ls.Env
   550  	/*
   551  		if ls.currentFrame == nil {
   552  			return ls.Env
   553  		}
   554  		return ls.currentFrame.Fn.Env
   555  	*/
   556  }
   557  
   558  func (ls *LState) rkValue(idx int) LValue {
   559  	/*
   560  		if OpIsK(idx) {
   561  			return ls.currentFrame.Fn.Proto.Constants[opIndexK(idx)]
   562  		}
   563  		return ls.reg.Get(ls.currentFrame.LocalBase + idx)
   564  	*/
   565  	if (idx & opBitRk) != 0 {
   566  		return ls.currentFrame.Fn.Proto.Constants[idx & ^opBitRk]
   567  	}
   568  	return ls.reg.array[ls.currentFrame.LocalBase+idx]
   569  }
   570  
   571  func (ls *LState) rkString(idx int) string {
   572  	if (idx & opBitRk) != 0 {
   573  		return ls.currentFrame.Fn.Proto.stringConstants[idx & ^opBitRk]
   574  	}
   575  	return string(ls.reg.array[ls.currentFrame.LocalBase+idx].(LString))
   576  }
   577  
   578  func (ls *LState) closeUpvalues(idx int) { // +inline-start
   579  	if ls.uvcache != nil {
   580  		var prev *Upvalue
   581  		for uv := ls.uvcache; uv != nil; uv = uv.next {
   582  			if uv.index >= idx {
   583  				if prev != nil {
   584  					prev.next = nil
   585  				} else {
   586  					ls.uvcache = nil
   587  				}
   588  				uv.Close()
   589  			}
   590  			prev = uv
   591  		}
   592  	}
   593  } // +inline-end
   594  
   595  func (ls *LState) findUpvalue(idx int) *Upvalue {
   596  	var prev *Upvalue
   597  	var next *Upvalue
   598  	if ls.uvcache != nil {
   599  		for uv := ls.uvcache; uv != nil; uv = uv.next {
   600  			if uv.index == idx {
   601  				return uv
   602  			}
   603  			if uv.index > idx {
   604  				next = uv
   605  				break
   606  			}
   607  			prev = uv
   608  		}
   609  	}
   610  	uv := &Upvalue{reg: ls.reg, index: idx, closed: false}
   611  	if prev != nil {
   612  		prev.next = uv
   613  	} else {
   614  		ls.uvcache = uv
   615  	}
   616  	if next != nil {
   617  		uv.next = next
   618  	}
   619  	return uv
   620  }
   621  
   622  func (ls *LState) metatable(lvalue LValue, rawget bool) LValue {
   623  	var metatable LValue = LNil
   624  	switch obj := lvalue.(type) {
   625  	case *LTable:
   626  		metatable = obj.Metatable
   627  	case *LUserData:
   628  		metatable = obj.Metatable
   629  	default:
   630  		if table, ok := ls.G.builtinMts[int(obj.Type())]; ok {
   631  			metatable = table
   632  		}
   633  	}
   634  
   635  	if !rawget && metatable != LNil {
   636  		oldmt := metatable
   637  		if tb, ok := metatable.(*LTable); ok {
   638  			metatable = tb.RawGetString("__metatable")
   639  			if metatable == LNil {
   640  				metatable = oldmt
   641  			}
   642  		}
   643  	}
   644  
   645  	return metatable
   646  }
   647  
   648  func (ls *LState) metaOp1(lvalue LValue, event string) LValue {
   649  	if mt := ls.metatable(lvalue, true); mt != LNil {
   650  		if tb, ok := mt.(*LTable); ok {
   651  			return tb.RawGetString(event)
   652  		}
   653  	}
   654  	return LNil
   655  }
   656  
   657  func (ls *LState) metaOp2(value1, value2 LValue, event string) LValue {
   658  	if mt := ls.metatable(value1, true); mt != LNil {
   659  		if tb, ok := mt.(*LTable); ok {
   660  			if ret := tb.RawGetString(event); ret != LNil {
   661  				return ret
   662  			}
   663  		}
   664  	}
   665  	if mt := ls.metatable(value2, true); mt != LNil {
   666  		if tb, ok := mt.(*LTable); ok {
   667  			return tb.RawGetString(event)
   668  		}
   669  	}
   670  	return LNil
   671  }
   672  
   673  func (ls *LState) metaCall(lvalue LValue) (*LFunction, bool) {
   674  	if fn, ok := lvalue.(*LFunction); ok {
   675  		return fn, false
   676  	}
   677  	if fn, ok := ls.metaOp1(lvalue, "__call").(*LFunction); ok {
   678  		return fn, true
   679  	}
   680  	return nil, false
   681  }
   682  
   683  func (ls *LState) initCallFrame(cf *callFrame) { // +inline-start
   684  	if cf.Fn.IsG {
   685  		ls.reg.SetTop(cf.LocalBase + cf.NArgs)
   686  	} else {
   687  		proto := cf.Fn.Proto
   688  		nargs := cf.NArgs
   689  		np := int(proto.NumParameters)
   690  		for i := nargs; i < np; i++ {
   691  			ls.reg.array[cf.LocalBase+i] = LNil
   692  			nargs = np
   693  		}
   694  
   695  		if (proto.IsVarArg & VarArgIsVarArg) == 0 {
   696  			if nargs < int(proto.NumUsedRegisters) {
   697  				nargs = int(proto.NumUsedRegisters)
   698  			}
   699  			for i := np; i < nargs; i++ {
   700  				ls.reg.array[cf.LocalBase+i] = LNil
   701  			}
   702  			ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters)
   703  		} else {
   704  			/* swap vararg positions:
   705  					   closure
   706  					   namedparam1 <- lbase
   707  					   namedparam2
   708  					   vararg1
   709  					   vararg2
   710  
   711  			           TO
   712  
   713  					   closure
   714  					   nil
   715  					   nil
   716  					   vararg1
   717  					   vararg2
   718  					   namedparam1 <- lbase
   719  					   namedparam2
   720  			*/
   721  			nvarargs := nargs - np
   722  			if nvarargs < 0 {
   723  				nvarargs = 0
   724  			}
   725  
   726  			ls.reg.SetTop(cf.LocalBase + nargs + np)
   727  			for i := 0; i < np; i++ {
   728  				//ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i))
   729  				ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i]
   730  				//ls.reg.Set(cf.LocalBase+i, LNil)
   731  				ls.reg.array[cf.LocalBase+i] = LNil
   732  			}
   733  
   734  			if CompatVarArg {
   735  				ls.reg.SetTop(cf.LocalBase + nargs + np + 1)
   736  				if (proto.IsVarArg & VarArgNeedsArg) != 0 {
   737  					argtb := newLTable(nvarargs, 0)
   738  					for i := 0; i < nvarargs; i++ {
   739  						argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i))
   740  					}
   741  					argtb.RawSetString("n", LNumber(nvarargs))
   742  					//ls.reg.Set(cf.LocalBase+nargs+np, argtb)
   743  					ls.reg.array[cf.LocalBase+nargs+np] = argtb
   744  				} else {
   745  					ls.reg.array[cf.LocalBase+nargs+np] = LNil
   746  				}
   747  			}
   748  			cf.LocalBase += nargs
   749  			maxreg := cf.LocalBase + int(proto.NumUsedRegisters)
   750  			ls.reg.SetTop(maxreg)
   751  		}
   752  	}
   753  } // +inline-end
   754  
   755  func (ls *LState) pushCallFrame(cf callFrame, fn LValue, meta bool) { // +inline-start
   756  	if meta {
   757  		cf.NArgs++
   758  		ls.reg.Insert(fn, cf.LocalBase)
   759  	}
   760  	if cf.Fn == nil {
   761  		ls.RaiseError("attempt to call a non-function object")
   762  	}
   763  	if ls.stack.sp == ls.Options.CallStackSize {
   764  		ls.RaiseError("stack overflow")
   765  	}
   766  	// this section is inlined by go-inline
   767  	// source function is 'func (cs *callFrameStack) Push(v callFrame) ' in '_state.go'
   768  	{
   769  		cs := ls.stack
   770  		v := cf
   771  		cs.array[cs.sp] = v
   772  		cs.array[cs.sp].Idx = cs.sp
   773  		cs.sp++
   774  	}
   775  	newcf := ls.stack.Last()
   776  	// this section is inlined by go-inline
   777  	// source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go'
   778  	{
   779  		cf := newcf
   780  		if cf.Fn.IsG {
   781  			ls.reg.SetTop(cf.LocalBase + cf.NArgs)
   782  		} else {
   783  			proto := cf.Fn.Proto
   784  			nargs := cf.NArgs
   785  			np := int(proto.NumParameters)
   786  			for i := nargs; i < np; i++ {
   787  				ls.reg.array[cf.LocalBase+i] = LNil
   788  				nargs = np
   789  			}
   790  
   791  			if (proto.IsVarArg & VarArgIsVarArg) == 0 {
   792  				if nargs < int(proto.NumUsedRegisters) {
   793  					nargs = int(proto.NumUsedRegisters)
   794  				}
   795  				for i := np; i < nargs; i++ {
   796  					ls.reg.array[cf.LocalBase+i] = LNil
   797  				}
   798  				ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters)
   799  			} else {
   800  				/* swap vararg positions:
   801  						   closure
   802  						   namedparam1 <- lbase
   803  						   namedparam2
   804  						   vararg1
   805  						   vararg2
   806  
   807  				           TO
   808  
   809  						   closure
   810  						   nil
   811  						   nil
   812  						   vararg1
   813  						   vararg2
   814  						   namedparam1 <- lbase
   815  						   namedparam2
   816  				*/
   817  				nvarargs := nargs - np
   818  				if nvarargs < 0 {
   819  					nvarargs = 0
   820  				}
   821  
   822  				ls.reg.SetTop(cf.LocalBase + nargs + np)
   823  				for i := 0; i < np; i++ {
   824  					//ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i))
   825  					ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i]
   826  					//ls.reg.Set(cf.LocalBase+i, LNil)
   827  					ls.reg.array[cf.LocalBase+i] = LNil
   828  				}
   829  
   830  				if CompatVarArg {
   831  					ls.reg.SetTop(cf.LocalBase + nargs + np + 1)
   832  					if (proto.IsVarArg & VarArgNeedsArg) != 0 {
   833  						argtb := newLTable(nvarargs, 0)
   834  						for i := 0; i < nvarargs; i++ {
   835  							argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i))
   836  						}
   837  						argtb.RawSetString("n", LNumber(nvarargs))
   838  						//ls.reg.Set(cf.LocalBase+nargs+np, argtb)
   839  						ls.reg.array[cf.LocalBase+nargs+np] = argtb
   840  					} else {
   841  						ls.reg.array[cf.LocalBase+nargs+np] = LNil
   842  					}
   843  				}
   844  				cf.LocalBase += nargs
   845  				maxreg := cf.LocalBase + int(proto.NumUsedRegisters)
   846  				ls.reg.SetTop(maxreg)
   847  			}
   848  		}
   849  	}
   850  	ls.currentFrame = newcf
   851  } // +inline-end
   852  
   853  func (ls *LState) callR(nargs, nret, rbase int) {
   854  	base := ls.reg.Top() - nargs - 1
   855  	if rbase < 0 {
   856  		rbase = base
   857  	}
   858  	lv := ls.reg.Get(base)
   859  	fn, meta := ls.metaCall(lv)
   860  	ls.pushCallFrame(callFrame{
   861  		Fn:         fn,
   862  		Pc:         0,
   863  		Base:       base,
   864  		LocalBase:  base + 1,
   865  		ReturnBase: rbase,
   866  		NArgs:      nargs,
   867  		NRet:       nret,
   868  		Parent:     ls.currentFrame,
   869  		TailCall:   0,
   870  	}, lv, meta)
   871  	if ls.G.MainThread == nil {
   872  		ls.G.MainThread = ls
   873  		ls.G.CurrentThread = ls
   874  		ls.mainLoop(ls, nil)
   875  	} else {
   876  		ls.mainLoop(ls, ls.currentFrame)
   877  	}
   878  	if nret != MultRet {
   879  		ls.reg.SetTop(rbase + nret)
   880  	}
   881  }
   882  
   883  func (ls *LState) getField(obj LValue, key LValue) LValue {
   884  	curobj := obj
   885  	for i := 0; i < MaxTableGetLoop; i++ {
   886  		tb, istable := curobj.(*LTable)
   887  		if istable {
   888  			ret := tb.RawGet(key)
   889  			if ret != LNil {
   890  				return ret
   891  			}
   892  		}
   893  		metaindex := ls.metaOp1(curobj, "__index")
   894  		if metaindex == LNil {
   895  			if !istable {
   896  				ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
   897  			}
   898  			return LNil
   899  		}
   900  		if metaindex.Type() == LTFunction {
   901  			ls.reg.Push(metaindex)
   902  			ls.reg.Push(curobj)
   903  			ls.reg.Push(key)
   904  			ls.Call(2, 1)
   905  			return ls.reg.Pop()
   906  		} else {
   907  			curobj = metaindex
   908  		}
   909  	}
   910  	ls.RaiseError("too many recursions in gettable")
   911  	return nil
   912  }
   913  
   914  func (ls *LState) getFieldString(obj LValue, key string) LValue {
   915  	curobj := obj
   916  	for i := 0; i < MaxTableGetLoop; i++ {
   917  		tb, istable := curobj.(*LTable)
   918  		if istable {
   919  			ret := tb.RawGetString(key)
   920  			if ret != LNil {
   921  				return ret
   922  			}
   923  		}
   924  		metaindex := ls.metaOp1(curobj, "__index")
   925  		if metaindex == LNil {
   926  			if !istable {
   927  				ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
   928  			}
   929  			return LNil
   930  		}
   931  		if metaindex.Type() == LTFunction {
   932  			ls.reg.Push(metaindex)
   933  			ls.reg.Push(curobj)
   934  			ls.reg.Push(LString(key))
   935  			ls.Call(2, 1)
   936  			return ls.reg.Pop()
   937  		} else {
   938  			curobj = metaindex
   939  		}
   940  	}
   941  	ls.RaiseError("too many recursions in gettable")
   942  	return nil
   943  }
   944  
   945  func (ls *LState) setField(obj LValue, key LValue, value LValue) {
   946  	curobj := obj
   947  	for i := 0; i < MaxTableGetLoop; i++ {
   948  		tb, istable := curobj.(*LTable)
   949  		if istable {
   950  			if tb.RawGet(key) != LNil {
   951  				ls.RawSet(tb, key, value)
   952  				return
   953  			}
   954  		}
   955  		metaindex := ls.metaOp1(curobj, "__newindex")
   956  		if metaindex == LNil {
   957  			if !istable {
   958  				ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
   959  			}
   960  			ls.RawSet(tb, key, value)
   961  			return
   962  		}
   963  		if metaindex.Type() == LTFunction {
   964  			ls.reg.Push(metaindex)
   965  			ls.reg.Push(curobj)
   966  			ls.reg.Push(key)
   967  			ls.reg.Push(value)
   968  			ls.Call(3, 0)
   969  			return
   970  		} else {
   971  			curobj = metaindex
   972  		}
   973  	}
   974  	ls.RaiseError("too many recursions in settable")
   975  }
   976  
   977  func (ls *LState) setFieldString(obj LValue, key string, value LValue) {
   978  	curobj := obj
   979  	for i := 0; i < MaxTableGetLoop; i++ {
   980  		tb, istable := curobj.(*LTable)
   981  		if istable {
   982  			if tb.RawGetString(key) != LNil {
   983  				tb.RawSetString(key, value)
   984  				return
   985  			}
   986  		}
   987  		metaindex := ls.metaOp1(curobj, "__newindex")
   988  		if metaindex == LNil {
   989  			if !istable {
   990  				ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
   991  			}
   992  			tb.RawSetString(key, value)
   993  			return
   994  		}
   995  		if metaindex.Type() == LTFunction {
   996  			ls.reg.Push(metaindex)
   997  			ls.reg.Push(curobj)
   998  			ls.reg.Push(LString(key))
   999  			ls.reg.Push(value)
  1000  			ls.Call(3, 0)
  1001  			return
  1002  		} else {
  1003  			curobj = metaindex
  1004  		}
  1005  	}
  1006  	ls.RaiseError("too many recursions in settable")
  1007  }
  1008  
  1009  /* }}} */
  1010  
  1011  /* api methods {{{ */
  1012  
  1013  func NewState(opts ...Options) *LState {
  1014  	var ls *LState
  1015  	if len(opts) == 0 {
  1016  		ls = newLState(Options{
  1017  			CallStackSize: CallStackSize,
  1018  			RegistrySize:  RegistrySize,
  1019  		})
  1020  		ls.OpenLibs()
  1021  	} else {
  1022  		if opts[0].CallStackSize < 1 {
  1023  			opts[0].CallStackSize = CallStackSize
  1024  		}
  1025  		if opts[0].RegistrySize < 128 {
  1026  			opts[0].RegistrySize = RegistrySize
  1027  		}
  1028  		ls = newLState(opts[0])
  1029  		if !opts[0].SkipOpenLibs {
  1030  			ls.OpenLibs()
  1031  		}
  1032  	}
  1033  	return ls
  1034  }
  1035  
  1036  func (ls *LState) Close() {
  1037  	atomic.AddInt32(&ls.stop, 1)
  1038  	for _, file := range ls.G.tempFiles {
  1039  		// ignore errors in these operations
  1040  		file.Close()
  1041  		os.Remove(file.Name())
  1042  	}
  1043  }
  1044  
  1045  /* registry operations {{{ */
  1046  
  1047  func (ls *LState) GetTop() int {
  1048  	return ls.reg.Top() - ls.currentLocalBase()
  1049  }
  1050  
  1051  func (ls *LState) SetTop(idx int) {
  1052  	base := ls.currentLocalBase()
  1053  	newtop := ls.indexToReg(idx) + 1
  1054  	if newtop < base {
  1055  		ls.reg.SetTop(base)
  1056  	} else {
  1057  		ls.reg.SetTop(newtop)
  1058  	}
  1059  }
  1060  
  1061  func (ls *LState) Replace(idx int, value LValue) {
  1062  	base := ls.currentLocalBase()
  1063  	if idx > 0 {
  1064  		reg := base + idx - 1
  1065  		if reg < ls.reg.Top() {
  1066  			ls.reg.Set(reg, value)
  1067  		}
  1068  	} else if idx == 0 {
  1069  	} else if idx > RegistryIndex {
  1070  		if tidx := ls.reg.Top() + idx; tidx >= base {
  1071  			ls.reg.Set(tidx, value)
  1072  		}
  1073  	} else {
  1074  		switch idx {
  1075  		case RegistryIndex:
  1076  			if tb, ok := value.(*LTable); ok {
  1077  				ls.G.Registry = tb
  1078  			} else {
  1079  				ls.RaiseError("registry must be a table(%v)", value.Type().String())
  1080  			}
  1081  		case EnvironIndex:
  1082  			if ls.currentFrame == nil {
  1083  				ls.RaiseError("no calling environment")
  1084  			}
  1085  			if tb, ok := value.(*LTable); ok {
  1086  				ls.currentFrame.Fn.Env = tb
  1087  			} else {
  1088  				ls.RaiseError("environment must be a table(%v)", value.Type().String())
  1089  			}
  1090  		case GlobalsIndex:
  1091  			if tb, ok := value.(*LTable); ok {
  1092  				ls.G.Global = tb
  1093  			} else {
  1094  				ls.RaiseError("_G must be a table(%v)", value.Type().String())
  1095  			}
  1096  		default:
  1097  			fn := ls.currentFrame.Fn
  1098  			index := GlobalsIndex - idx - 1
  1099  			if index < len(fn.Upvalues) {
  1100  				fn.Upvalues[index].SetValue(value)
  1101  			}
  1102  		}
  1103  	}
  1104  }
  1105  
  1106  func (ls *LState) Get(idx int) LValue {
  1107  	base := ls.currentLocalBase()
  1108  	if idx > 0 {
  1109  		reg := base + idx - 1
  1110  		if reg < ls.reg.Top() {
  1111  			return ls.reg.Get(reg)
  1112  		}
  1113  		return LNil
  1114  	} else if idx == 0 {
  1115  		return LNil
  1116  	} else if idx > RegistryIndex {
  1117  		tidx := ls.reg.Top() + idx
  1118  		if tidx < base {
  1119  			return LNil
  1120  		}
  1121  		return ls.reg.Get(tidx)
  1122  	} else {
  1123  		switch idx {
  1124  		case RegistryIndex:
  1125  			return ls.G.Registry
  1126  		case EnvironIndex:
  1127  			if ls.currentFrame == nil {
  1128  				return ls.Env
  1129  			}
  1130  			return ls.currentFrame.Fn.Env
  1131  		case GlobalsIndex:
  1132  			return ls.G.Global
  1133  		default:
  1134  			fn := ls.currentFrame.Fn
  1135  			index := GlobalsIndex - idx - 1
  1136  			if index < len(fn.Upvalues) {
  1137  				return fn.Upvalues[index].Value()
  1138  			}
  1139  			return LNil
  1140  		}
  1141  	}
  1142  }
  1143  
  1144  func (ls *LState) Push(value LValue) {
  1145  	ls.reg.Push(value)
  1146  }
  1147  
  1148  func (ls *LState) Pop(n int) {
  1149  	for i := 0; i < n; i++ {
  1150  		if ls.GetTop() == 0 {
  1151  			ls.RaiseError("register underflow")
  1152  		}
  1153  		ls.reg.Pop()
  1154  	}
  1155  }
  1156  
  1157  func (ls *LState) Insert(value LValue, index int) {
  1158  	reg := ls.indexToReg(index)
  1159  	top := ls.reg.Top()
  1160  	if reg >= top {
  1161  		ls.reg.Set(reg, value)
  1162  		return
  1163  	}
  1164  	if reg <= ls.currentLocalBase() {
  1165  		reg = ls.currentLocalBase()
  1166  	}
  1167  	top--
  1168  	for ; top >= reg; top-- {
  1169  		ls.reg.Set(top+1, ls.reg.Get(top))
  1170  	}
  1171  	ls.reg.Set(reg, value)
  1172  }
  1173  
  1174  func (ls *LState) Remove(index int) {
  1175  	reg := ls.indexToReg(index)
  1176  	top := ls.reg.Top()
  1177  	switch {
  1178  	case reg >= top:
  1179  		return
  1180  	case reg < ls.currentLocalBase():
  1181  		return
  1182  	case reg == top-1:
  1183  		ls.Pop(1)
  1184  		return
  1185  	}
  1186  	for i := reg; i < top-1; i++ {
  1187  		ls.reg.Set(i, ls.reg.Get(i+1))
  1188  	}
  1189  	ls.reg.SetTop(top - 1)
  1190  }
  1191  
  1192  /* }}} */
  1193  
  1194  /* object allocation {{{ */
  1195  
  1196  func (ls *LState) NewTable() *LTable {
  1197  	return newLTable(defaultArrayCap, defaultHashCap)
  1198  }
  1199  
  1200  func (ls *LState) CreateTable(acap, hcap int) *LTable {
  1201  	return newLTable(acap, hcap)
  1202  }
  1203  
  1204  // NewThread returns a new LState that shares with the original state all global objects.
  1205  // If the original state has context.Context, the new state has a new child context of the original state and this function returns its cancel function.
  1206  func (ls *LState) NewThread() (*LState, context.CancelFunc) {
  1207  	thread := newLState(ls.Options)
  1208  	thread.G = ls.G
  1209  	thread.Env = ls.Env
  1210  	var f context.CancelFunc = nil
  1211  	if ls.ctx != nil {
  1212  		thread.mainLoop = mainLoopWithContext
  1213  		thread.ctx, f = context.WithCancel(ls.ctx)
  1214  	}
  1215  	return thread, f
  1216  }
  1217  
  1218  func (ls *LState) NewFunctionFromProto(proto *FunctionProto) *LFunction {
  1219  	return newLFunctionL(proto, ls.Env, int(proto.NumUpvalues))
  1220  }
  1221  
  1222  func (ls *LState) NewUserData() *LUserData {
  1223  	return &LUserData{
  1224  		Env:       ls.currentEnv(),
  1225  		Metatable: LNil,
  1226  	}
  1227  }
  1228  
  1229  func (ls *LState) NewFunction(fn LGFunction) *LFunction {
  1230  	return newLFunctionG(fn, ls.currentEnv(), 0)
  1231  }
  1232  
  1233  func (ls *LState) NewClosure(fn LGFunction, upvalues ...LValue) *LFunction {
  1234  	cl := newLFunctionG(fn, ls.currentEnv(), len(upvalues))
  1235  	for i, lv := range upvalues {
  1236  		cl.Upvalues[i] = &Upvalue{}
  1237  		cl.Upvalues[i].Close()
  1238  		cl.Upvalues[i].SetValue(lv)
  1239  	}
  1240  	return cl
  1241  }
  1242  
  1243  /* }}} */
  1244  
  1245  /* toType {{{ */
  1246  
  1247  func (ls *LState) ToBool(n int) bool {
  1248  	return LVAsBool(ls.Get(n))
  1249  }
  1250  
  1251  func (ls *LState) ToInt(n int) int {
  1252  	if lv, ok := ls.Get(n).(LNumber); ok {
  1253  		return int(lv)
  1254  	}
  1255  	if lv, ok := ls.Get(n).(LString); ok {
  1256  		if num, err := parseNumber(string(lv)); err == nil {
  1257  			return int(num)
  1258  		}
  1259  	}
  1260  	return 0
  1261  }
  1262  
  1263  func (ls *LState) ToInt64(n int) int64 {
  1264  	if lv, ok := ls.Get(n).(LNumber); ok {
  1265  		return int64(lv)
  1266  	}
  1267  	if lv, ok := ls.Get(n).(LString); ok {
  1268  		if num, err := parseNumber(string(lv)); err == nil {
  1269  			return int64(num)
  1270  		}
  1271  	}
  1272  	return 0
  1273  }
  1274  
  1275  func (ls *LState) ToNumber(n int) LNumber {
  1276  	return LVAsNumber(ls.Get(n))
  1277  }
  1278  
  1279  func (ls *LState) ToString(n int) string {
  1280  	return LVAsString(ls.Get(n))
  1281  }
  1282  
  1283  func (ls *LState) ToTable(n int) *LTable {
  1284  	if lv, ok := ls.Get(n).(*LTable); ok {
  1285  		return lv
  1286  	}
  1287  	return nil
  1288  }
  1289  
  1290  func (ls *LState) ToFunction(n int) *LFunction {
  1291  	if lv, ok := ls.Get(n).(*LFunction); ok {
  1292  		return lv
  1293  	}
  1294  	return nil
  1295  }
  1296  
  1297  func (ls *LState) ToUserData(n int) *LUserData {
  1298  	if lv, ok := ls.Get(n).(*LUserData); ok {
  1299  		return lv
  1300  	}
  1301  	return nil
  1302  }
  1303  
  1304  func (ls *LState) ToThread(n int) *LState {
  1305  	if lv, ok := ls.Get(n).(*LState); ok {
  1306  		return lv
  1307  	}
  1308  	return nil
  1309  }
  1310  
  1311  /* }}} */
  1312  
  1313  /* error & debug operations {{{ */
  1314  
  1315  // This function is equivalent to luaL_error( http://www.lua.org/manual/5.1/manual.html#luaL_error ).
  1316  func (ls *LState) RaiseError(format string, args ...interface{}) {
  1317  	ls.raiseError(1, format, args...)
  1318  }
  1319  
  1320  // This function is equivalent to lua_error( http://www.lua.org/manual/5.1/manual.html#lua_error ).
  1321  func (ls *LState) Error(lv LValue, level int) {
  1322  	if str, ok := lv.(LString); ok {
  1323  		ls.raiseError(level, string(str))
  1324  	} else {
  1325  		if !ls.hasErrorFunc {
  1326  			ls.closeAllUpvalues()
  1327  		}
  1328  		ls.Push(lv)
  1329  		ls.Panic(ls)
  1330  	}
  1331  }
  1332  
  1333  func (ls *LState) GetInfo(what string, dbg *Debug, fn LValue) (LValue, error) {
  1334  	if !strings.HasPrefix(what, ">") {
  1335  		fn = dbg.frame.Fn
  1336  	} else {
  1337  		what = what[1:]
  1338  	}
  1339  	f, ok := fn.(*LFunction)
  1340  	if !ok {
  1341  		return LNil, newApiErrorS(ApiErrorRun, "can not get debug info(an object in not a function)")
  1342  	}
  1343  
  1344  	retfn := false
  1345  	for _, c := range what {
  1346  		switch c {
  1347  		case 'f':
  1348  			retfn = true
  1349  		case 'S':
  1350  			if dbg.frame != nil && dbg.frame.Parent == nil {
  1351  				dbg.What = "main"
  1352  			} else if f.IsG {
  1353  				dbg.What = "G"
  1354  			} else if dbg.frame != nil && dbg.frame.TailCall > 0 {
  1355  				dbg.What = "tail"
  1356  			} else {
  1357  				dbg.What = "Lua"
  1358  			}
  1359  			if !f.IsG {
  1360  				dbg.Source = f.Proto.SourceName
  1361  				dbg.LineDefined = f.Proto.LineDefined
  1362  				dbg.LastLineDefined = f.Proto.LastLineDefined
  1363  			}
  1364  		case 'l':
  1365  			if !f.IsG && dbg.frame != nil {
  1366  				if dbg.frame.Pc > 0 {
  1367  					dbg.CurrentLine = f.Proto.DbgSourcePositions[dbg.frame.Pc-1]
  1368  				}
  1369  			} else {
  1370  				dbg.CurrentLine = -1
  1371  			}
  1372  		case 'u':
  1373  			dbg.NUpvalues = len(f.Upvalues)
  1374  		case 'n':
  1375  			if dbg.frame != nil {
  1376  				dbg.Name = ls.rawFrameFuncName(dbg.frame)
  1377  			}
  1378  		default:
  1379  			return LNil, newApiErrorS(ApiErrorRun, "invalid what: "+string(c))
  1380  		}
  1381  	}
  1382  
  1383  	if retfn {
  1384  		return f, nil
  1385  	}
  1386  	return LNil, nil
  1387  
  1388  }
  1389  
  1390  func (ls *LState) GetStack(level int) (*Debug, bool) {
  1391  	frame := ls.currentFrame
  1392  	for ; level > 0 && frame != nil; frame = frame.Parent {
  1393  		level--
  1394  		if !frame.Fn.IsG {
  1395  			level -= frame.TailCall
  1396  		}
  1397  	}
  1398  
  1399  	if level == 0 && frame != nil {
  1400  		return &Debug{frame: frame}, true
  1401  	} else if level < 0 && ls.stack.Sp() > 0 {
  1402  		return &Debug{frame: ls.stack.At(0)}, true
  1403  	}
  1404  	return &Debug{}, false
  1405  }
  1406  
  1407  func (ls *LState) GetLocal(dbg *Debug, no int) (string, LValue) {
  1408  	frame := dbg.frame
  1409  	if name := ls.findLocal(frame, no); len(name) > 0 {
  1410  		return name, ls.reg.Get(frame.LocalBase + no - 1)
  1411  	}
  1412  	return "", LNil
  1413  }
  1414  
  1415  func (ls *LState) SetLocal(dbg *Debug, no int, lv LValue) string {
  1416  	frame := dbg.frame
  1417  	if name := ls.findLocal(frame, no); len(name) > 0 {
  1418  		ls.reg.Set(frame.LocalBase+no-1, lv)
  1419  		return name
  1420  	}
  1421  	return ""
  1422  }
  1423  
  1424  func (ls *LState) GetUpvalue(fn *LFunction, no int) (string, LValue) {
  1425  	if fn.IsG {
  1426  		return "", LNil
  1427  	}
  1428  
  1429  	no--
  1430  	if no >= 0 && no < len(fn.Upvalues) {
  1431  		return fn.Proto.DbgUpvalues[no], fn.Upvalues[no].Value()
  1432  	}
  1433  	return "", LNil
  1434  }
  1435  
  1436  func (ls *LState) SetUpvalue(fn *LFunction, no int, lv LValue) string {
  1437  	if fn.IsG {
  1438  		return ""
  1439  	}
  1440  
  1441  	no--
  1442  	if no >= 0 && no < len(fn.Upvalues) {
  1443  		fn.Upvalues[no].SetValue(lv)
  1444  		return fn.Proto.DbgUpvalues[no]
  1445  	}
  1446  	return ""
  1447  }
  1448  
  1449  /* }}} */
  1450  
  1451  /* env operations {{{ */
  1452  
  1453  func (ls *LState) GetFEnv(obj LValue) LValue {
  1454  	switch lv := obj.(type) {
  1455  	case *LFunction:
  1456  		return lv.Env
  1457  	case *LUserData:
  1458  		return lv.Env
  1459  	case *LState:
  1460  		return lv.Env
  1461  	}
  1462  	return LNil
  1463  }
  1464  
  1465  func (ls *LState) SetFEnv(obj LValue, env LValue) {
  1466  	tb, ok := env.(*LTable)
  1467  	if !ok {
  1468  		ls.RaiseError("cannot use %v as an environment", env.Type().String())
  1469  	}
  1470  
  1471  	switch lv := obj.(type) {
  1472  	case *LFunction:
  1473  		lv.Env = tb
  1474  	case *LUserData:
  1475  		lv.Env = tb
  1476  	case *LState:
  1477  		lv.Env = tb
  1478  	}
  1479  	/* do nothing */
  1480  }
  1481  
  1482  /* }}} */
  1483  
  1484  /* table operations {{{ */
  1485  
  1486  func (ls *LState) RawGet(tb *LTable, key LValue) LValue {
  1487  	return tb.RawGet(key)
  1488  }
  1489  
  1490  func (ls *LState) RawGetInt(tb *LTable, key int) LValue {
  1491  	return tb.RawGetInt(key)
  1492  }
  1493  
  1494  func (ls *LState) GetField(obj LValue, skey string) LValue {
  1495  	return ls.getFieldString(obj, skey)
  1496  }
  1497  
  1498  func (ls *LState) GetTable(obj LValue, key LValue) LValue {
  1499  	return ls.getField(obj, key)
  1500  }
  1501  
  1502  func (ls *LState) RawSet(tb *LTable, key LValue, value LValue) {
  1503  	if n, ok := key.(LNumber); ok && math.IsNaN(float64(n)) {
  1504  		ls.RaiseError("table index is NaN")
  1505  	} else if key == LNil {
  1506  		ls.RaiseError("table index is nil")
  1507  	}
  1508  	tb.RawSet(key, value)
  1509  }
  1510  
  1511  func (ls *LState) RawSetInt(tb *LTable, key int, value LValue) {
  1512  	tb.RawSetInt(key, value)
  1513  }
  1514  
  1515  func (ls *LState) SetField(obj LValue, key string, value LValue) {
  1516  	ls.setFieldString(obj, key, value)
  1517  }
  1518  
  1519  func (ls *LState) SetTable(obj LValue, key LValue, value LValue) {
  1520  	ls.setField(obj, key, value)
  1521  }
  1522  
  1523  func (ls *LState) ForEach(tb *LTable, cb func(LValue, LValue)) {
  1524  	tb.ForEach(cb)
  1525  }
  1526  
  1527  func (ls *LState) GetGlobal(name string) LValue {
  1528  	return ls.GetField(ls.Get(GlobalsIndex), name)
  1529  }
  1530  
  1531  func (ls *LState) SetGlobal(name string, value LValue) {
  1532  	ls.SetField(ls.Get(GlobalsIndex), name, value)
  1533  }
  1534  
  1535  func (ls *LState) Next(tb *LTable, key LValue) (LValue, LValue) {
  1536  	return tb.Next(key)
  1537  }
  1538  
  1539  /* }}} */
  1540  
  1541  /* unary operations {{{ */
  1542  
  1543  func (ls *LState) ObjLen(v1 LValue) int {
  1544  	if v1.Type() == LTString {
  1545  		return len(string(v1.(LString)))
  1546  	}
  1547  	op := ls.metaOp1(v1, "__len")
  1548  	if op.Type() == LTFunction {
  1549  		ls.Push(op)
  1550  		ls.Push(v1)
  1551  		ls.Call(1, 1)
  1552  		ret := ls.reg.Pop()
  1553  		if ret.Type() == LTNumber {
  1554  			return int(ret.(LNumber))
  1555  		}
  1556  	} else if v1.Type() == LTTable {
  1557  		return v1.(*LTable).Len()
  1558  	}
  1559  	return 0
  1560  }
  1561  
  1562  /* }}} */
  1563  
  1564  /* binary operations {{{ */
  1565  
  1566  func (ls *LState) Concat(values ...LValue) string {
  1567  	top := ls.reg.Top()
  1568  	for _, value := range values {
  1569  		ls.reg.Push(value)
  1570  	}
  1571  	ret := stringConcat(ls, len(values), ls.reg.Top()-1)
  1572  	ls.reg.SetTop(top)
  1573  	return LVAsString(ret)
  1574  }
  1575  
  1576  func (ls *LState) LessThan(lhs, rhs LValue) bool {
  1577  	return lessThan(ls, lhs, rhs)
  1578  }
  1579  
  1580  func (ls *LState) Equal(lhs, rhs LValue) bool {
  1581  	return equals(ls, lhs, rhs, false)
  1582  }
  1583  
  1584  func (ls *LState) RawEqual(lhs, rhs LValue) bool {
  1585  	return equals(ls, lhs, rhs, true)
  1586  }
  1587  
  1588  /* }}} */
  1589  
  1590  /* register operations {{{ */
  1591  
  1592  func (ls *LState) Register(name string, fn LGFunction) {
  1593  	ls.SetGlobal(name, ls.NewFunction(fn))
  1594  }
  1595  
  1596  /* }}} */
  1597  
  1598  /* load and function call operations {{{ */
  1599  
  1600  func (ls *LState) Load(reader io.Reader, name string) (*LFunction, error) {
  1601  	chunk, err := parse.Parse(reader, name)
  1602  	if err != nil {
  1603  		return nil, newApiErrorE(ApiErrorSyntax, err)
  1604  	}
  1605  	proto, err := Compile(chunk, name)
  1606  	if err != nil {
  1607  		return nil, newApiErrorE(ApiErrorSyntax, err)
  1608  	}
  1609  	return newLFunctionL(proto, ls.currentEnv(), 0), nil
  1610  }
  1611  
  1612  func (ls *LState) Call(nargs, nret int) {
  1613  	ls.callR(nargs, nret, -1)
  1614  }
  1615  
  1616  func (ls *LState) PCall(nargs, nret int, errfunc *LFunction) (err error) {
  1617  	err = nil
  1618  	sp := ls.stack.Sp()
  1619  	base := ls.reg.Top() - nargs - 1
  1620  	oldpanic := ls.Panic
  1621  	ls.Panic = panicWithoutTraceback
  1622  	if errfunc != nil {
  1623  		ls.hasErrorFunc = true
  1624  	}
  1625  	defer func() {
  1626  		ls.Panic = oldpanic
  1627  		ls.hasErrorFunc = false
  1628  		rcv := recover()
  1629  		if rcv != nil {
  1630  			if _, ok := rcv.(*ApiError); !ok {
  1631  				err = newApiErrorS(ApiErrorPanic, fmt.Sprint(rcv))
  1632  				if ls.Options.IncludeGoStackTrace {
  1633  					buf := make([]byte, 4096)
  1634  					runtime.Stack(buf, false)
  1635  					err.(*ApiError).StackTrace = strings.Trim(string(buf), "\000") + "\n" + ls.stackTrace(0)
  1636  				}
  1637  			} else {
  1638  				err = rcv.(*ApiError)
  1639  			}
  1640  			if errfunc != nil {
  1641  				ls.Push(errfunc)
  1642  				ls.Push(err.(*ApiError).Object)
  1643  				ls.Panic = panicWithoutTraceback
  1644  				defer func() {
  1645  					ls.Panic = oldpanic
  1646  					rcv := recover()
  1647  					if rcv != nil {
  1648  						if _, ok := rcv.(*ApiError); !ok {
  1649  							err = newApiErrorS(ApiErrorPanic, fmt.Sprint(rcv))
  1650  							if ls.Options.IncludeGoStackTrace {
  1651  								buf := make([]byte, 4096)
  1652  								runtime.Stack(buf, false)
  1653  								err.(*ApiError).StackTrace = strings.Trim(string(buf), "\000") + ls.stackTrace(0)
  1654  							}
  1655  						} else {
  1656  							err = rcv.(*ApiError)
  1657  							err.(*ApiError).StackTrace = ls.stackTrace(0)
  1658  						}
  1659  					}
  1660  				}()
  1661  				ls.Call(1, 1)
  1662  				err = newApiError(ApiErrorError, ls.Get(-1))
  1663  			} else if len(err.(*ApiError).StackTrace) == 0 {
  1664  				err.(*ApiError).StackTrace = ls.stackTrace(0)
  1665  			}
  1666  			ls.stack.SetSp(sp)
  1667  			ls.currentFrame = ls.stack.Last()
  1668  			ls.reg.SetTop(base)
  1669  		}
  1670  		ls.stack.SetSp(sp)
  1671  		if sp == 0 {
  1672  			ls.currentFrame = nil
  1673  		}
  1674  	}()
  1675  
  1676  	ls.Call(nargs, nret)
  1677  
  1678  	return
  1679  }
  1680  
  1681  func (ls *LState) GPCall(fn LGFunction, data LValue) error {
  1682  	ls.Push(newLFunctionG(fn, ls.currentEnv(), 0))
  1683  	ls.Push(data)
  1684  	return ls.PCall(1, MultRet, nil)
  1685  }
  1686  
  1687  func (ls *LState) CallByParam(cp P, args ...LValue) error {
  1688  	ls.Push(cp.Fn)
  1689  	for _, arg := range args {
  1690  		ls.Push(arg)
  1691  	}
  1692  
  1693  	if cp.Protect {
  1694  		return ls.PCall(len(args), cp.NRet, cp.Handler)
  1695  	}
  1696  	ls.Call(len(args), cp.NRet)
  1697  	return nil
  1698  }
  1699  
  1700  /* }}} */
  1701  
  1702  /* metatable operations {{{ */
  1703  
  1704  func (ls *LState) GetMetatable(obj LValue) LValue {
  1705  	return ls.metatable(obj, false)
  1706  }
  1707  
  1708  func (ls *LState) SetMetatable(obj LValue, mt LValue) {
  1709  	switch mt.(type) {
  1710  	case *LNilType, *LTable:
  1711  	default:
  1712  		ls.RaiseError("metatable must be a table or nil, but got %v", mt.Type().String())
  1713  	}
  1714  
  1715  	switch v := obj.(type) {
  1716  	case *LTable:
  1717  		v.Metatable = mt
  1718  	case *LUserData:
  1719  		v.Metatable = mt
  1720  	default:
  1721  		ls.G.builtinMts[int(obj.Type())] = mt
  1722  	}
  1723  }
  1724  
  1725  /* }}} */
  1726  
  1727  /* coroutine operations {{{ */
  1728  
  1729  func (ls *LState) Status(th *LState) string {
  1730  	status := "suspended"
  1731  	if th.Dead {
  1732  		status = "dead"
  1733  	} else if ls.G.CurrentThread == th {
  1734  		status = "running"
  1735  	} else if ls.Parent == th {
  1736  		status = "normal"
  1737  	}
  1738  	return status
  1739  }
  1740  
  1741  func (ls *LState) Resume(th *LState, fn *LFunction, args ...LValue) (ResumeState, error, []LValue) {
  1742  	isstarted := th.isStarted()
  1743  	if !isstarted {
  1744  		base := 0
  1745  		th.stack.Push(callFrame{
  1746  			Fn:         fn,
  1747  			Pc:         0,
  1748  			Base:       base,
  1749  			LocalBase:  base + 1,
  1750  			ReturnBase: base,
  1751  			NArgs:      0,
  1752  			NRet:       MultRet,
  1753  			Parent:     nil,
  1754  			TailCall:   0,
  1755  		})
  1756  	}
  1757  
  1758  	if ls.G.CurrentThread == th {
  1759  		return ResumeError, newApiErrorS(ApiErrorRun, "can not resume a running thread"), nil
  1760  	}
  1761  	if th.Dead {
  1762  		return ResumeError, newApiErrorS(ApiErrorRun, "can not resume a dead thread"), nil
  1763  	}
  1764  	th.Parent = ls
  1765  	ls.G.CurrentThread = th
  1766  	if !isstarted {
  1767  		cf := th.stack.Last()
  1768  		th.currentFrame = cf
  1769  		th.SetTop(0)
  1770  		for _, arg := range args {
  1771  			th.Push(arg)
  1772  		}
  1773  		cf.NArgs = len(args)
  1774  		th.initCallFrame(cf)
  1775  		th.Panic = panicWithoutTraceback
  1776  	} else {
  1777  		for _, arg := range args {
  1778  			th.Push(arg)
  1779  		}
  1780  	}
  1781  	top := ls.GetTop()
  1782  	threadRun(th)
  1783  	haserror := LVIsFalse(ls.Get(top + 1))
  1784  	ret := make([]LValue, 0, ls.GetTop())
  1785  	for idx := top + 2; idx <= ls.GetTop(); idx++ {
  1786  		ret = append(ret, ls.Get(idx))
  1787  	}
  1788  	if len(ret) == 0 {
  1789  		ret = append(ret, LNil)
  1790  	}
  1791  	ls.SetTop(top)
  1792  
  1793  	if haserror {
  1794  		return ResumeError, newApiError(ApiErrorRun, ret[0]), nil
  1795  	} else if th.stack.IsEmpty() {
  1796  		return ResumeOK, nil, ret
  1797  	}
  1798  	return ResumeYield, nil, ret
  1799  }
  1800  
  1801  func (ls *LState) Yield(values ...LValue) int {
  1802  	ls.SetTop(0)
  1803  	for _, lv := range values {
  1804  		ls.Push(lv)
  1805  	}
  1806  	return -1
  1807  }
  1808  
  1809  func (ls *LState) XMoveTo(other *LState, n int) {
  1810  	if ls == other {
  1811  		return
  1812  	}
  1813  	top := ls.GetTop()
  1814  	n = intMin(n, top)
  1815  	for i := n; i > 0; i-- {
  1816  		other.Push(ls.Get(top - i + 1))
  1817  	}
  1818  	ls.SetTop(top - n)
  1819  }
  1820  
  1821  /* }}} */
  1822  
  1823  /* GopherLua original APIs {{{ */
  1824  
  1825  // Set maximum memory size. This function can only be called from the main thread.
  1826  func (ls *LState) SetMx(mx int) {
  1827  	if ls.Parent != nil {
  1828  		ls.RaiseError("sub threads are not allowed to set a memory limit")
  1829  	}
  1830  	go func() {
  1831  		limit := uint64(mx * 1024 * 1024) //MB
  1832  		var s runtime.MemStats
  1833  		for ls.stop == 0 {
  1834  			runtime.ReadMemStats(&s)
  1835  			if s.Alloc >= limit {
  1836  				fmt.Println("out of memory")
  1837  				os.Exit(3)
  1838  			}
  1839  			time.Sleep(100 * time.Millisecond)
  1840  		}
  1841  	}()
  1842  }
  1843  
  1844  // SetContext set a context ctx to this LState. The provided ctx must be non-nil.
  1845  func (ls *LState) SetContext(ctx context.Context) {
  1846  	ls.mainLoop = mainLoopWithContext
  1847  	ls.ctx = ctx
  1848  }
  1849  
  1850  // Context returns the LState's context. To change the context, use WithContext.
  1851  func (ls *LState) Context() context.Context {
  1852  	return ls.ctx
  1853  }
  1854  
  1855  // RemoveContext removes the context associated with this LState and returns this context.
  1856  func (ls *LState) RemoveContext() context.Context {
  1857  	oldctx := ls.ctx
  1858  	ls.mainLoop = mainLoop
  1859  	ls.ctx = nil
  1860  	return oldctx
  1861  }
  1862  
  1863  // Converts the Lua value at the given acceptable index to the chan LValue.
  1864  func (ls *LState) ToChannel(n int) chan LValue {
  1865  	if lv, ok := ls.Get(n).(LChannel); ok {
  1866  		return (chan LValue)(lv)
  1867  	}
  1868  	return nil
  1869  }
  1870  
  1871  /* }}} */
  1872  
  1873  /* }}} */
  1874  
  1875  //