github.com/jslyzt/glua@v0.0.0-20210819023911-4030c8e0234a/_state.go (about)

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