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