github.com/shawnclovie/gopher-lua@v0.0.0-20200520092726-90b44ec0e2f2/state.go (about)

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