github.com/coinstack/gopher-lua@v0.0.0-20180626044619-c9c62d4ee45e/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/coinstack/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  	// Maximum instruction size
   102  	MaxInstSize uint64
   103  }
   104  
   105  /* }}} */
   106  
   107  /* Debug {{{ */
   108  
   109  type Debug struct {
   110  	frame           *callFrame
   111  	Name            string
   112  	What            string
   113  	Source          string
   114  	CurrentLine     int
   115  	NUpvalues       int
   116  	LineDefined     int
   117  	LastLineDefined int
   118  }
   119  
   120  /* }}} */
   121  
   122  /* callFrame {{{ */
   123  
   124  type callFrame struct {
   125  	Idx        int
   126  	Fn         *LFunction
   127  	Parent     *callFrame
   128  	Pc         int
   129  	Base       int
   130  	LocalBase  int
   131  	ReturnBase int
   132  	NArgs      int
   133  	NRet       int
   134  	TailCall   int
   135  }
   136  
   137  type callFrameStack struct {
   138  	array []callFrame
   139  	sp    int
   140  }
   141  
   142  func newCallFrameStack(size int) *callFrameStack {
   143  	return &callFrameStack{
   144  		array: make([]callFrame, size),
   145  		sp:    0,
   146  	}
   147  }
   148  
   149  func (cs *callFrameStack) IsEmpty() bool { return cs.sp == 0 }
   150  
   151  func (cs *callFrameStack) Clear() {
   152  	cs.sp = 0
   153  }
   154  
   155  func (cs *callFrameStack) Push(v callFrame) { // +inline-start
   156  	cs.array[cs.sp] = v
   157  	cs.array[cs.sp].Idx = cs.sp
   158  	cs.sp++
   159  } // +inline-end
   160  
   161  func (cs *callFrameStack) Remove(sp int) {
   162  	psp := sp - 1
   163  	nsp := sp + 1
   164  	var pre *callFrame
   165  	var next *callFrame
   166  	if psp > 0 {
   167  		pre = &cs.array[psp]
   168  	}
   169  	if nsp < cs.sp {
   170  		next = &cs.array[nsp]
   171  	}
   172  	if next != nil {
   173  		next.Parent = pre
   174  	}
   175  	for i := sp; i+1 < cs.sp; i++ {
   176  		cs.array[i] = cs.array[i+1]
   177  		cs.array[i].Idx = i
   178  		cs.sp = i
   179  	}
   180  	cs.sp++
   181  }
   182  
   183  func (cs *callFrameStack) Sp() int {
   184  	return cs.sp
   185  }
   186  
   187  func (cs *callFrameStack) SetSp(sp int) {
   188  	cs.sp = sp
   189  }
   190  
   191  func (cs *callFrameStack) Last() *callFrame {
   192  	if cs.sp == 0 {
   193  		return nil
   194  	}
   195  	return &cs.array[cs.sp-1]
   196  }
   197  
   198  func (cs *callFrameStack) At(sp int) *callFrame {
   199  	return &cs.array[sp]
   200  }
   201  
   202  func (cs *callFrameStack) Pop() *callFrame {
   203  	cs.sp--
   204  	return &cs.array[cs.sp]
   205  }
   206  
   207  /* }}} */
   208  
   209  /* registry {{{ */
   210  
   211  type registry struct {
   212  	array []LValue
   213  	top   int
   214  	alloc *allocator
   215  }
   216  
   217  func newRegistry(size int, alloc *allocator) *registry {
   218  	return &registry{make([]LValue, size), 0, alloc}
   219  }
   220  
   221  func (rg *registry) SetTop(top int) {
   222  	oldtop := rg.top
   223  	rg.top = top
   224  	for i := oldtop; i < rg.top; i++ {
   225  		rg.array[i] = LNil
   226  	}
   227  	for i := rg.top; i < oldtop; i++ {
   228  		rg.array[i] = LNil
   229  	}
   230  }
   231  
   232  func (rg *registry) Top() int {
   233  	return rg.top
   234  }
   235  
   236  func (rg *registry) Push(v LValue) {
   237  	rg.array[rg.top] = v
   238  	rg.top++
   239  }
   240  
   241  func (rg *registry) Pop() LValue {
   242  	v := rg.array[rg.top-1]
   243  	rg.array[rg.top-1] = LNil
   244  	rg.top--
   245  	return v
   246  }
   247  
   248  func (rg *registry) Get(reg int) LValue {
   249  	return rg.array[reg]
   250  }
   251  
   252  func (rg *registry) CopyRange(regv, start, limit, n int) { // +inline-start
   253  	for i := 0; i < n; i++ {
   254  		if tidx := start + i; tidx >= rg.top || limit > -1 && tidx >= limit || tidx < 0 {
   255  			rg.array[regv+i] = LNil
   256  		} else {
   257  			rg.array[regv+i] = rg.array[tidx]
   258  		}
   259  	}
   260  	rg.top = regv + n
   261  } // +inline-end
   262  
   263  func (rg *registry) FillNil(regm, n int) { // +inline-start
   264  	for i := 0; i < n; i++ {
   265  		rg.array[regm+i] = LNil
   266  	}
   267  	rg.top = regm + n
   268  } // +inline-end
   269  
   270  func (rg *registry) Insert(value LValue, reg int) {
   271  	top := rg.Top()
   272  	if reg >= top {
   273  		rg.Set(reg, value)
   274  		return
   275  	}
   276  	top--
   277  	for ; top >= reg; top-- {
   278  		rg.Set(top+1, rg.Get(top))
   279  	}
   280  	rg.Set(reg, value)
   281  }
   282  
   283  func (rg *registry) Set(reg int, val LValue) {
   284  	rg.array[reg] = val
   285  	if reg >= rg.top {
   286  		rg.top = reg + 1
   287  	}
   288  }
   289  
   290  func (rg *registry) SetNumber(reg int, val LNumber) {
   291  	rg.array[reg] = rg.alloc.LNumber2I(val)
   292  	if reg >= rg.top {
   293  		rg.top = reg + 1
   294  	}
   295  } /* }}} */
   296  
   297  /* Global {{{ */
   298  
   299  func newGlobal() *Global {
   300  	return &Global{
   301  		MainThread: nil,
   302  		Registry:   newLTable(0, 32),
   303  		Global:     newLTable(0, 64),
   304  		builtinMts: make(map[int]LValue),
   305  		tempFiles:  make([]*os.File, 0, 10),
   306  	}
   307  }
   308  
   309  /* }}} */
   310  
   311  /* package local methods {{{ */
   312  
   313  func panicWithTraceback(L *LState) {
   314  	err := newApiError(ApiErrorRun, L.Get(-1))
   315  	err.StackTrace = L.stackTrace(0)
   316  	panic(err)
   317  }
   318  
   319  func panicWithoutTraceback(L *LState) {
   320  	err := newApiError(ApiErrorRun, L.Get(-1))
   321  	panic(err)
   322  }
   323  
   324  func newLState(options Options) *LState {
   325  	al := newAllocator(32)
   326  	ls := &LState{
   327  		G:       newGlobal(),
   328  		Parent:  nil,
   329  		Panic:   panicWithTraceback,
   330  		Dead:    false,
   331  		Options: options,
   332  
   333  		stop:         0,
   334  		reg:          newRegistry(options.RegistrySize, al),
   335  		stack:        newCallFrameStack(options.CallStackSize),
   336  		alloc:        al,
   337  		currentFrame: nil,
   338  		wrapped:      false,
   339  		uvcache:      nil,
   340  		hasErrorFunc: false,
   341  		mainLoop:     mainLoop,
   342  		ctx:          nil,
   343  		instCount:    0,
   344  	}
   345  	ls.Env = ls.G.Global
   346  	return ls
   347  }
   348  
   349  func (ls *LState) printReg() {
   350  	println("-------------------------")
   351  	println("thread:", ls)
   352  	println("top:", ls.reg.Top())
   353  	if ls.currentFrame != nil {
   354  		println("function base:", ls.currentFrame.Base)
   355  		println("return base:", ls.currentFrame.ReturnBase)
   356  	} else {
   357  		println("(vm not started)")
   358  	}
   359  	println("local base:", ls.currentLocalBase())
   360  	for i := 0; i < ls.reg.Top(); i++ {
   361  		println(i, ls.reg.Get(i).String())
   362  	}
   363  	println("-------------------------")
   364  }
   365  
   366  func (ls *LState) printCallStack() {
   367  	println("-------------------------")
   368  	for i := 0; i < ls.stack.Sp(); i++ {
   369  		print(i)
   370  		print(" ")
   371  		frame := ls.stack.At(i)
   372  		if frame == nil {
   373  			break
   374  		}
   375  		if frame.Fn.IsG {
   376  			println("IsG:", true, "Frame:", frame, "Fn:", frame.Fn)
   377  		} else {
   378  			println("IsG:", false, "Frame:", frame, "Fn:", frame.Fn, "pc:", frame.Pc)
   379  		}
   380  	}
   381  	println("-------------------------")
   382  }
   383  
   384  func (ls *LState) closeAllUpvalues() { // +inline-start
   385  	for cf := ls.currentFrame; cf != nil; cf = cf.Parent {
   386  		if !cf.Fn.IsG {
   387  			ls.closeUpvalues(cf.LocalBase)
   388  		}
   389  	}
   390  } // +inline-end
   391  
   392  func (ls *LState) raiseError(level int, format string, args ...interface{}) {
   393  	if !ls.hasErrorFunc {
   394  		ls.closeAllUpvalues()
   395  	}
   396  	message := format
   397  	if len(args) > 0 {
   398  		message = fmt.Sprintf(format, args...)
   399  	}
   400  	if level > 0 {
   401  		message = fmt.Sprintf("%v %v", ls.where(level-1, true), message)
   402  	}
   403  	ls.reg.Push(LString(message))
   404  	ls.Panic(ls)
   405  }
   406  
   407  func (ls *LState) findLocal(frame *callFrame, no int) string {
   408  	fn := frame.Fn
   409  	if !fn.IsG {
   410  		if name, ok := fn.LocalName(no, frame.Pc-1); ok {
   411  			return name
   412  		}
   413  	}
   414  	var top int
   415  	if ls.currentFrame == frame {
   416  		top = ls.reg.Top()
   417  	} else if frame.Idx+1 < ls.stack.Sp() {
   418  		top = ls.stack.At(frame.Idx + 1).Base
   419  	} else {
   420  		return ""
   421  	}
   422  	if top-frame.LocalBase >= no {
   423  		return "(*temporary)"
   424  	}
   425  	return ""
   426  }
   427  
   428  func (ls *LState) where(level int, skipg bool) string {
   429  	dbg, ok := ls.GetStack(level)
   430  	if !ok {
   431  		return ""
   432  	}
   433  	cf := dbg.frame
   434  	proto := cf.Fn.Proto
   435  	sourcename := "[G]"
   436  	if proto != nil {
   437  		sourcename = proto.SourceName
   438  	} else if skipg {
   439  		return ls.where(level+1, skipg)
   440  	}
   441  	line := ""
   442  	if proto != nil {
   443  		line = fmt.Sprintf("%v:", proto.DbgSourcePositions[cf.Pc-1])
   444  	}
   445  	return fmt.Sprintf("%v:%v", sourcename, line)
   446  }
   447  
   448  func (ls *LState) stackTrace(level int) string {
   449  	buf := []string{}
   450  	header := "stack traceback:"
   451  	if ls.currentFrame != nil {
   452  		i := 0
   453  		for dbg, ok := ls.GetStack(i); ok; dbg, ok = ls.GetStack(i) {
   454  			cf := dbg.frame
   455  			buf = append(buf, fmt.Sprintf("\t%v in %v", ls.Where(i), ls.formattedFrameFuncName(cf)))
   456  			if !cf.Fn.IsG && cf.TailCall > 0 {
   457  				for tc := cf.TailCall; tc > 0; tc-- {
   458  					buf = append(buf, "\t(tailcall): ?")
   459  					i++
   460  				}
   461  			}
   462  			i++
   463  		}
   464  	}
   465  	buf = append(buf, fmt.Sprintf("\t%v: %v", "[G]", "?"))
   466  	buf = buf[intMax(0, intMin(level, len(buf))):len(buf)]
   467  	if len(buf) > 20 {
   468  		newbuf := make([]string, 0, 20)
   469  		newbuf = append(newbuf, buf[0:7]...)
   470  		newbuf = append(newbuf, "\t...")
   471  		newbuf = append(newbuf, buf[len(buf)-7:len(buf)]...)
   472  		buf = newbuf
   473  	}
   474  	return fmt.Sprintf("%s\n%s", header, strings.Join(buf, "\n"))
   475  }
   476  
   477  func (ls *LState) formattedFrameFuncName(fr *callFrame) string {
   478  	name, ischunk := ls.frameFuncName(fr)
   479  	if ischunk {
   480  		return name
   481  	}
   482  	if name[0] != '(' && name[0] != '<' {
   483  		return fmt.Sprintf("function '%s'", name)
   484  	}
   485  	return fmt.Sprintf("function %s", name)
   486  }
   487  
   488  func (ls *LState) rawFrameFuncName(fr *callFrame) string {
   489  	name, _ := ls.frameFuncName(fr)
   490  	return name
   491  }
   492  
   493  func (ls *LState) frameFuncName(fr *callFrame) (string, bool) {
   494  	frame := fr.Parent
   495  	if frame == nil {
   496  		if ls.Parent == nil {
   497  			return "main chunk", true
   498  		} else {
   499  			return "corountine", true
   500  		}
   501  	}
   502  	if !frame.Fn.IsG {
   503  		pc := frame.Pc - 1
   504  		for _, call := range frame.Fn.Proto.DbgCalls {
   505  			if call.Pc == pc {
   506  				name := call.Name
   507  				if (name == "?" || fr.TailCall > 0) && !fr.Fn.IsG {
   508  					name = fmt.Sprintf("<%v:%v>", fr.Fn.Proto.SourceName, fr.Fn.Proto.LineDefined)
   509  				}
   510  				return name, false
   511  			}
   512  		}
   513  	}
   514  	if !fr.Fn.IsG {
   515  		return fmt.Sprintf("<%v:%v>", fr.Fn.Proto.SourceName, fr.Fn.Proto.LineDefined), false
   516  	}
   517  	return "(anonymous)", false
   518  }
   519  
   520  func (ls *LState) isStarted() bool {
   521  	return ls.currentFrame != nil
   522  }
   523  
   524  func (ls *LState) kill() {
   525  	ls.Dead = true
   526  }
   527  
   528  func (ls *LState) indexToReg(idx int) int {
   529  	base := ls.currentLocalBase()
   530  	if idx > 0 {
   531  		return base + idx - 1
   532  	} else if idx == 0 {
   533  		return -1
   534  	} else {
   535  		tidx := ls.reg.Top() + idx
   536  		if tidx < base {
   537  			return -1
   538  		}
   539  		return tidx
   540  	}
   541  }
   542  
   543  func (ls *LState) currentLocalBase() int {
   544  	base := 0
   545  	if ls.currentFrame != nil {
   546  		base = ls.currentFrame.LocalBase
   547  	}
   548  	return base
   549  }
   550  
   551  func (ls *LState) currentEnv() *LTable {
   552  	return ls.Env
   553  	/*
   554  		if ls.currentFrame == nil {
   555  			return ls.Env
   556  		}
   557  		return ls.currentFrame.Fn.Env
   558  	*/
   559  }
   560  
   561  func (ls *LState) rkValue(idx int) LValue {
   562  	/*
   563  		if OpIsK(idx) {
   564  			return ls.currentFrame.Fn.Proto.Constants[opIndexK(idx)]
   565  		}
   566  		return ls.reg.Get(ls.currentFrame.LocalBase + idx)
   567  	*/
   568  	if (idx & opBitRk) != 0 {
   569  		return ls.currentFrame.Fn.Proto.Constants[idx & ^opBitRk]
   570  	}
   571  	return ls.reg.array[ls.currentFrame.LocalBase+idx]
   572  }
   573  
   574  func (ls *LState) rkString(idx int) string {
   575  	if (idx & opBitRk) != 0 {
   576  		return ls.currentFrame.Fn.Proto.stringConstants[idx & ^opBitRk]
   577  	}
   578  	return string(ls.reg.array[ls.currentFrame.LocalBase+idx].(LString))
   579  }
   580  
   581  func (ls *LState) closeUpvalues(idx int) { // +inline-start
   582  	if ls.uvcache != nil {
   583  		var prev *Upvalue
   584  		for uv := ls.uvcache; uv != nil; uv = uv.next {
   585  			if uv.index >= idx {
   586  				if prev != nil {
   587  					prev.next = nil
   588  				} else {
   589  					ls.uvcache = nil
   590  				}
   591  				uv.Close()
   592  			}
   593  			prev = uv
   594  		}
   595  	}
   596  } // +inline-end
   597  
   598  func (ls *LState) findUpvalue(idx int) *Upvalue {
   599  	var prev *Upvalue
   600  	var next *Upvalue
   601  	if ls.uvcache != nil {
   602  		for uv := ls.uvcache; uv != nil; uv = uv.next {
   603  			if uv.index == idx {
   604  				return uv
   605  			}
   606  			if uv.index > idx {
   607  				next = uv
   608  				break
   609  			}
   610  			prev = uv
   611  		}
   612  	}
   613  	uv := &Upvalue{reg: ls.reg, index: idx, closed: false}
   614  	if prev != nil {
   615  		prev.next = uv
   616  	} else {
   617  		ls.uvcache = uv
   618  	}
   619  	if next != nil {
   620  		uv.next = next
   621  	}
   622  	return uv
   623  }
   624  
   625  func (ls *LState) metatable(lvalue LValue, rawget bool) LValue {
   626  	var metatable LValue = LNil
   627  	switch obj := lvalue.(type) {
   628  	case *LTable:
   629  		metatable = obj.Metatable
   630  	case *LUserData:
   631  		metatable = obj.Metatable
   632  	default:
   633  		if table, ok := ls.G.builtinMts[int(obj.Type())]; ok {
   634  			metatable = table
   635  		}
   636  	}
   637  
   638  	if !rawget && metatable != LNil {
   639  		oldmt := metatable
   640  		if tb, ok := metatable.(*LTable); ok {
   641  			metatable = tb.RawGetString("__metatable")
   642  			if metatable == LNil {
   643  				metatable = oldmt
   644  			}
   645  		}
   646  	}
   647  
   648  	return metatable
   649  }
   650  
   651  func (ls *LState) metaOp1(lvalue LValue, event string) LValue {
   652  	if mt := ls.metatable(lvalue, true); mt != LNil {
   653  		if tb, ok := mt.(*LTable); ok {
   654  			return tb.RawGetString(event)
   655  		}
   656  	}
   657  	return LNil
   658  }
   659  
   660  func (ls *LState) metaOp2(value1, value2 LValue, event string) LValue {
   661  	if mt := ls.metatable(value1, true); mt != LNil {
   662  		if tb, ok := mt.(*LTable); ok {
   663  			if ret := tb.RawGetString(event); ret != LNil {
   664  				return ret
   665  			}
   666  		}
   667  	}
   668  	if mt := ls.metatable(value2, true); mt != LNil {
   669  		if tb, ok := mt.(*LTable); ok {
   670  			return tb.RawGetString(event)
   671  		}
   672  	}
   673  	return LNil
   674  }
   675  
   676  func (ls *LState) metaCall(lvalue LValue) (*LFunction, bool) {
   677  	if fn, ok := lvalue.(*LFunction); ok {
   678  		return fn, false
   679  	}
   680  	if fn, ok := ls.metaOp1(lvalue, "__call").(*LFunction); ok {
   681  		return fn, true
   682  	}
   683  	return nil, false
   684  }
   685  
   686  func (ls *LState) initCallFrame(cf *callFrame) { // +inline-start
   687  	if cf.Fn.IsG {
   688  		ls.reg.SetTop(cf.LocalBase + cf.NArgs)
   689  	} else {
   690  		proto := cf.Fn.Proto
   691  		nargs := cf.NArgs
   692  		np := int(proto.NumParameters)
   693  		for i := nargs; i < np; i++ {
   694  			ls.reg.array[cf.LocalBase+i] = LNil
   695  			nargs = np
   696  		}
   697  
   698  		if (proto.IsVarArg & VarArgIsVarArg) == 0 {
   699  			if nargs < int(proto.NumUsedRegisters) {
   700  				nargs = int(proto.NumUsedRegisters)
   701  			}
   702  			for i := np; i < nargs; i++ {
   703  				ls.reg.array[cf.LocalBase+i] = LNil
   704  			}
   705  			ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters)
   706  		} else {
   707  			/* swap vararg positions:
   708  					   closure
   709  					   namedparam1 <- lbase
   710  					   namedparam2
   711  					   vararg1
   712  					   vararg2
   713  
   714  			           TO
   715  
   716  					   closure
   717  					   nil
   718  					   nil
   719  					   vararg1
   720  					   vararg2
   721  					   namedparam1 <- lbase
   722  					   namedparam2
   723  			*/
   724  			nvarargs := nargs - np
   725  			if nvarargs < 0 {
   726  				nvarargs = 0
   727  			}
   728  
   729  			ls.reg.SetTop(cf.LocalBase + nargs + np)
   730  			for i := 0; i < np; i++ {
   731  				//ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i))
   732  				ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i]
   733  				//ls.reg.Set(cf.LocalBase+i, LNil)
   734  				ls.reg.array[cf.LocalBase+i] = LNil
   735  			}
   736  
   737  			if CompatVarArg {
   738  				ls.reg.SetTop(cf.LocalBase + nargs + np + 1)
   739  				if (proto.IsVarArg & VarArgNeedsArg) != 0 {
   740  					argtb := newLTable(nvarargs, 0)
   741  					for i := 0; i < nvarargs; i++ {
   742  						argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i))
   743  					}
   744  					argtb.RawSetString("n", LNumber(nvarargs))
   745  					//ls.reg.Set(cf.LocalBase+nargs+np, argtb)
   746  					ls.reg.array[cf.LocalBase+nargs+np] = argtb
   747  				} else {
   748  					ls.reg.array[cf.LocalBase+nargs+np] = LNil
   749  				}
   750  			}
   751  			cf.LocalBase += nargs
   752  			maxreg := cf.LocalBase + int(proto.NumUsedRegisters)
   753  			ls.reg.SetTop(maxreg)
   754  		}
   755  	}
   756  } // +inline-end
   757  
   758  func (ls *LState) pushCallFrame(cf callFrame, fn LValue, meta bool) { // +inline-start
   759  	if meta {
   760  		cf.NArgs++
   761  		ls.reg.Insert(fn, cf.LocalBase)
   762  	}
   763  	if cf.Fn == nil {
   764  		ls.RaiseError("attempt to call a non-function object")
   765  	}
   766  	if ls.stack.sp == ls.Options.CallStackSize {
   767  		ls.RaiseError("stack overflow")
   768  	}
   769  	// this section is inlined by go-inline
   770  	// source function is 'func (cs *callFrameStack) Push(v callFrame) ' in '_state.go'
   771  	{
   772  		cs := ls.stack
   773  		v := cf
   774  		cs.array[cs.sp] = v
   775  		cs.array[cs.sp].Idx = cs.sp
   776  		cs.sp++
   777  	}
   778  	newcf := ls.stack.Last()
   779  	// this section is inlined by go-inline
   780  	// source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go'
   781  	{
   782  		cf := newcf
   783  		if cf.Fn.IsG {
   784  			ls.reg.SetTop(cf.LocalBase + cf.NArgs)
   785  		} else {
   786  			proto := cf.Fn.Proto
   787  			nargs := cf.NArgs
   788  			np := int(proto.NumParameters)
   789  			for i := nargs; i < np; i++ {
   790  				ls.reg.array[cf.LocalBase+i] = LNil
   791  				nargs = np
   792  			}
   793  
   794  			if (proto.IsVarArg & VarArgIsVarArg) == 0 {
   795  				if nargs < int(proto.NumUsedRegisters) {
   796  					nargs = int(proto.NumUsedRegisters)
   797  				}
   798  				for i := np; i < nargs; i++ {
   799  					ls.reg.array[cf.LocalBase+i] = LNil
   800  				}
   801  				ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters)
   802  			} else {
   803  				/* swap vararg positions:
   804  						   closure
   805  						   namedparam1 <- lbase
   806  						   namedparam2
   807  						   vararg1
   808  						   vararg2
   809  
   810  				           TO
   811  
   812  						   closure
   813  						   nil
   814  						   nil
   815  						   vararg1
   816  						   vararg2
   817  						   namedparam1 <- lbase
   818  						   namedparam2
   819  				*/
   820  				nvarargs := nargs - np
   821  				if nvarargs < 0 {
   822  					nvarargs = 0
   823  				}
   824  
   825  				ls.reg.SetTop(cf.LocalBase + nargs + np)
   826  				for i := 0; i < np; i++ {
   827  					//ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i))
   828  					ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i]
   829  					//ls.reg.Set(cf.LocalBase+i, LNil)
   830  					ls.reg.array[cf.LocalBase+i] = LNil
   831  				}
   832  
   833  				if CompatVarArg {
   834  					ls.reg.SetTop(cf.LocalBase + nargs + np + 1)
   835  					if (proto.IsVarArg & VarArgNeedsArg) != 0 {
   836  						argtb := newLTable(nvarargs, 0)
   837  						for i := 0; i < nvarargs; i++ {
   838  							argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i))
   839  						}
   840  						argtb.RawSetString("n", LNumber(nvarargs))
   841  						//ls.reg.Set(cf.LocalBase+nargs+np, argtb)
   842  						ls.reg.array[cf.LocalBase+nargs+np] = argtb
   843  					} else {
   844  						ls.reg.array[cf.LocalBase+nargs+np] = LNil
   845  					}
   846  				}
   847  				cf.LocalBase += nargs
   848  				maxreg := cf.LocalBase + int(proto.NumUsedRegisters)
   849  				ls.reg.SetTop(maxreg)
   850  			}
   851  		}
   852  	}
   853  	ls.currentFrame = newcf
   854  } // +inline-end
   855  
   856  func (ls *LState) callR(nargs, nret, rbase int) {
   857  	base := ls.reg.Top() - nargs - 1
   858  	if rbase < 0 {
   859  		rbase = base
   860  	}
   861  	lv := ls.reg.Get(base)
   862  	fn, meta := ls.metaCall(lv)
   863  	ls.pushCallFrame(callFrame{
   864  		Fn:         fn,
   865  		Pc:         0,
   866  		Base:       base,
   867  		LocalBase:  base + 1,
   868  		ReturnBase: rbase,
   869  		NArgs:      nargs,
   870  		NRet:       nret,
   871  		Parent:     ls.currentFrame,
   872  		TailCall:   0,
   873  	}, lv, meta)
   874  	if ls.G.MainThread == nil {
   875  		ls.G.MainThread = ls
   876  		ls.G.CurrentThread = ls
   877  		ls.mainLoop(ls, nil)
   878  	} else {
   879  		ls.mainLoop(ls, ls.currentFrame)
   880  	}
   881  	if nret != MultRet {
   882  		ls.reg.SetTop(rbase + nret)
   883  	}
   884  }
   885  
   886  func (ls *LState) getField(obj LValue, key LValue) LValue {
   887  	curobj := obj
   888  	for i := 0; i < MaxTableGetLoop; i++ {
   889  		tb, istable := curobj.(*LTable)
   890  		if istable {
   891  			ret := tb.RawGet(key)
   892  			if ret != LNil {
   893  				return ret
   894  			}
   895  		}
   896  		metaindex := ls.metaOp1(curobj, "__index")
   897  		if metaindex == LNil {
   898  			if !istable {
   899  				ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
   900  			}
   901  			return LNil
   902  		}
   903  		if metaindex.Type() == LTFunction {
   904  			ls.reg.Push(metaindex)
   905  			ls.reg.Push(curobj)
   906  			ls.reg.Push(key)
   907  			ls.Call(2, 1)
   908  			return ls.reg.Pop()
   909  		} else {
   910  			curobj = metaindex
   911  		}
   912  	}
   913  	ls.RaiseError("too many recursions in gettable")
   914  	return nil
   915  }
   916  
   917  func (ls *LState) getFieldString(obj LValue, key string) LValue {
   918  	curobj := obj
   919  	for i := 0; i < MaxTableGetLoop; i++ {
   920  		tb, istable := curobj.(*LTable)
   921  		if istable {
   922  			ret := tb.RawGetString(key)
   923  			if ret != LNil {
   924  				return ret
   925  			}
   926  		}
   927  		metaindex := ls.metaOp1(curobj, "__index")
   928  		if metaindex == LNil {
   929  			if !istable {
   930  				ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
   931  			}
   932  			return LNil
   933  		}
   934  		if metaindex.Type() == LTFunction {
   935  			ls.reg.Push(metaindex)
   936  			ls.reg.Push(curobj)
   937  			ls.reg.Push(LString(key))
   938  			ls.Call(2, 1)
   939  			return ls.reg.Pop()
   940  		} else {
   941  			curobj = metaindex
   942  		}
   943  	}
   944  	ls.RaiseError("too many recursions in gettable")
   945  	return nil
   946  }
   947  
   948  func (ls *LState) setField(obj LValue, key LValue, value LValue) {
   949  	curobj := obj
   950  	for i := 0; i < MaxTableGetLoop; i++ {
   951  		tb, istable := curobj.(*LTable)
   952  		if istable {
   953  			if tb.RawGet(key) != LNil {
   954  				ls.RawSet(tb, key, value)
   955  				return
   956  			}
   957  		}
   958  		metaindex := ls.metaOp1(curobj, "__newindex")
   959  		if metaindex == LNil {
   960  			if !istable {
   961  				ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
   962  			}
   963  			ls.RawSet(tb, key, value)
   964  			return
   965  		}
   966  		if metaindex.Type() == LTFunction {
   967  			ls.reg.Push(metaindex)
   968  			ls.reg.Push(curobj)
   969  			ls.reg.Push(key)
   970  			ls.reg.Push(value)
   971  			ls.Call(3, 0)
   972  			return
   973  		} else {
   974  			curobj = metaindex
   975  		}
   976  	}
   977  	ls.RaiseError("too many recursions in settable")
   978  }
   979  
   980  func (ls *LState) setFieldString(obj LValue, key string, value LValue) {
   981  	curobj := obj
   982  	for i := 0; i < MaxTableGetLoop; i++ {
   983  		tb, istable := curobj.(*LTable)
   984  		if istable {
   985  			if tb.RawGetString(key) != LNil {
   986  				tb.RawSetString(key, value)
   987  				return
   988  			}
   989  		}
   990  		metaindex := ls.metaOp1(curobj, "__newindex")
   991  		if metaindex == LNil {
   992  			if !istable {
   993  				ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
   994  			}
   995  			tb.RawSetString(key, value)
   996  			return
   997  		}
   998  		if metaindex.Type() == LTFunction {
   999  			ls.reg.Push(metaindex)
  1000  			ls.reg.Push(curobj)
  1001  			ls.reg.Push(LString(key))
  1002  			ls.reg.Push(value)
  1003  			ls.Call(3, 0)
  1004  			return
  1005  		} else {
  1006  			curobj = metaindex
  1007  		}
  1008  	}
  1009  	ls.RaiseError("too many recursions in settable")
  1010  }
  1011  
  1012  /* }}} */
  1013  
  1014  /* api methods {{{ */
  1015  
  1016  func NewState(opts ...Options) *LState {
  1017  	var ls *LState
  1018  	if len(opts) == 0 {
  1019  		ls = newLState(Options{
  1020  			CallStackSize: CallStackSize,
  1021  			RegistrySize:  RegistrySize,
  1022  		})
  1023  		ls.OpenLibs()
  1024  	} else {
  1025  		if opts[0].CallStackSize < 1 {
  1026  			opts[0].CallStackSize = CallStackSize
  1027  		}
  1028  		if opts[0].RegistrySize < 128 {
  1029  			opts[0].RegistrySize = RegistrySize
  1030  		}
  1031  		ls = newLState(opts[0])
  1032  		if !opts[0].SkipOpenLibs {
  1033  			ls.OpenLibs()
  1034  		}
  1035  	}
  1036  	return ls
  1037  }
  1038  
  1039  func (ls *LState) Close() {
  1040  	atomic.AddInt32(&ls.stop, 1)
  1041  	for _, file := range ls.G.tempFiles {
  1042  		// ignore errors in these operations
  1043  		file.Close()
  1044  		os.Remove(file.Name())
  1045  	}
  1046  }
  1047  
  1048  /* registry operations {{{ */
  1049  
  1050  func (ls *LState) GetTop() int {
  1051  	return ls.reg.Top() - ls.currentLocalBase()
  1052  }
  1053  
  1054  func (ls *LState) SetTop(idx int) {
  1055  	base := ls.currentLocalBase()
  1056  	newtop := ls.indexToReg(idx) + 1
  1057  	if newtop < base {
  1058  		ls.reg.SetTop(base)
  1059  	} else {
  1060  		ls.reg.SetTop(newtop)
  1061  	}
  1062  }
  1063  
  1064  func (ls *LState) Replace(idx int, value LValue) {
  1065  	base := ls.currentLocalBase()
  1066  	if idx > 0 {
  1067  		reg := base + idx - 1
  1068  		if reg < ls.reg.Top() {
  1069  			ls.reg.Set(reg, value)
  1070  		}
  1071  	} else if idx == 0 {
  1072  	} else if idx > RegistryIndex {
  1073  		if tidx := ls.reg.Top() + idx; tidx >= base {
  1074  			ls.reg.Set(tidx, value)
  1075  		}
  1076  	} else {
  1077  		switch idx {
  1078  		case RegistryIndex:
  1079  			if tb, ok := value.(*LTable); ok {
  1080  				ls.G.Registry = tb
  1081  			} else {
  1082  				ls.RaiseError("registry must be a table(%v)", value.Type().String())
  1083  			}
  1084  		case EnvironIndex:
  1085  			if ls.currentFrame == nil {
  1086  				ls.RaiseError("no calling environment")
  1087  			}
  1088  			if tb, ok := value.(*LTable); ok {
  1089  				ls.currentFrame.Fn.Env = tb
  1090  			} else {
  1091  				ls.RaiseError("environment must be a table(%v)", value.Type().String())
  1092  			}
  1093  		case GlobalsIndex:
  1094  			if tb, ok := value.(*LTable); ok {
  1095  				ls.G.Global = tb
  1096  			} else {
  1097  				ls.RaiseError("_G must be a table(%v)", value.Type().String())
  1098  			}
  1099  		default:
  1100  			fn := ls.currentFrame.Fn
  1101  			index := GlobalsIndex - idx - 1
  1102  			if index < len(fn.Upvalues) {
  1103  				fn.Upvalues[index].SetValue(value)
  1104  			}
  1105  		}
  1106  	}
  1107  }
  1108  
  1109  func (ls *LState) Get(idx int) LValue {
  1110  	base := ls.currentLocalBase()
  1111  	if idx > 0 {
  1112  		reg := base + idx - 1
  1113  		if reg < ls.reg.Top() {
  1114  			return ls.reg.Get(reg)
  1115  		}
  1116  		return LNil
  1117  	} else if idx == 0 {
  1118  		return LNil
  1119  	} else if idx > RegistryIndex {
  1120  		tidx := ls.reg.Top() + idx
  1121  		if tidx < base {
  1122  			return LNil
  1123  		}
  1124  		return ls.reg.Get(tidx)
  1125  	} else {
  1126  		switch idx {
  1127  		case RegistryIndex:
  1128  			return ls.G.Registry
  1129  		case EnvironIndex:
  1130  			if ls.currentFrame == nil {
  1131  				return ls.Env
  1132  			}
  1133  			return ls.currentFrame.Fn.Env
  1134  		case GlobalsIndex:
  1135  			return ls.G.Global
  1136  		default:
  1137  			fn := ls.currentFrame.Fn
  1138  			index := GlobalsIndex - idx - 1
  1139  			if index < len(fn.Upvalues) {
  1140  				return fn.Upvalues[index].Value()
  1141  			}
  1142  			return LNil
  1143  		}
  1144  	}
  1145  	return LNil
  1146  }
  1147  
  1148  func (ls *LState) Push(value LValue) {
  1149  	ls.reg.Push(value)
  1150  }
  1151  
  1152  func (ls *LState) Pop(n int) {
  1153  	for i := 0; i < n; i++ {
  1154  		if ls.GetTop() == 0 {
  1155  			ls.RaiseError("register underflow")
  1156  		}
  1157  		ls.reg.Pop()
  1158  	}
  1159  }
  1160  
  1161  func (ls *LState) Insert(value LValue, index int) {
  1162  	reg := ls.indexToReg(index)
  1163  	top := ls.reg.Top()
  1164  	if reg >= top {
  1165  		ls.reg.Set(reg, value)
  1166  		return
  1167  	}
  1168  	if reg <= ls.currentLocalBase() {
  1169  		reg = ls.currentLocalBase()
  1170  	}
  1171  	top--
  1172  	for ; top >= reg; top-- {
  1173  		ls.reg.Set(top+1, ls.reg.Get(top))
  1174  	}
  1175  	ls.reg.Set(reg, value)
  1176  }
  1177  
  1178  func (ls *LState) Remove(index int) {
  1179  	reg := ls.indexToReg(index)
  1180  	top := ls.reg.Top()
  1181  	switch {
  1182  	case reg >= top:
  1183  		return
  1184  	case reg < ls.currentLocalBase():
  1185  		return
  1186  	case reg == top-1:
  1187  		ls.Pop(1)
  1188  		return
  1189  	}
  1190  	for i := reg; i < top-1; i++ {
  1191  		ls.reg.Set(i, ls.reg.Get(i+1))
  1192  	}
  1193  	ls.reg.SetTop(top - 1)
  1194  }
  1195  
  1196  /* }}} */
  1197  
  1198  /* object allocation {{{ */
  1199  
  1200  func (ls *LState) NewTable() *LTable {
  1201  	return newLTable(defaultArrayCap, defaultHashCap)
  1202  }
  1203  
  1204  func (ls *LState) CreateTable(acap, hcap int) *LTable {
  1205  	return newLTable(acap, hcap)
  1206  }
  1207  
  1208  // NewThread returns a new LState that shares with the original state all global objects.
  1209  // 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.
  1210  func (ls *LState) NewThread() (*LState, context.CancelFunc) {
  1211  	thread := newLState(ls.Options)
  1212  	thread.G = ls.G
  1213  	thread.Env = ls.Env
  1214  	var f context.CancelFunc = nil
  1215  	if ls.ctx != nil {
  1216  		thread.mainLoop = mainLoopWithContext
  1217  		thread.ctx, f = context.WithCancel(ls.ctx)
  1218  	}
  1219  	return thread, f
  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  /* utility operations {{{ */
  1874  
  1875  func (ls *LState) AddInstCount(n uint64) {
  1876  	if ls.Options.MaxInstSize > 0 {
  1877  		ls.instCount += n
  1878  	}
  1879  }
  1880  
  1881  /* }}} */
  1882  
  1883  /* }}} */
  1884  
  1885  //