github.com/enotodden/gopher-lua@v1.1.2/vm.go (about)

     1  package lua
     2  
     3  ////////////////////////////////////////////////////////
     4  // This file was generated by go-inline. DO NOT EDIT. //
     5  ////////////////////////////////////////////////////////
     6  
     7  import (
     8  	"fmt"
     9  	"math"
    10  	"strings"
    11  )
    12  
    13  func mainLoop(L *LState, baseframe *callFrame) {
    14  	var inst uint32
    15  	var cf *callFrame
    16  
    17  	if L.stack.IsEmpty() {
    18  		return
    19  	}
    20  
    21  	L.currentFrame = L.stack.Last()
    22  	if L.currentFrame.Fn.IsG {
    23  		callGFunction(L, false)
    24  		return
    25  	}
    26  
    27  	for {
    28  		cf = L.currentFrame
    29  		inst = cf.Fn.Proto.Code[cf.Pc]
    30  		cf.Pc++
    31  		if jumpTable[int(inst>>26)](L, inst, baseframe) == 1 {
    32  			return
    33  		}
    34  	}
    35  }
    36  
    37  func mainLoopWithContext(L *LState, baseframe *callFrame) {
    38  	var inst uint32
    39  	var cf *callFrame
    40  
    41  	if L.stack.IsEmpty() {
    42  		return
    43  	}
    44  
    45  	L.currentFrame = L.stack.Last()
    46  	if L.currentFrame.Fn.IsG {
    47  		callGFunction(L, false)
    48  		return
    49  	}
    50  
    51  	for {
    52  		cf = L.currentFrame
    53  		inst = cf.Fn.Proto.Code[cf.Pc]
    54  		cf.Pc++
    55  		select {
    56  		case <-L.ctx.Done():
    57  			L.RaiseError(L.ctx.Err().Error())
    58  			return
    59  		default:
    60  			if jumpTable[int(inst>>26)](L, inst, baseframe) == 1 {
    61  				return
    62  			}
    63  		}
    64  	}
    65  }
    66  
    67  // regv is the first target register to copy the return values to.
    68  // It can be reg.top, indicating that the copied values are going into new registers, or it can be below reg.top
    69  // Indicating that the values should be within the existing registers.
    70  // b is the available number of return values + 1.
    71  // n is the desired number of return values.
    72  // If n more than the available return values then the extra values are set to nil.
    73  // When this function returns the top of the registry will be set to regv+n.
    74  func copyReturnValues(L *LState, regv, start, n, b int) { // +inline-start
    75  	if b == 1 {
    76  		// this section is inlined by go-inline
    77  		// source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go'
    78  		{
    79  			rg := L.reg
    80  			regm := regv
    81  			newSize := regm + n
    82  			// this section is inlined by go-inline
    83  			// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
    84  			{
    85  				requiredSize := newSize
    86  				if requiredSize > cap(rg.array) {
    87  					rg.resize(requiredSize)
    88  				}
    89  			}
    90  			for i := 0; i < n; i++ {
    91  				rg.array[regm+i] = LNil
    92  			}
    93  			// values beyond top don't need to be valid LValues, so setting them to nil is fine
    94  			// setting them to nil rather than LNil lets us invoke the golang memclr opto
    95  			oldtop := rg.top
    96  			rg.top = regm + n
    97  			if rg.top < oldtop {
    98  				nilRange := rg.array[rg.top:oldtop]
    99  				for i := range nilRange {
   100  					nilRange[i] = nil
   101  				}
   102  			}
   103  		}
   104  	} else {
   105  		// this section is inlined by go-inline
   106  		// source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go'
   107  		{
   108  			rg := L.reg
   109  			limit := -1
   110  			newSize := regv + n
   111  			// this section is inlined by go-inline
   112  			// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   113  			{
   114  				requiredSize := newSize
   115  				if requiredSize > cap(rg.array) {
   116  					rg.resize(requiredSize)
   117  				}
   118  			}
   119  			if limit == -1 || limit > rg.top {
   120  				limit = rg.top
   121  			}
   122  			for i := 0; i < n; i++ {
   123  				srcIdx := start + i
   124  				if srcIdx >= limit || srcIdx < 0 {
   125  					rg.array[regv+i] = LNil
   126  				} else {
   127  					rg.array[regv+i] = rg.array[srcIdx]
   128  				}
   129  			}
   130  
   131  			// values beyond top don't need to be valid LValues, so setting them to nil is fine
   132  			// setting them to nil rather than LNil lets us invoke the golang memclr opto
   133  			oldtop := rg.top
   134  			rg.top = regv + n
   135  			if rg.top < oldtop {
   136  				nilRange := rg.array[rg.top:oldtop]
   137  				for i := range nilRange {
   138  					nilRange[i] = nil
   139  				}
   140  			}
   141  		}
   142  		if b > 1 && n > (b-1) {
   143  			// this section is inlined by go-inline
   144  			// source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go'
   145  			{
   146  				rg := L.reg
   147  				regm := regv + b - 1
   148  				n := n - (b - 1)
   149  				newSize := regm + n
   150  				// this section is inlined by go-inline
   151  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   152  				{
   153  					requiredSize := newSize
   154  					if requiredSize > cap(rg.array) {
   155  						rg.resize(requiredSize)
   156  					}
   157  				}
   158  				for i := 0; i < n; i++ {
   159  					rg.array[regm+i] = LNil
   160  				}
   161  				// values beyond top don't need to be valid LValues, so setting them to nil is fine
   162  				// setting them to nil rather than LNil lets us invoke the golang memclr opto
   163  				oldtop := rg.top
   164  				rg.top = regm + n
   165  				if rg.top < oldtop {
   166  					nilRange := rg.array[rg.top:oldtop]
   167  					for i := range nilRange {
   168  						nilRange[i] = nil
   169  					}
   170  				}
   171  			}
   172  		}
   173  	}
   174  } // +inline-end
   175  
   176  func switchToParentThread(L *LState, nargs int, haserror bool, kill bool) {
   177  	parent := L.Parent
   178  	if parent == nil {
   179  		L.RaiseError("can not yield from outside of a coroutine")
   180  	}
   181  	L.G.CurrentThread = parent
   182  	L.Parent = nil
   183  	if !L.wrapped {
   184  		if haserror {
   185  			parent.Push(LFalse)
   186  		} else {
   187  			parent.Push(LTrue)
   188  		}
   189  	}
   190  	L.XMoveTo(parent, nargs)
   191  	L.stack.Pop()
   192  	offset := L.currentFrame.LocalBase - L.currentFrame.ReturnBase
   193  	L.currentFrame = L.stack.Last()
   194  	L.reg.SetTop(L.reg.Top() - offset) // remove 'yield' function(including tailcalled functions)
   195  	if kill {
   196  		L.kill()
   197  	}
   198  }
   199  
   200  func callGFunction(L *LState, tailcall bool) bool {
   201  	frame := L.currentFrame
   202  	gfnret := frame.Fn.GFunction(L)
   203  	if tailcall {
   204  		L.currentFrame = L.RemoveCallerFrame()
   205  	}
   206  
   207  	if gfnret < 0 {
   208  		switchToParentThread(L, L.GetTop(), false, false)
   209  		return true
   210  	}
   211  
   212  	wantret := frame.NRet
   213  	if wantret == MultRet {
   214  		wantret = gfnret
   215  	}
   216  
   217  	if tailcall && L.Parent != nil && L.stack.Sp() == 1 {
   218  		switchToParentThread(L, wantret, false, true)
   219  		return true
   220  	}
   221  
   222  	// this section is inlined by go-inline
   223  	// source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go'
   224  	{
   225  		rg := L.reg
   226  		regv := frame.ReturnBase
   227  		start := L.reg.Top() - gfnret
   228  		limit := -1
   229  		n := wantret
   230  		newSize := regv + n
   231  		// this section is inlined by go-inline
   232  		// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   233  		{
   234  			requiredSize := newSize
   235  			if requiredSize > cap(rg.array) {
   236  				rg.resize(requiredSize)
   237  			}
   238  		}
   239  		if limit == -1 || limit > rg.top {
   240  			limit = rg.top
   241  		}
   242  		for i := 0; i < n; i++ {
   243  			srcIdx := start + i
   244  			if srcIdx >= limit || srcIdx < 0 {
   245  				rg.array[regv+i] = LNil
   246  			} else {
   247  				rg.array[regv+i] = rg.array[srcIdx]
   248  			}
   249  		}
   250  
   251  		// values beyond top don't need to be valid LValues, so setting them to nil is fine
   252  		// setting them to nil rather than LNil lets us invoke the golang memclr opto
   253  		oldtop := rg.top
   254  		rg.top = regv + n
   255  		if rg.top < oldtop {
   256  			nilRange := rg.array[rg.top:oldtop]
   257  			for i := range nilRange {
   258  				nilRange[i] = nil
   259  			}
   260  		}
   261  	}
   262  	L.stack.Pop()
   263  	L.currentFrame = L.stack.Last()
   264  	return false
   265  }
   266  
   267  func threadRun(L *LState) {
   268  	if L.stack.IsEmpty() {
   269  		return
   270  	}
   271  
   272  	defer func() {
   273  		if rcv := recover(); rcv != nil {
   274  			var lv LValue
   275  			if v, ok := rcv.(*ApiError); ok {
   276  				lv = v.Object
   277  			} else {
   278  				lv = LString(fmt.Sprint(rcv))
   279  			}
   280  			if parent := L.Parent; parent != nil {
   281  				if L.wrapped {
   282  					L.Push(lv)
   283  					parent.Panic(L)
   284  				} else {
   285  					L.SetTop(0)
   286  					L.Push(lv)
   287  					switchToParentThread(L, 1, true, true)
   288  				}
   289  			} else {
   290  				panic(rcv)
   291  			}
   292  		}
   293  	}()
   294  	L.mainLoop(L, nil)
   295  }
   296  
   297  type instFunc func(*LState, uint32, *callFrame) int
   298  
   299  var jumpTable [opCodeMax + 1]instFunc
   300  
   301  func init() {
   302  	jumpTable = [opCodeMax + 1]instFunc{
   303  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_MOVE
   304  			reg := L.reg
   305  			cf := L.currentFrame
   306  			lbase := cf.LocalBase
   307  			A := int(inst>>18) & 0xff // GETA
   308  			RA := lbase + A
   309  			B := int(inst & 0x1ff) // GETB
   310  			v := reg.Get(lbase + B)
   311  			// this section is inlined by go-inline
   312  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   313  			{
   314  				rg := reg
   315  				regi := RA
   316  				vali := v
   317  				newSize := regi + 1
   318  				// this section is inlined by go-inline
   319  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   320  				{
   321  					requiredSize := newSize
   322  					if requiredSize > cap(rg.array) {
   323  						rg.resize(requiredSize)
   324  					}
   325  				}
   326  				rg.array[regi] = vali
   327  				if regi >= rg.top {
   328  					rg.top = regi + 1
   329  				}
   330  			}
   331  			return 0
   332  		},
   333  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_MOVEN
   334  			reg := L.reg
   335  			cf := L.currentFrame
   336  			lbase := cf.LocalBase
   337  			A := int(inst>>18) & 0xff // GETA
   338  			B := int(inst & 0x1ff)    // GETB
   339  			C := int(inst>>9) & 0x1ff // GETC
   340  			v := reg.Get(lbase + B)
   341  			// this section is inlined by go-inline
   342  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   343  			{
   344  				rg := reg
   345  				regi := lbase + A
   346  				vali := v
   347  				newSize := regi + 1
   348  				// this section is inlined by go-inline
   349  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   350  				{
   351  					requiredSize := newSize
   352  					if requiredSize > cap(rg.array) {
   353  						rg.resize(requiredSize)
   354  					}
   355  				}
   356  				rg.array[regi] = vali
   357  				if regi >= rg.top {
   358  					rg.top = regi + 1
   359  				}
   360  			}
   361  			code := cf.Fn.Proto.Code
   362  			pc := cf.Pc
   363  			for i := 0; i < C; i++ {
   364  				inst = code[pc]
   365  				pc++
   366  				A = int(inst>>18) & 0xff // GETA
   367  				B = int(inst & 0x1ff)    // GETB
   368  				v := reg.Get(lbase + B)
   369  				// this section is inlined by go-inline
   370  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   371  				{
   372  					rg := reg
   373  					regi := lbase + A
   374  					vali := v
   375  					newSize := regi + 1
   376  					// this section is inlined by go-inline
   377  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   378  					{
   379  						requiredSize := newSize
   380  						if requiredSize > cap(rg.array) {
   381  							rg.resize(requiredSize)
   382  						}
   383  					}
   384  					rg.array[regi] = vali
   385  					if regi >= rg.top {
   386  						rg.top = regi + 1
   387  					}
   388  				}
   389  			}
   390  			cf.Pc = pc
   391  			return 0
   392  		},
   393  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_LOADK
   394  			reg := L.reg
   395  			cf := L.currentFrame
   396  			lbase := cf.LocalBase
   397  			A := int(inst>>18) & 0xff // GETA
   398  			RA := lbase + A
   399  			Bx := int(inst & 0x3ffff) // GETBX
   400  			v := cf.Fn.Proto.Constants[Bx]
   401  			// this section is inlined by go-inline
   402  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   403  			{
   404  				rg := reg
   405  				regi := RA
   406  				vali := v
   407  				newSize := regi + 1
   408  				// this section is inlined by go-inline
   409  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   410  				{
   411  					requiredSize := newSize
   412  					if requiredSize > cap(rg.array) {
   413  						rg.resize(requiredSize)
   414  					}
   415  				}
   416  				rg.array[regi] = vali
   417  				if regi >= rg.top {
   418  					rg.top = regi + 1
   419  				}
   420  			}
   421  			return 0
   422  		},
   423  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_LOADBOOL
   424  			reg := L.reg
   425  			cf := L.currentFrame
   426  			lbase := cf.LocalBase
   427  			A := int(inst>>18) & 0xff // GETA
   428  			RA := lbase + A
   429  			B := int(inst & 0x1ff)    // GETB
   430  			C := int(inst>>9) & 0x1ff // GETC
   431  			if B != 0 {
   432  				// this section is inlined by go-inline
   433  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   434  				{
   435  					rg := reg
   436  					regi := RA
   437  					vali := LTrue
   438  					newSize := regi + 1
   439  					// this section is inlined by go-inline
   440  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   441  					{
   442  						requiredSize := newSize
   443  						if requiredSize > cap(rg.array) {
   444  							rg.resize(requiredSize)
   445  						}
   446  					}
   447  					rg.array[regi] = vali
   448  					if regi >= rg.top {
   449  						rg.top = regi + 1
   450  					}
   451  				}
   452  			} else {
   453  				// this section is inlined by go-inline
   454  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   455  				{
   456  					rg := reg
   457  					regi := RA
   458  					vali := LFalse
   459  					newSize := regi + 1
   460  					// this section is inlined by go-inline
   461  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   462  					{
   463  						requiredSize := newSize
   464  						if requiredSize > cap(rg.array) {
   465  							rg.resize(requiredSize)
   466  						}
   467  					}
   468  					rg.array[regi] = vali
   469  					if regi >= rg.top {
   470  						rg.top = regi + 1
   471  					}
   472  				}
   473  			}
   474  			if C != 0 {
   475  				cf.Pc++
   476  			}
   477  			return 0
   478  		},
   479  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_LOADNIL
   480  			reg := L.reg
   481  			cf := L.currentFrame
   482  			lbase := cf.LocalBase
   483  			A := int(inst>>18) & 0xff // GETA
   484  			RA := lbase + A
   485  			B := int(inst & 0x1ff) // GETB
   486  			for i := RA; i <= lbase+B; i++ {
   487  				// this section is inlined by go-inline
   488  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   489  				{
   490  					rg := reg
   491  					regi := i
   492  					vali := LNil
   493  					newSize := regi + 1
   494  					// this section is inlined by go-inline
   495  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   496  					{
   497  						requiredSize := newSize
   498  						if requiredSize > cap(rg.array) {
   499  							rg.resize(requiredSize)
   500  						}
   501  					}
   502  					rg.array[regi] = vali
   503  					if regi >= rg.top {
   504  						rg.top = regi + 1
   505  					}
   506  				}
   507  			}
   508  			return 0
   509  		},
   510  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_GETUPVAL
   511  			reg := L.reg
   512  			cf := L.currentFrame
   513  			lbase := cf.LocalBase
   514  			A := int(inst>>18) & 0xff // GETA
   515  			RA := lbase + A
   516  			B := int(inst & 0x1ff) // GETB
   517  			v := cf.Fn.Upvalues[B].Value()
   518  			// this section is inlined by go-inline
   519  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   520  			{
   521  				rg := reg
   522  				regi := RA
   523  				vali := v
   524  				newSize := regi + 1
   525  				// this section is inlined by go-inline
   526  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   527  				{
   528  					requiredSize := newSize
   529  					if requiredSize > cap(rg.array) {
   530  						rg.resize(requiredSize)
   531  					}
   532  				}
   533  				rg.array[regi] = vali
   534  				if regi >= rg.top {
   535  					rg.top = regi + 1
   536  				}
   537  			}
   538  			return 0
   539  		},
   540  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_GETGLOBAL
   541  			reg := L.reg
   542  			cf := L.currentFrame
   543  			lbase := cf.LocalBase
   544  			A := int(inst>>18) & 0xff // GETA
   545  			RA := lbase + A
   546  			Bx := int(inst & 0x3ffff) // GETBX
   547  			// reg.Set(RA, L.getField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx]))
   548  			v := L.getFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx])
   549  			// this section is inlined by go-inline
   550  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   551  			{
   552  				rg := reg
   553  				regi := RA
   554  				vali := v
   555  				newSize := regi + 1
   556  				// this section is inlined by go-inline
   557  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   558  				{
   559  					requiredSize := newSize
   560  					if requiredSize > cap(rg.array) {
   561  						rg.resize(requiredSize)
   562  					}
   563  				}
   564  				rg.array[regi] = vali
   565  				if regi >= rg.top {
   566  					rg.top = regi + 1
   567  				}
   568  			}
   569  			return 0
   570  		},
   571  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_GETTABLE
   572  			reg := L.reg
   573  			cf := L.currentFrame
   574  			lbase := cf.LocalBase
   575  			A := int(inst>>18) & 0xff // GETA
   576  			RA := lbase + A
   577  			B := int(inst & 0x1ff)    // GETB
   578  			C := int(inst>>9) & 0x1ff // GETC
   579  			v := L.getField(reg.Get(lbase+B), L.rkValue(C))
   580  			// this section is inlined by go-inline
   581  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   582  			{
   583  				rg := reg
   584  				regi := RA
   585  				vali := v
   586  				newSize := regi + 1
   587  				// this section is inlined by go-inline
   588  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   589  				{
   590  					requiredSize := newSize
   591  					if requiredSize > cap(rg.array) {
   592  						rg.resize(requiredSize)
   593  					}
   594  				}
   595  				rg.array[regi] = vali
   596  				if regi >= rg.top {
   597  					rg.top = regi + 1
   598  				}
   599  			}
   600  			return 0
   601  		},
   602  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_GETTABLEKS
   603  			reg := L.reg
   604  			cf := L.currentFrame
   605  			lbase := cf.LocalBase
   606  			A := int(inst>>18) & 0xff // GETA
   607  			RA := lbase + A
   608  			B := int(inst & 0x1ff)    // GETB
   609  			C := int(inst>>9) & 0x1ff // GETC
   610  			v := L.getFieldString(reg.Get(lbase+B), L.rkString(C))
   611  			// this section is inlined by go-inline
   612  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   613  			{
   614  				rg := reg
   615  				regi := RA
   616  				vali := v
   617  				newSize := regi + 1
   618  				// this section is inlined by go-inline
   619  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   620  				{
   621  					requiredSize := newSize
   622  					if requiredSize > cap(rg.array) {
   623  						rg.resize(requiredSize)
   624  					}
   625  				}
   626  				rg.array[regi] = vali
   627  				if regi >= rg.top {
   628  					rg.top = regi + 1
   629  				}
   630  			}
   631  			return 0
   632  		},
   633  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_SETGLOBAL
   634  			reg := L.reg
   635  			cf := L.currentFrame
   636  			lbase := cf.LocalBase
   637  			A := int(inst>>18) & 0xff // GETA
   638  			RA := lbase + A
   639  			Bx := int(inst & 0x3ffff) // GETBX
   640  			// L.setField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx], reg.Get(RA))
   641  			L.setFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx], reg.Get(RA))
   642  			return 0
   643  		},
   644  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_SETUPVAL
   645  			reg := L.reg
   646  			cf := L.currentFrame
   647  			lbase := cf.LocalBase
   648  			A := int(inst>>18) & 0xff // GETA
   649  			RA := lbase + A
   650  			B := int(inst & 0x1ff) // GETB
   651  			cf.Fn.Upvalues[B].SetValue(reg.Get(RA))
   652  			return 0
   653  		},
   654  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_SETTABLE
   655  			reg := L.reg
   656  			cf := L.currentFrame
   657  			lbase := cf.LocalBase
   658  			A := int(inst>>18) & 0xff // GETA
   659  			RA := lbase + A
   660  			B := int(inst & 0x1ff)    // GETB
   661  			C := int(inst>>9) & 0x1ff // GETC
   662  			L.setField(reg.Get(RA), L.rkValue(B), L.rkValue(C))
   663  			return 0
   664  		},
   665  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_SETTABLEKS
   666  			reg := L.reg
   667  			cf := L.currentFrame
   668  			lbase := cf.LocalBase
   669  			A := int(inst>>18) & 0xff // GETA
   670  			RA := lbase + A
   671  			B := int(inst & 0x1ff)    // GETB
   672  			C := int(inst>>9) & 0x1ff // GETC
   673  			L.setFieldString(reg.Get(RA), L.rkString(B), L.rkValue(C))
   674  			return 0
   675  		},
   676  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_NEWTABLE
   677  			reg := L.reg
   678  			cf := L.currentFrame
   679  			lbase := cf.LocalBase
   680  			A := int(inst>>18) & 0xff // GETA
   681  			RA := lbase + A
   682  			B := int(inst & 0x1ff)    // GETB
   683  			C := int(inst>>9) & 0x1ff // GETC
   684  			v := newLTable(B, C)
   685  			// this section is inlined by go-inline
   686  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   687  			{
   688  				rg := reg
   689  				regi := RA
   690  				vali := v
   691  				newSize := regi + 1
   692  				// this section is inlined by go-inline
   693  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   694  				{
   695  					requiredSize := newSize
   696  					if requiredSize > cap(rg.array) {
   697  						rg.resize(requiredSize)
   698  					}
   699  				}
   700  				rg.array[regi] = vali
   701  				if regi >= rg.top {
   702  					rg.top = regi + 1
   703  				}
   704  			}
   705  			return 0
   706  		},
   707  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_SELF
   708  			reg := L.reg
   709  			cf := L.currentFrame
   710  			lbase := cf.LocalBase
   711  			A := int(inst>>18) & 0xff // GETA
   712  			RA := lbase + A
   713  			B := int(inst & 0x1ff)    // GETB
   714  			C := int(inst>>9) & 0x1ff // GETC
   715  			selfobj := reg.Get(lbase + B)
   716  			v := L.getFieldString(selfobj, L.rkString(C))
   717  			// this section is inlined by go-inline
   718  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   719  			{
   720  				rg := reg
   721  				regi := RA
   722  				vali := v
   723  				newSize := regi + 1
   724  				// this section is inlined by go-inline
   725  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   726  				{
   727  					requiredSize := newSize
   728  					if requiredSize > cap(rg.array) {
   729  						rg.resize(requiredSize)
   730  					}
   731  				}
   732  				rg.array[regi] = vali
   733  				if regi >= rg.top {
   734  					rg.top = regi + 1
   735  				}
   736  			}
   737  			// this section is inlined by go-inline
   738  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   739  			{
   740  				rg := reg
   741  				regi := RA + 1
   742  				vali := selfobj
   743  				newSize := regi + 1
   744  				// this section is inlined by go-inline
   745  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   746  				{
   747  					requiredSize := newSize
   748  					if requiredSize > cap(rg.array) {
   749  						rg.resize(requiredSize)
   750  					}
   751  				}
   752  				rg.array[regi] = vali
   753  				if regi >= rg.top {
   754  					rg.top = regi + 1
   755  				}
   756  			}
   757  			return 0
   758  		},
   759  		opArith, // OP_ADD
   760  		opArith, // OP_SUB
   761  		opArith, // OP_MUL
   762  		opArith, // OP_DIV
   763  		opArith, // OP_BITOR
   764  		opArith, // OP_MOD
   765  		opArith, // OP_POW
   766  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_UNM
   767  			reg := L.reg
   768  			cf := L.currentFrame
   769  			lbase := cf.LocalBase
   770  			A := int(inst>>18) & 0xff // GETA
   771  			RA := lbase + A
   772  			B := int(inst & 0x1ff) // GETB
   773  			unaryv := L.rkValue(B)
   774  			if nm, ok := unaryv.(LNumber); ok {
   775  				// this section is inlined by go-inline
   776  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   777  				{
   778  					rg := reg
   779  					regi := RA
   780  					vali := -nm
   781  					newSize := regi + 1
   782  					// this section is inlined by go-inline
   783  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   784  					{
   785  						requiredSize := newSize
   786  						if requiredSize > cap(rg.array) {
   787  							rg.resize(requiredSize)
   788  						}
   789  					}
   790  					rg.array[regi] = vali
   791  					if regi >= rg.top {
   792  						rg.top = regi + 1
   793  					}
   794  				}
   795  			} else {
   796  				op := L.metaOp1(unaryv, "__unm")
   797  				if op.Type() == LTFunction {
   798  					reg.Push(op)
   799  					reg.Push(unaryv)
   800  					L.Call(1, 1)
   801  					// this section is inlined by go-inline
   802  					// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   803  					{
   804  						rg := reg
   805  						regi := RA
   806  						vali := reg.Pop()
   807  						newSize := regi + 1
   808  						// this section is inlined by go-inline
   809  						// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   810  						{
   811  							requiredSize := newSize
   812  							if requiredSize > cap(rg.array) {
   813  								rg.resize(requiredSize)
   814  							}
   815  						}
   816  						rg.array[regi] = vali
   817  						if regi >= rg.top {
   818  							rg.top = regi + 1
   819  						}
   820  					}
   821  				} else if str, ok1 := unaryv.(LString); ok1 {
   822  					if num, err := parseNumber(string(str)); err == nil {
   823  						// this section is inlined by go-inline
   824  						// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   825  						{
   826  							rg := reg
   827  							regi := RA
   828  							vali := -num
   829  							newSize := regi + 1
   830  							// this section is inlined by go-inline
   831  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   832  							{
   833  								requiredSize := newSize
   834  								if requiredSize > cap(rg.array) {
   835  									rg.resize(requiredSize)
   836  								}
   837  							}
   838  							rg.array[regi] = vali
   839  							if regi >= rg.top {
   840  								rg.top = regi + 1
   841  							}
   842  						}
   843  					} else {
   844  						L.RaiseError("__unm undefined")
   845  					}
   846  				} else {
   847  					L.RaiseError("__unm undefined")
   848  				}
   849  			}
   850  			return 0
   851  		},
   852  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_NOT
   853  			reg := L.reg
   854  			cf := L.currentFrame
   855  			lbase := cf.LocalBase
   856  			A := int(inst>>18) & 0xff // GETA
   857  			RA := lbase + A
   858  			B := int(inst & 0x1ff) // GETB
   859  			if LVIsFalse(reg.Get(lbase + B)) {
   860  				// this section is inlined by go-inline
   861  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   862  				{
   863  					rg := reg
   864  					regi := RA
   865  					vali := LTrue
   866  					newSize := regi + 1
   867  					// this section is inlined by go-inline
   868  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   869  					{
   870  						requiredSize := newSize
   871  						if requiredSize > cap(rg.array) {
   872  							rg.resize(requiredSize)
   873  						}
   874  					}
   875  					rg.array[regi] = vali
   876  					if regi >= rg.top {
   877  						rg.top = regi + 1
   878  					}
   879  				}
   880  			} else {
   881  				// this section is inlined by go-inline
   882  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   883  				{
   884  					rg := reg
   885  					regi := RA
   886  					vali := LFalse
   887  					newSize := regi + 1
   888  					// this section is inlined by go-inline
   889  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   890  					{
   891  						requiredSize := newSize
   892  						if requiredSize > cap(rg.array) {
   893  							rg.resize(requiredSize)
   894  						}
   895  					}
   896  					rg.array[regi] = vali
   897  					if regi >= rg.top {
   898  						rg.top = regi + 1
   899  					}
   900  				}
   901  			}
   902  			return 0
   903  		},
   904  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_LEN
   905  			reg := L.reg
   906  			cf := L.currentFrame
   907  			lbase := cf.LocalBase
   908  			A := int(inst>>18) & 0xff // GETA
   909  			RA := lbase + A
   910  			B := int(inst & 0x1ff) // GETB
   911  			switch lv := L.rkValue(B).(type) {
   912  			case LString:
   913  				// this section is inlined by go-inline
   914  				// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
   915  				{
   916  					rg := reg
   917  					regi := RA
   918  					vali := LNumber(len(lv))
   919  					newSize := regi + 1
   920  					// this section is inlined by go-inline
   921  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   922  					{
   923  						requiredSize := newSize
   924  						if requiredSize > cap(rg.array) {
   925  							rg.resize(requiredSize)
   926  						}
   927  					}
   928  					rg.array[regi] = rg.alloc.LNumber2I(vali)
   929  					if regi >= rg.top {
   930  						rg.top = regi + 1
   931  					}
   932  				}
   933  			default:
   934  				op := L.metaOp1(lv, "__len")
   935  				if op.Type() == LTFunction {
   936  					reg.Push(op)
   937  					reg.Push(lv)
   938  					L.Call(1, 1)
   939  					ret := reg.Pop()
   940  					if ret.Type() == LTNumber {
   941  						v, _ := ret.(LNumber)
   942  						// this section is inlined by go-inline
   943  						// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
   944  						{
   945  							rg := reg
   946  							regi := RA
   947  							vali := v
   948  							newSize := regi + 1
   949  							// this section is inlined by go-inline
   950  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   951  							{
   952  								requiredSize := newSize
   953  								if requiredSize > cap(rg.array) {
   954  									rg.resize(requiredSize)
   955  								}
   956  							}
   957  							rg.array[regi] = rg.alloc.LNumber2I(vali)
   958  							if regi >= rg.top {
   959  								rg.top = regi + 1
   960  							}
   961  						}
   962  					} else {
   963  						// this section is inlined by go-inline
   964  						// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   965  						{
   966  							rg := reg
   967  							regi := RA
   968  							vali := ret
   969  							newSize := regi + 1
   970  							// this section is inlined by go-inline
   971  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   972  							{
   973  								requiredSize := newSize
   974  								if requiredSize > cap(rg.array) {
   975  									rg.resize(requiredSize)
   976  								}
   977  							}
   978  							rg.array[regi] = vali
   979  							if regi >= rg.top {
   980  								rg.top = regi + 1
   981  							}
   982  						}
   983  					}
   984  				} else if lv.Type() == LTTable {
   985  					// this section is inlined by go-inline
   986  					// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
   987  					{
   988  						rg := reg
   989  						regi := RA
   990  						vali := LNumber(lv.(*LTable).Len())
   991  						newSize := regi + 1
   992  						// this section is inlined by go-inline
   993  						// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   994  						{
   995  							requiredSize := newSize
   996  							if requiredSize > cap(rg.array) {
   997  								rg.resize(requiredSize)
   998  							}
   999  						}
  1000  						rg.array[regi] = rg.alloc.LNumber2I(vali)
  1001  						if regi >= rg.top {
  1002  							rg.top = regi + 1
  1003  						}
  1004  					}
  1005  				} else {
  1006  					L.RaiseError("__len undefined")
  1007  				}
  1008  			}
  1009  			return 0
  1010  		},
  1011  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_CONCAT
  1012  			reg := L.reg
  1013  			cf := L.currentFrame
  1014  			lbase := cf.LocalBase
  1015  			A := int(inst>>18) & 0xff // GETA
  1016  			RA := lbase + A
  1017  			B := int(inst & 0x1ff)    // GETB
  1018  			C := int(inst>>9) & 0x1ff // GETC
  1019  			RC := lbase + C
  1020  			RB := lbase + B
  1021  			v := stringConcat(L, RC-RB+1, RC)
  1022  			// this section is inlined by go-inline
  1023  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  1024  			{
  1025  				rg := reg
  1026  				regi := RA
  1027  				vali := v
  1028  				newSize := regi + 1
  1029  				// this section is inlined by go-inline
  1030  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1031  				{
  1032  					requiredSize := newSize
  1033  					if requiredSize > cap(rg.array) {
  1034  						rg.resize(requiredSize)
  1035  					}
  1036  				}
  1037  				rg.array[regi] = vali
  1038  				if regi >= rg.top {
  1039  					rg.top = regi + 1
  1040  				}
  1041  			}
  1042  			return 0
  1043  		},
  1044  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_JMP
  1045  			cf := L.currentFrame
  1046  			Sbx := int(inst&0x3ffff) - opMaxArgSbx // GETSBX
  1047  			cf.Pc += Sbx
  1048  			return 0
  1049  		},
  1050  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_EQ
  1051  			cf := L.currentFrame
  1052  			A := int(inst>>18) & 0xff // GETA
  1053  			B := int(inst & 0x1ff)    // GETB
  1054  			C := int(inst>>9) & 0x1ff // GETC
  1055  			ret := equals(L, L.rkValue(B), L.rkValue(C), false)
  1056  			v := 1
  1057  			if ret {
  1058  				v = 0
  1059  			}
  1060  			if v == A {
  1061  				cf.Pc++
  1062  			}
  1063  			return 0
  1064  		},
  1065  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_LT
  1066  			cf := L.currentFrame
  1067  			A := int(inst>>18) & 0xff // GETA
  1068  			B := int(inst & 0x1ff)    // GETB
  1069  			C := int(inst>>9) & 0x1ff // GETC
  1070  			ret := lessThan(L, L.rkValue(B), L.rkValue(C))
  1071  			v := 1
  1072  			if ret {
  1073  				v = 0
  1074  			}
  1075  			if v == A {
  1076  				cf.Pc++
  1077  			}
  1078  			return 0
  1079  		},
  1080  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_LE
  1081  			cf := L.currentFrame
  1082  			A := int(inst>>18) & 0xff // GETA
  1083  			B := int(inst & 0x1ff)    // GETB
  1084  			C := int(inst>>9) & 0x1ff // GETC
  1085  			lhs := L.rkValue(B)
  1086  			rhs := L.rkValue(C)
  1087  			ret := false
  1088  
  1089  			if v1, ok1 := lhs.(LNumber); ok1 {
  1090  				if v2, ok2 := rhs.(LNumber); ok2 {
  1091  					ret = v1 <= v2
  1092  				} else {
  1093  					L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  1094  				}
  1095  			} else {
  1096  				if lhs.Type() != rhs.Type() {
  1097  					L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  1098  				}
  1099  				switch lhs.Type() {
  1100  				case LTString:
  1101  					ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) <= 0
  1102  				default:
  1103  					switch objectRational(L, lhs, rhs, "__le") {
  1104  					case 1:
  1105  						ret = true
  1106  					case 0:
  1107  						ret = false
  1108  					default:
  1109  						ret = !objectRationalWithError(L, rhs, lhs, "__lt")
  1110  					}
  1111  				}
  1112  			}
  1113  
  1114  			v := 1
  1115  			if ret {
  1116  				v = 0
  1117  			}
  1118  			if v == A {
  1119  				cf.Pc++
  1120  			}
  1121  			return 0
  1122  		},
  1123  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_TEST
  1124  			reg := L.reg
  1125  			cf := L.currentFrame
  1126  			lbase := cf.LocalBase
  1127  			A := int(inst>>18) & 0xff // GETA
  1128  			RA := lbase + A
  1129  			C := int(inst>>9) & 0x1ff // GETC
  1130  			if LVAsBool(reg.Get(RA)) == (C == 0) {
  1131  				cf.Pc++
  1132  			}
  1133  			return 0
  1134  		},
  1135  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_TESTSET
  1136  			reg := L.reg
  1137  			cf := L.currentFrame
  1138  			lbase := cf.LocalBase
  1139  			A := int(inst>>18) & 0xff // GETA
  1140  			RA := lbase + A
  1141  			B := int(inst & 0x1ff)    // GETB
  1142  			C := int(inst>>9) & 0x1ff // GETC
  1143  			if value := reg.Get(lbase + B); LVAsBool(value) != (C == 0) {
  1144  				// this section is inlined by go-inline
  1145  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  1146  				{
  1147  					rg := reg
  1148  					regi := RA
  1149  					vali := value
  1150  					newSize := regi + 1
  1151  					// this section is inlined by go-inline
  1152  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1153  					{
  1154  						requiredSize := newSize
  1155  						if requiredSize > cap(rg.array) {
  1156  							rg.resize(requiredSize)
  1157  						}
  1158  					}
  1159  					rg.array[regi] = vali
  1160  					if regi >= rg.top {
  1161  						rg.top = regi + 1
  1162  					}
  1163  				}
  1164  			} else {
  1165  				cf.Pc++
  1166  			}
  1167  			return 0
  1168  		},
  1169  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_CALL
  1170  			reg := L.reg
  1171  			cf := L.currentFrame
  1172  			lbase := cf.LocalBase
  1173  			A := int(inst>>18) & 0xff // GETA
  1174  			RA := lbase + A
  1175  			B := int(inst & 0x1ff)    // GETB
  1176  			C := int(inst>>9) & 0x1ff // GETC
  1177  			nargs := B - 1
  1178  			if B == 0 {
  1179  				nargs = reg.Top() - (RA + 1)
  1180  			}
  1181  			lv := reg.Get(RA)
  1182  			nret := C - 1
  1183  			var callable *LFunction
  1184  			var meta bool
  1185  			if fn, ok := lv.(*LFunction); ok {
  1186  				callable = fn
  1187  				meta = false
  1188  			} else {
  1189  				callable, meta = L.metaCall(lv)
  1190  			}
  1191  			// this section is inlined by go-inline
  1192  			// source function is 'func (ls *LState) pushCallFrame(cf callFrame, fn LValue, meta bool) ' in '_state.go'
  1193  			{
  1194  				ls := L
  1195  				cf := callFrame{Fn: callable, Pc: 0, Base: RA, LocalBase: RA + 1, ReturnBase: RA, NArgs: nargs, NRet: nret, Parent: cf, TailCall: 0}
  1196  				fn := lv
  1197  				if meta {
  1198  					cf.NArgs++
  1199  					ls.reg.Insert(fn, cf.LocalBase)
  1200  				}
  1201  				if cf.Fn == nil {
  1202  					ls.RaiseError("attempt to call a non-function object")
  1203  				}
  1204  				if ls.stack.IsFull() {
  1205  					ls.RaiseError("stack overflow")
  1206  				}
  1207  				ls.stack.Push(cf)
  1208  				newcf := ls.stack.Last()
  1209  				// this section is inlined by go-inline
  1210  				// source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go'
  1211  				{
  1212  					cf := newcf
  1213  					if cf.Fn.IsG {
  1214  						ls.reg.SetTop(cf.LocalBase + cf.NArgs)
  1215  					} else {
  1216  						proto := cf.Fn.Proto
  1217  						nargs := cf.NArgs
  1218  						np := int(proto.NumParameters)
  1219  						if nargs < np {
  1220  							// default any missing arguments to nil
  1221  							newSize := cf.LocalBase + np
  1222  							// this section is inlined by go-inline
  1223  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1224  							{
  1225  								rg := ls.reg
  1226  								requiredSize := newSize
  1227  								if requiredSize > cap(rg.array) {
  1228  									rg.resize(requiredSize)
  1229  								}
  1230  							}
  1231  							for i := nargs; i < np; i++ {
  1232  								ls.reg.array[cf.LocalBase+i] = LNil
  1233  							}
  1234  							nargs = np
  1235  							ls.reg.top = newSize
  1236  						}
  1237  
  1238  						if (proto.IsVarArg & VarArgIsVarArg) == 0 {
  1239  							if nargs < int(proto.NumUsedRegisters) {
  1240  								nargs = int(proto.NumUsedRegisters)
  1241  							}
  1242  							newSize := cf.LocalBase + nargs
  1243  							// this section is inlined by go-inline
  1244  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1245  							{
  1246  								rg := ls.reg
  1247  								requiredSize := newSize
  1248  								if requiredSize > cap(rg.array) {
  1249  									rg.resize(requiredSize)
  1250  								}
  1251  							}
  1252  							for i := np; i < nargs; i++ {
  1253  								ls.reg.array[cf.LocalBase+i] = LNil
  1254  							}
  1255  							ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters)
  1256  						} else {
  1257  							/* swap vararg positions:
  1258  									   closure
  1259  									   namedparam1 <- lbase
  1260  									   namedparam2
  1261  									   vararg1
  1262  									   vararg2
  1263  
  1264  							           TO
  1265  
  1266  									   closure
  1267  									   nil
  1268  									   nil
  1269  									   vararg1
  1270  									   vararg2
  1271  									   namedparam1 <- lbase
  1272  									   namedparam2
  1273  							*/
  1274  							nvarargs := nargs - np
  1275  							if nvarargs < 0 {
  1276  								nvarargs = 0
  1277  							}
  1278  
  1279  							ls.reg.SetTop(cf.LocalBase + nargs + np)
  1280  							for i := 0; i < np; i++ {
  1281  								// ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i))
  1282  								ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i]
  1283  								// ls.reg.Set(cf.LocalBase+i, LNil)
  1284  								ls.reg.array[cf.LocalBase+i] = LNil
  1285  							}
  1286  
  1287  							if CompatVarArg {
  1288  								ls.reg.SetTop(cf.LocalBase + nargs + np + 1)
  1289  								if (proto.IsVarArg & VarArgNeedsArg) != 0 {
  1290  									argtb := newLTable(nvarargs, 0)
  1291  									for i := 0; i < nvarargs; i++ {
  1292  										argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i))
  1293  									}
  1294  									argtb.RawSetString("n", LNumber(nvarargs))
  1295  									// ls.reg.Set(cf.LocalBase+nargs+np, argtb)
  1296  									ls.reg.array[cf.LocalBase+nargs+np] = argtb
  1297  								} else {
  1298  									ls.reg.array[cf.LocalBase+nargs+np] = LNil
  1299  								}
  1300  							}
  1301  							cf.LocalBase += nargs
  1302  							maxreg := cf.LocalBase + int(proto.NumUsedRegisters)
  1303  							ls.reg.SetTop(maxreg)
  1304  						}
  1305  					}
  1306  				}
  1307  				ls.currentFrame = newcf
  1308  			}
  1309  			if callable.IsG && callGFunction(L, false) {
  1310  				return 1
  1311  			}
  1312  			return 0
  1313  		},
  1314  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_TAILCALL
  1315  			reg := L.reg
  1316  			cf := L.currentFrame
  1317  			lbase := cf.LocalBase
  1318  			A := int(inst>>18) & 0xff // GETA
  1319  			RA := lbase + A
  1320  			B := int(inst & 0x1ff) // GETB
  1321  			nargs := B - 1
  1322  			if B == 0 {
  1323  				nargs = reg.Top() - (RA + 1)
  1324  			}
  1325  			lv := reg.Get(RA)
  1326  			var callable *LFunction
  1327  			var meta bool
  1328  			if fn, ok := lv.(*LFunction); ok {
  1329  				callable = fn
  1330  				meta = false
  1331  			} else {
  1332  				callable, meta = L.metaCall(lv)
  1333  			}
  1334  			if callable == nil {
  1335  				L.RaiseError("attempt to call a non-function object")
  1336  			}
  1337  			// this section is inlined by go-inline
  1338  			// source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go'
  1339  			{
  1340  				ls := L
  1341  				idx := lbase
  1342  				if ls.uvcache != nil {
  1343  					var prev *Upvalue
  1344  					for uv := ls.uvcache; uv != nil; uv = uv.next {
  1345  						if uv.index >= idx {
  1346  							if prev != nil {
  1347  								prev.next = nil
  1348  							} else {
  1349  								ls.uvcache = nil
  1350  							}
  1351  							uv.Close()
  1352  						}
  1353  						prev = uv
  1354  					}
  1355  				}
  1356  			}
  1357  			if callable.IsG {
  1358  				luaframe := cf
  1359  				L.pushCallFrame(callFrame{
  1360  					Fn:         callable,
  1361  					Pc:         0,
  1362  					Base:       RA,
  1363  					LocalBase:  RA + 1,
  1364  					ReturnBase: cf.ReturnBase,
  1365  					NArgs:      nargs,
  1366  					NRet:       cf.NRet,
  1367  					Parent:     cf,
  1368  					TailCall:   0,
  1369  				}, lv, meta)
  1370  				if callGFunction(L, true) {
  1371  					return 1
  1372  				}
  1373  				if L.currentFrame == nil || L.currentFrame.Fn.IsG || luaframe == baseframe {
  1374  					return 1
  1375  				}
  1376  			} else {
  1377  				base := cf.Base
  1378  				cf.Fn = callable
  1379  				cf.Pc = 0
  1380  				cf.Base = RA
  1381  				cf.LocalBase = RA + 1
  1382  				cf.ReturnBase = cf.ReturnBase
  1383  				cf.NArgs = nargs
  1384  				cf.NRet = cf.NRet
  1385  				cf.TailCall++
  1386  				lbase := cf.LocalBase
  1387  				if meta {
  1388  					cf.NArgs++
  1389  					L.reg.Insert(lv, cf.LocalBase)
  1390  				}
  1391  				// this section is inlined by go-inline
  1392  				// source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go'
  1393  				{
  1394  					ls := L
  1395  					if cf.Fn.IsG {
  1396  						ls.reg.SetTop(cf.LocalBase + cf.NArgs)
  1397  					} else {
  1398  						proto := cf.Fn.Proto
  1399  						nargs := cf.NArgs
  1400  						np := int(proto.NumParameters)
  1401  						if nargs < np {
  1402  							// default any missing arguments to nil
  1403  							newSize := cf.LocalBase + np
  1404  							// this section is inlined by go-inline
  1405  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1406  							{
  1407  								rg := ls.reg
  1408  								requiredSize := newSize
  1409  								if requiredSize > cap(rg.array) {
  1410  									rg.resize(requiredSize)
  1411  								}
  1412  							}
  1413  							for i := nargs; i < np; i++ {
  1414  								ls.reg.array[cf.LocalBase+i] = LNil
  1415  							}
  1416  							nargs = np
  1417  							ls.reg.top = newSize
  1418  						}
  1419  
  1420  						if (proto.IsVarArg & VarArgIsVarArg) == 0 {
  1421  							if nargs < int(proto.NumUsedRegisters) {
  1422  								nargs = int(proto.NumUsedRegisters)
  1423  							}
  1424  							newSize := cf.LocalBase + nargs
  1425  							// this section is inlined by go-inline
  1426  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1427  							{
  1428  								rg := ls.reg
  1429  								requiredSize := newSize
  1430  								if requiredSize > cap(rg.array) {
  1431  									rg.resize(requiredSize)
  1432  								}
  1433  							}
  1434  							for i := np; i < nargs; i++ {
  1435  								ls.reg.array[cf.LocalBase+i] = LNil
  1436  							}
  1437  							ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters)
  1438  						} else {
  1439  							/* swap vararg positions:
  1440  									   closure
  1441  									   namedparam1 <- lbase
  1442  									   namedparam2
  1443  									   vararg1
  1444  									   vararg2
  1445  
  1446  							           TO
  1447  
  1448  									   closure
  1449  									   nil
  1450  									   nil
  1451  									   vararg1
  1452  									   vararg2
  1453  									   namedparam1 <- lbase
  1454  									   namedparam2
  1455  							*/
  1456  							nvarargs := nargs - np
  1457  							if nvarargs < 0 {
  1458  								nvarargs = 0
  1459  							}
  1460  
  1461  							ls.reg.SetTop(cf.LocalBase + nargs + np)
  1462  							for i := 0; i < np; i++ {
  1463  								// ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i))
  1464  								ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i]
  1465  								// ls.reg.Set(cf.LocalBase+i, LNil)
  1466  								ls.reg.array[cf.LocalBase+i] = LNil
  1467  							}
  1468  
  1469  							if CompatVarArg {
  1470  								ls.reg.SetTop(cf.LocalBase + nargs + np + 1)
  1471  								if (proto.IsVarArg & VarArgNeedsArg) != 0 {
  1472  									argtb := newLTable(nvarargs, 0)
  1473  									for i := 0; i < nvarargs; i++ {
  1474  										argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i))
  1475  									}
  1476  									argtb.RawSetString("n", LNumber(nvarargs))
  1477  									// ls.reg.Set(cf.LocalBase+nargs+np, argtb)
  1478  									ls.reg.array[cf.LocalBase+nargs+np] = argtb
  1479  								} else {
  1480  									ls.reg.array[cf.LocalBase+nargs+np] = LNil
  1481  								}
  1482  							}
  1483  							cf.LocalBase += nargs
  1484  							maxreg := cf.LocalBase + int(proto.NumUsedRegisters)
  1485  							ls.reg.SetTop(maxreg)
  1486  						}
  1487  					}
  1488  				}
  1489  				// this section is inlined by go-inline
  1490  				// source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go'
  1491  				{
  1492  					rg := L.reg
  1493  					regv := base
  1494  					start := RA
  1495  					limit := -1
  1496  					n := reg.Top() - RA - 1
  1497  					newSize := regv + n
  1498  					// this section is inlined by go-inline
  1499  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1500  					{
  1501  						requiredSize := newSize
  1502  						if requiredSize > cap(rg.array) {
  1503  							rg.resize(requiredSize)
  1504  						}
  1505  					}
  1506  					if limit == -1 || limit > rg.top {
  1507  						limit = rg.top
  1508  					}
  1509  					for i := 0; i < n; i++ {
  1510  						srcIdx := start + i
  1511  						if srcIdx >= limit || srcIdx < 0 {
  1512  							rg.array[regv+i] = LNil
  1513  						} else {
  1514  							rg.array[regv+i] = rg.array[srcIdx]
  1515  						}
  1516  					}
  1517  
  1518  					// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1519  					// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1520  					oldtop := rg.top
  1521  					rg.top = regv + n
  1522  					if rg.top < oldtop {
  1523  						nilRange := rg.array[rg.top:oldtop]
  1524  						for i := range nilRange {
  1525  							nilRange[i] = nil
  1526  						}
  1527  					}
  1528  				}
  1529  				cf.Base = base
  1530  				cf.LocalBase = base + (cf.LocalBase - lbase + 1)
  1531  			}
  1532  			return 0
  1533  		},
  1534  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_RETURN
  1535  			reg := L.reg
  1536  			cf := L.currentFrame
  1537  			lbase := cf.LocalBase
  1538  			A := int(inst>>18) & 0xff // GETA
  1539  			RA := lbase + A
  1540  			B := int(inst & 0x1ff) // GETB
  1541  			// this section is inlined by go-inline
  1542  			// source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go'
  1543  			{
  1544  				ls := L
  1545  				idx := lbase
  1546  				if ls.uvcache != nil {
  1547  					var prev *Upvalue
  1548  					for uv := ls.uvcache; uv != nil; uv = uv.next {
  1549  						if uv.index >= idx {
  1550  							if prev != nil {
  1551  								prev.next = nil
  1552  							} else {
  1553  								ls.uvcache = nil
  1554  							}
  1555  							uv.Close()
  1556  						}
  1557  						prev = uv
  1558  					}
  1559  				}
  1560  			}
  1561  			nret := B - 1
  1562  			if B == 0 {
  1563  				nret = reg.Top() - RA
  1564  			}
  1565  			n := cf.NRet
  1566  			if cf.NRet == MultRet {
  1567  				n = nret
  1568  			}
  1569  
  1570  			if L.Parent != nil && L.stack.Sp() == 1 {
  1571  				// this section is inlined by go-inline
  1572  				// source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go'
  1573  				{
  1574  					regv := reg.Top()
  1575  					start := RA
  1576  					b := B
  1577  					if b == 1 {
  1578  						// this section is inlined by go-inline
  1579  						// source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go'
  1580  						{
  1581  							rg := L.reg
  1582  							regm := regv
  1583  							newSize := regm + n
  1584  							// this section is inlined by go-inline
  1585  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1586  							{
  1587  								requiredSize := newSize
  1588  								if requiredSize > cap(rg.array) {
  1589  									rg.resize(requiredSize)
  1590  								}
  1591  							}
  1592  							for i := 0; i < n; i++ {
  1593  								rg.array[regm+i] = LNil
  1594  							}
  1595  							// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1596  							// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1597  							oldtop := rg.top
  1598  							rg.top = regm + n
  1599  							if rg.top < oldtop {
  1600  								nilRange := rg.array[rg.top:oldtop]
  1601  								for i := range nilRange {
  1602  									nilRange[i] = nil
  1603  								}
  1604  							}
  1605  						}
  1606  					} else {
  1607  						// this section is inlined by go-inline
  1608  						// source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go'
  1609  						{
  1610  							rg := L.reg
  1611  							limit := -1
  1612  							newSize := regv + n
  1613  							// this section is inlined by go-inline
  1614  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1615  							{
  1616  								requiredSize := newSize
  1617  								if requiredSize > cap(rg.array) {
  1618  									rg.resize(requiredSize)
  1619  								}
  1620  							}
  1621  							if limit == -1 || limit > rg.top {
  1622  								limit = rg.top
  1623  							}
  1624  							for i := 0; i < n; i++ {
  1625  								srcIdx := start + i
  1626  								if srcIdx >= limit || srcIdx < 0 {
  1627  									rg.array[regv+i] = LNil
  1628  								} else {
  1629  									rg.array[regv+i] = rg.array[srcIdx]
  1630  								}
  1631  							}
  1632  
  1633  							// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1634  							// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1635  							oldtop := rg.top
  1636  							rg.top = regv + n
  1637  							if rg.top < oldtop {
  1638  								nilRange := rg.array[rg.top:oldtop]
  1639  								for i := range nilRange {
  1640  									nilRange[i] = nil
  1641  								}
  1642  							}
  1643  						}
  1644  						if b > 1 && n > (b-1) {
  1645  							// this section is inlined by go-inline
  1646  							// source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go'
  1647  							{
  1648  								rg := L.reg
  1649  								regm := regv + b - 1
  1650  								n := n - (b - 1)
  1651  								newSize := regm + n
  1652  								// this section is inlined by go-inline
  1653  								// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1654  								{
  1655  									requiredSize := newSize
  1656  									if requiredSize > cap(rg.array) {
  1657  										rg.resize(requiredSize)
  1658  									}
  1659  								}
  1660  								for i := 0; i < n; i++ {
  1661  									rg.array[regm+i] = LNil
  1662  								}
  1663  								// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1664  								// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1665  								oldtop := rg.top
  1666  								rg.top = regm + n
  1667  								if rg.top < oldtop {
  1668  									nilRange := rg.array[rg.top:oldtop]
  1669  									for i := range nilRange {
  1670  										nilRange[i] = nil
  1671  									}
  1672  								}
  1673  							}
  1674  						}
  1675  					}
  1676  				}
  1677  				switchToParentThread(L, n, false, true)
  1678  				return 1
  1679  			}
  1680  			islast := baseframe == L.stack.Pop() || L.stack.IsEmpty()
  1681  			// this section is inlined by go-inline
  1682  			// source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go'
  1683  			{
  1684  				regv := cf.ReturnBase
  1685  				start := RA
  1686  				b := B
  1687  				if b == 1 {
  1688  					// this section is inlined by go-inline
  1689  					// source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go'
  1690  					{
  1691  						rg := L.reg
  1692  						regm := regv
  1693  						newSize := regm + n
  1694  						// this section is inlined by go-inline
  1695  						// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1696  						{
  1697  							requiredSize := newSize
  1698  							if requiredSize > cap(rg.array) {
  1699  								rg.resize(requiredSize)
  1700  							}
  1701  						}
  1702  						for i := 0; i < n; i++ {
  1703  							rg.array[regm+i] = LNil
  1704  						}
  1705  						// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1706  						// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1707  						oldtop := rg.top
  1708  						rg.top = regm + n
  1709  						if rg.top < oldtop {
  1710  							nilRange := rg.array[rg.top:oldtop]
  1711  							for i := range nilRange {
  1712  								nilRange[i] = nil
  1713  							}
  1714  						}
  1715  					}
  1716  				} else {
  1717  					// this section is inlined by go-inline
  1718  					// source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go'
  1719  					{
  1720  						rg := L.reg
  1721  						limit := -1
  1722  						newSize := regv + n
  1723  						// this section is inlined by go-inline
  1724  						// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1725  						{
  1726  							requiredSize := newSize
  1727  							if requiredSize > cap(rg.array) {
  1728  								rg.resize(requiredSize)
  1729  							}
  1730  						}
  1731  						if limit == -1 || limit > rg.top {
  1732  							limit = rg.top
  1733  						}
  1734  						for i := 0; i < n; i++ {
  1735  							srcIdx := start + i
  1736  							if srcIdx >= limit || srcIdx < 0 {
  1737  								rg.array[regv+i] = LNil
  1738  							} else {
  1739  								rg.array[regv+i] = rg.array[srcIdx]
  1740  							}
  1741  						}
  1742  
  1743  						// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1744  						// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1745  						oldtop := rg.top
  1746  						rg.top = regv + n
  1747  						if rg.top < oldtop {
  1748  							nilRange := rg.array[rg.top:oldtop]
  1749  							for i := range nilRange {
  1750  								nilRange[i] = nil
  1751  							}
  1752  						}
  1753  					}
  1754  					if b > 1 && n > (b-1) {
  1755  						// this section is inlined by go-inline
  1756  						// source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go'
  1757  						{
  1758  							rg := L.reg
  1759  							regm := regv + b - 1
  1760  							n := n - (b - 1)
  1761  							newSize := regm + n
  1762  							// this section is inlined by go-inline
  1763  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1764  							{
  1765  								requiredSize := newSize
  1766  								if requiredSize > cap(rg.array) {
  1767  									rg.resize(requiredSize)
  1768  								}
  1769  							}
  1770  							for i := 0; i < n; i++ {
  1771  								rg.array[regm+i] = LNil
  1772  							}
  1773  							// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1774  							// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1775  							oldtop := rg.top
  1776  							rg.top = regm + n
  1777  							if rg.top < oldtop {
  1778  								nilRange := rg.array[rg.top:oldtop]
  1779  								for i := range nilRange {
  1780  									nilRange[i] = nil
  1781  								}
  1782  							}
  1783  						}
  1784  					}
  1785  				}
  1786  			}
  1787  			L.currentFrame = L.stack.Last()
  1788  			if islast || L.currentFrame == nil || L.currentFrame.Fn.IsG {
  1789  				return 1
  1790  			}
  1791  			return 0
  1792  		},
  1793  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_FORLOOP
  1794  			reg := L.reg
  1795  			cf := L.currentFrame
  1796  			lbase := cf.LocalBase
  1797  			A := int(inst>>18) & 0xff // GETA
  1798  			RA := lbase + A
  1799  			if init, ok1 := reg.Get(RA).(LNumber); ok1 {
  1800  				if limit, ok2 := reg.Get(RA + 1).(LNumber); ok2 {
  1801  					if step, ok3 := reg.Get(RA + 2).(LNumber); ok3 {
  1802  						init += step
  1803  						v := LNumber(init)
  1804  						// this section is inlined by go-inline
  1805  						// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
  1806  						{
  1807  							rg := reg
  1808  							regi := RA
  1809  							vali := v
  1810  							newSize := regi + 1
  1811  							// this section is inlined by go-inline
  1812  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1813  							{
  1814  								requiredSize := newSize
  1815  								if requiredSize > cap(rg.array) {
  1816  									rg.resize(requiredSize)
  1817  								}
  1818  							}
  1819  							rg.array[regi] = rg.alloc.LNumber2I(vali)
  1820  							if regi >= rg.top {
  1821  								rg.top = regi + 1
  1822  							}
  1823  						}
  1824  						if (step > 0 && init <= limit) || (step <= 0 && init >= limit) {
  1825  							Sbx := int(inst&0x3ffff) - opMaxArgSbx // GETSBX
  1826  							cf.Pc += Sbx
  1827  							// this section is inlined by go-inline
  1828  							// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
  1829  							{
  1830  								rg := reg
  1831  								regi := RA + 3
  1832  								vali := v
  1833  								newSize := regi + 1
  1834  								// this section is inlined by go-inline
  1835  								// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1836  								{
  1837  									requiredSize := newSize
  1838  									if requiredSize > cap(rg.array) {
  1839  										rg.resize(requiredSize)
  1840  									}
  1841  								}
  1842  								rg.array[regi] = rg.alloc.LNumber2I(vali)
  1843  								if regi >= rg.top {
  1844  									rg.top = regi + 1
  1845  								}
  1846  							}
  1847  						} else {
  1848  							// this section is inlined by go-inline
  1849  							// source function is 'func (rg *registry) SetTop(topi int) ' in '_state.go'
  1850  							{
  1851  								rg := reg
  1852  								topi := RA + 1
  1853  								// this section is inlined by go-inline
  1854  								// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1855  								{
  1856  									requiredSize := topi
  1857  									if requiredSize > cap(rg.array) {
  1858  										rg.resize(requiredSize)
  1859  									}
  1860  								}
  1861  								oldtopi := rg.top
  1862  								rg.top = topi
  1863  								for i := oldtopi; i < rg.top; i++ {
  1864  									rg.array[i] = LNil
  1865  								}
  1866  								// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1867  								// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1868  								if rg.top < oldtopi {
  1869  									nilRange := rg.array[rg.top:oldtopi]
  1870  									for i := range nilRange {
  1871  										nilRange[i] = nil
  1872  									}
  1873  								}
  1874  								//for i := rg.top; i < oldtop; i++ {
  1875  								//	rg.array[i] = LNil
  1876  								//}
  1877  							}
  1878  						}
  1879  					} else {
  1880  						L.RaiseError("for statement step must be a number")
  1881  					}
  1882  				} else {
  1883  					L.RaiseError("for statement limit must be a number")
  1884  				}
  1885  			} else {
  1886  				L.RaiseError("for statement init must be a number")
  1887  			}
  1888  			return 0
  1889  		},
  1890  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_FORPREP
  1891  			reg := L.reg
  1892  			cf := L.currentFrame
  1893  			lbase := cf.LocalBase
  1894  			A := int(inst>>18) & 0xff // GETA
  1895  			RA := lbase + A
  1896  			Sbx := int(inst&0x3ffff) - opMaxArgSbx // GETSBX
  1897  			if init, ok1 := reg.Get(RA).(LNumber); ok1 {
  1898  				if step, ok2 := reg.Get(RA + 2).(LNumber); ok2 {
  1899  					// this section is inlined by go-inline
  1900  					// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
  1901  					{
  1902  						rg := reg
  1903  						regi := RA
  1904  						vali := LNumber(init - step)
  1905  						newSize := regi + 1
  1906  						// this section is inlined by go-inline
  1907  						// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1908  						{
  1909  							requiredSize := newSize
  1910  							if requiredSize > cap(rg.array) {
  1911  								rg.resize(requiredSize)
  1912  							}
  1913  						}
  1914  						rg.array[regi] = rg.alloc.LNumber2I(vali)
  1915  						if regi >= rg.top {
  1916  							rg.top = regi + 1
  1917  						}
  1918  					}
  1919  				} else {
  1920  					L.RaiseError("for statement step must be a number")
  1921  				}
  1922  			} else {
  1923  				L.RaiseError("for statement init must be a number")
  1924  			}
  1925  			cf.Pc += Sbx
  1926  			return 0
  1927  		},
  1928  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_TFORLOOP
  1929  			reg := L.reg
  1930  			cf := L.currentFrame
  1931  			lbase := cf.LocalBase
  1932  			A := int(inst>>18) & 0xff // GETA
  1933  			RA := lbase + A
  1934  			C := int(inst>>9) & 0x1ff // GETC
  1935  			nret := C
  1936  			// this section is inlined by go-inline
  1937  			// source function is 'func (rg *registry) SetTop(topi int) ' in '_state.go'
  1938  			{
  1939  				rg := reg
  1940  				topi := RA + 3 + 2
  1941  				// this section is inlined by go-inline
  1942  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1943  				{
  1944  					requiredSize := topi
  1945  					if requiredSize > cap(rg.array) {
  1946  						rg.resize(requiredSize)
  1947  					}
  1948  				}
  1949  				oldtopi := rg.top
  1950  				rg.top = topi
  1951  				for i := oldtopi; i < rg.top; i++ {
  1952  					rg.array[i] = LNil
  1953  				}
  1954  				// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1955  				// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1956  				if rg.top < oldtopi {
  1957  					nilRange := rg.array[rg.top:oldtopi]
  1958  					for i := range nilRange {
  1959  						nilRange[i] = nil
  1960  					}
  1961  				}
  1962  				//for i := rg.top; i < oldtop; i++ {
  1963  				//	rg.array[i] = LNil
  1964  				//}
  1965  			}
  1966  			// this section is inlined by go-inline
  1967  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  1968  			{
  1969  				rg := reg
  1970  				regi := RA + 3 + 2
  1971  				vali := reg.Get(RA + 2)
  1972  				newSize := regi + 1
  1973  				// this section is inlined by go-inline
  1974  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1975  				{
  1976  					requiredSize := newSize
  1977  					if requiredSize > cap(rg.array) {
  1978  						rg.resize(requiredSize)
  1979  					}
  1980  				}
  1981  				rg.array[regi] = vali
  1982  				if regi >= rg.top {
  1983  					rg.top = regi + 1
  1984  				}
  1985  			}
  1986  			// this section is inlined by go-inline
  1987  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  1988  			{
  1989  				rg := reg
  1990  				regi := RA + 3 + 1
  1991  				vali := reg.Get(RA + 1)
  1992  				newSize := regi + 1
  1993  				// this section is inlined by go-inline
  1994  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1995  				{
  1996  					requiredSize := newSize
  1997  					if requiredSize > cap(rg.array) {
  1998  						rg.resize(requiredSize)
  1999  					}
  2000  				}
  2001  				rg.array[regi] = vali
  2002  				if regi >= rg.top {
  2003  					rg.top = regi + 1
  2004  				}
  2005  			}
  2006  			// this section is inlined by go-inline
  2007  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  2008  			{
  2009  				rg := reg
  2010  				regi := RA + 3
  2011  				vali := reg.Get(RA)
  2012  				newSize := regi + 1
  2013  				// this section is inlined by go-inline
  2014  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2015  				{
  2016  					requiredSize := newSize
  2017  					if requiredSize > cap(rg.array) {
  2018  						rg.resize(requiredSize)
  2019  					}
  2020  				}
  2021  				rg.array[regi] = vali
  2022  				if regi >= rg.top {
  2023  					rg.top = regi + 1
  2024  				}
  2025  			}
  2026  			L.callR(2, nret, RA+3)
  2027  			if value := reg.Get(RA + 3); value != LNil {
  2028  				// this section is inlined by go-inline
  2029  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  2030  				{
  2031  					rg := reg
  2032  					regi := RA + 2
  2033  					vali := value
  2034  					newSize := regi + 1
  2035  					// this section is inlined by go-inline
  2036  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2037  					{
  2038  						requiredSize := newSize
  2039  						if requiredSize > cap(rg.array) {
  2040  							rg.resize(requiredSize)
  2041  						}
  2042  					}
  2043  					rg.array[regi] = vali
  2044  					if regi >= rg.top {
  2045  						rg.top = regi + 1
  2046  					}
  2047  				}
  2048  				pc := cf.Fn.Proto.Code[cf.Pc]
  2049  				cf.Pc += int(pc&0x3ffff) - opMaxArgSbx
  2050  			}
  2051  			cf.Pc++
  2052  			return 0
  2053  		},
  2054  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_SETLIST
  2055  			reg := L.reg
  2056  			cf := L.currentFrame
  2057  			lbase := cf.LocalBase
  2058  			A := int(inst>>18) & 0xff // GETA
  2059  			RA := lbase + A
  2060  			B := int(inst & 0x1ff)    // GETB
  2061  			C := int(inst>>9) & 0x1ff // GETC
  2062  			if C == 0 {
  2063  				C = int(cf.Fn.Proto.Code[cf.Pc])
  2064  				cf.Pc++
  2065  			}
  2066  			offset := (C - 1) * FieldsPerFlush
  2067  			table := reg.Get(RA).(*LTable)
  2068  			nelem := B
  2069  			if B == 0 {
  2070  				nelem = reg.Top() - RA - 1
  2071  			}
  2072  			for i := 1; i <= nelem; i++ {
  2073  				table.RawSetInt(offset+i, reg.Get(RA+i))
  2074  			}
  2075  			return 0
  2076  		},
  2077  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_CLOSE
  2078  			cf := L.currentFrame
  2079  			lbase := cf.LocalBase
  2080  			A := int(inst>>18) & 0xff // GETA
  2081  			RA := lbase + A
  2082  			// this section is inlined by go-inline
  2083  			// source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go'
  2084  			{
  2085  				ls := L
  2086  				idx := RA
  2087  				if ls.uvcache != nil {
  2088  					var prev *Upvalue
  2089  					for uv := ls.uvcache; uv != nil; uv = uv.next {
  2090  						if uv.index >= idx {
  2091  							if prev != nil {
  2092  								prev.next = nil
  2093  							} else {
  2094  								ls.uvcache = nil
  2095  							}
  2096  							uv.Close()
  2097  						}
  2098  						prev = uv
  2099  					}
  2100  				}
  2101  			}
  2102  			return 0
  2103  		},
  2104  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_CLOSURE
  2105  			reg := L.reg
  2106  			cf := L.currentFrame
  2107  			lbase := cf.LocalBase
  2108  			A := int(inst>>18) & 0xff // GETA
  2109  			RA := lbase + A
  2110  			Bx := int(inst & 0x3ffff) // GETBX
  2111  			proto := cf.Fn.Proto.FunctionPrototypes[Bx]
  2112  			closure := newLFunctionL(proto, cf.Fn.Env, int(proto.NumUpvalues))
  2113  			// this section is inlined by go-inline
  2114  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  2115  			{
  2116  				rg := reg
  2117  				regi := RA
  2118  				vali := closure
  2119  				newSize := regi + 1
  2120  				// this section is inlined by go-inline
  2121  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2122  				{
  2123  					requiredSize := newSize
  2124  					if requiredSize > cap(rg.array) {
  2125  						rg.resize(requiredSize)
  2126  					}
  2127  				}
  2128  				rg.array[regi] = vali
  2129  				if regi >= rg.top {
  2130  					rg.top = regi + 1
  2131  				}
  2132  			}
  2133  			for i := 0; i < int(proto.NumUpvalues); i++ {
  2134  				inst = cf.Fn.Proto.Code[cf.Pc]
  2135  				cf.Pc++
  2136  				B := opGetArgB(inst)
  2137  				switch opGetOpCode(inst) {
  2138  				case OP_MOVE:
  2139  					closure.Upvalues[i] = L.findUpvalue(lbase + B)
  2140  				case OP_GETUPVAL:
  2141  					closure.Upvalues[i] = cf.Fn.Upvalues[B]
  2142  				}
  2143  			}
  2144  			return 0
  2145  		},
  2146  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_VARARG
  2147  			reg := L.reg
  2148  			cf := L.currentFrame
  2149  			lbase := cf.LocalBase
  2150  			A := int(inst>>18) & 0xff // GETA
  2151  			RA := lbase + A
  2152  			B := int(inst & 0x1ff) // GETB
  2153  			nparams := int(cf.Fn.Proto.NumParameters)
  2154  			nvarargs := cf.NArgs - nparams
  2155  			if nvarargs < 0 {
  2156  				nvarargs = 0
  2157  			}
  2158  			nwant := B - 1
  2159  			if B == 0 {
  2160  				nwant = nvarargs
  2161  			}
  2162  			// this section is inlined by go-inline
  2163  			// source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go'
  2164  			{
  2165  				rg := reg
  2166  				regv := RA
  2167  				start := cf.Base + nparams + 1
  2168  				limit := cf.LocalBase
  2169  				n := nwant
  2170  				newSize := regv + n
  2171  				// this section is inlined by go-inline
  2172  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2173  				{
  2174  					requiredSize := newSize
  2175  					if requiredSize > cap(rg.array) {
  2176  						rg.resize(requiredSize)
  2177  					}
  2178  				}
  2179  				if limit == -1 || limit > rg.top {
  2180  					limit = rg.top
  2181  				}
  2182  				for i := 0; i < n; i++ {
  2183  					srcIdx := start + i
  2184  					if srcIdx >= limit || srcIdx < 0 {
  2185  						rg.array[regv+i] = LNil
  2186  					} else {
  2187  						rg.array[regv+i] = rg.array[srcIdx]
  2188  					}
  2189  				}
  2190  
  2191  				// values beyond top don't need to be valid LValues, so setting them to nil is fine
  2192  				// setting them to nil rather than LNil lets us invoke the golang memclr opto
  2193  				oldtop := rg.top
  2194  				rg.top = regv + n
  2195  				if rg.top < oldtop {
  2196  					nilRange := rg.array[rg.top:oldtop]
  2197  					for i := range nilRange {
  2198  						nilRange[i] = nil
  2199  					}
  2200  				}
  2201  			}
  2202  			return 0
  2203  		},
  2204  		func(L *LState, inst uint32, baseframe *callFrame) int { // OP_NOP
  2205  			return 0
  2206  		},
  2207  	}
  2208  }
  2209  
  2210  func opArith(L *LState, inst uint32, baseframe *callFrame) int { // OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_BITOR, OP_MOD, OP_POW
  2211  	reg := L.reg
  2212  	cf := L.currentFrame
  2213  	lbase := cf.LocalBase
  2214  	A := int(inst>>18) & 0xff // GETA
  2215  	RA := lbase + A
  2216  	opcode := int(inst >> 26) // GETOPCODE
  2217  	B := int(inst & 0x1ff)    // GETB
  2218  	C := int(inst>>9) & 0x1ff // GETC
  2219  	lhs := L.rkValue(B)
  2220  	rhs := L.rkValue(C)
  2221  	v1, ok1 := lhs.(LNumber)
  2222  	v2, ok2 := rhs.(LNumber)
  2223  	if ok1 && ok2 {
  2224  		v := numberArith(L, opcode, LNumber(v1), LNumber(v2))
  2225  		// this section is inlined by go-inline
  2226  		// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
  2227  		{
  2228  			rg := reg
  2229  			regi := RA
  2230  			vali := v
  2231  			newSize := regi + 1
  2232  			// this section is inlined by go-inline
  2233  			// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2234  			{
  2235  				requiredSize := newSize
  2236  				if requiredSize > cap(rg.array) {
  2237  					rg.resize(requiredSize)
  2238  				}
  2239  			}
  2240  			rg.array[regi] = rg.alloc.LNumber2I(vali)
  2241  			if regi >= rg.top {
  2242  				rg.top = regi + 1
  2243  			}
  2244  		}
  2245  	} else {
  2246  		v := objectArith(L, opcode, lhs, rhs)
  2247  		// this section is inlined by go-inline
  2248  		// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  2249  		{
  2250  			rg := reg
  2251  			regi := RA
  2252  			vali := v
  2253  			newSize := regi + 1
  2254  			// this section is inlined by go-inline
  2255  			// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2256  			{
  2257  				requiredSize := newSize
  2258  				if requiredSize > cap(rg.array) {
  2259  					rg.resize(requiredSize)
  2260  				}
  2261  			}
  2262  			rg.array[regi] = vali
  2263  			if regi >= rg.top {
  2264  				rg.top = regi + 1
  2265  			}
  2266  		}
  2267  	}
  2268  	return 0
  2269  }
  2270  
  2271  func luaModulo(lhs, rhs LNumber) LNumber {
  2272  	flhs := float64(lhs)
  2273  	frhs := float64(rhs)
  2274  	v := math.Mod(flhs, frhs)
  2275  	if frhs > 0 && v < 0 || frhs < 0 && v > 0 {
  2276  		v += frhs
  2277  	}
  2278  	return LNumber(v)
  2279  }
  2280  
  2281  func numberArith(L *LState, opcode int, lhs, rhs LNumber) LNumber {
  2282  	switch opcode {
  2283  	case OP_ADD:
  2284  		return lhs + rhs
  2285  	case OP_SUB:
  2286  		return lhs - rhs
  2287  	case OP_MUL:
  2288  		return lhs * rhs
  2289  	case OP_DIV:
  2290  		return lhs / rhs
  2291  	case OP_BITOR:
  2292  		return lhs / rhs
  2293  	case OP_MOD:
  2294  		return luaModulo(lhs, rhs)
  2295  	case OP_POW:
  2296  		flhs := float64(lhs)
  2297  		frhs := float64(rhs)
  2298  		return LNumber(math.Pow(flhs, frhs))
  2299  	}
  2300  	panic("should not reach here")
  2301  	return LNumber(0)
  2302  }
  2303  
  2304  func objectArith(L *LState, opcode int, lhs, rhs LValue) LValue {
  2305  	event := ""
  2306  	switch opcode {
  2307  	case OP_ADD:
  2308  		event = "__add"
  2309  	case OP_SUB:
  2310  		event = "__sub"
  2311  	case OP_MUL:
  2312  		event = "__mul"
  2313  	case OP_DIV:
  2314  		event = "__div"
  2315  	case OP_BITOR:
  2316  		event = "__bitor"
  2317  	case OP_MOD:
  2318  		event = "__mod"
  2319  	case OP_POW:
  2320  		event = "__pow"
  2321  	}
  2322  	op := L.metaOp2(lhs, rhs, event)
  2323  	if _, ok := op.(*LFunction); ok {
  2324  		L.reg.Push(op)
  2325  		L.reg.Push(lhs)
  2326  		L.reg.Push(rhs)
  2327  		L.Call(2, 1)
  2328  		return L.reg.Pop()
  2329  	}
  2330  	if str, ok := lhs.(LString); ok {
  2331  		if lnum, err := parseNumber(string(str)); err == nil {
  2332  			lhs = lnum
  2333  		}
  2334  	}
  2335  	if str, ok := rhs.(LString); ok {
  2336  		if rnum, err := parseNumber(string(str)); err == nil {
  2337  			rhs = rnum
  2338  		}
  2339  	}
  2340  	if v1, ok1 := lhs.(LNumber); ok1 {
  2341  		if v2, ok2 := rhs.(LNumber); ok2 {
  2342  			return numberArith(L, opcode, LNumber(v1), LNumber(v2))
  2343  		}
  2344  	}
  2345  	L.RaiseError(fmt.Sprintf("cannot perform %v operation between %v and %v",
  2346  		strings.TrimLeft(event, "_"), lhs.Type().String(), rhs.Type().String()))
  2347  
  2348  	return LNil
  2349  }
  2350  
  2351  func stringConcat(L *LState, total, last int) LValue {
  2352  	rhs := L.reg.Get(last)
  2353  	total--
  2354  	for i := last - 1; total > 0; {
  2355  		lhs := L.reg.Get(i)
  2356  		if !(LVCanConvToString(lhs) && LVCanConvToString(rhs)) {
  2357  			op := L.metaOp2(lhs, rhs, "__concat")
  2358  			if op.Type() == LTFunction {
  2359  				L.reg.Push(op)
  2360  				L.reg.Push(lhs)
  2361  				L.reg.Push(rhs)
  2362  				L.Call(2, 1)
  2363  				rhs = L.reg.Pop()
  2364  				total--
  2365  				i--
  2366  			} else {
  2367  				L.RaiseError("cannot perform concat operation between %v and %v", lhs.Type().String(), rhs.Type().String())
  2368  				return LNil
  2369  			}
  2370  		} else {
  2371  			buf := make([]string, total+1)
  2372  			buf[total] = LVAsString(rhs)
  2373  			for total > 0 {
  2374  				lhs = L.reg.Get(i)
  2375  				if !LVCanConvToString(lhs) {
  2376  					break
  2377  				}
  2378  				buf[total-1] = LVAsString(lhs)
  2379  				i--
  2380  				total--
  2381  			}
  2382  			rhs = LString(strings.Join(buf, ""))
  2383  		}
  2384  	}
  2385  	return rhs
  2386  }
  2387  
  2388  func lessThan(L *LState, lhs, rhs LValue) bool {
  2389  	// optimization for numbers
  2390  	if v1, ok1 := lhs.(LNumber); ok1 {
  2391  		if v2, ok2 := rhs.(LNumber); ok2 {
  2392  			return v1 < v2
  2393  		}
  2394  		L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  2395  	}
  2396  	if lhs.Type() != rhs.Type() {
  2397  		L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  2398  		return false
  2399  	}
  2400  	ret := false
  2401  	switch lhs.Type() {
  2402  	case LTString:
  2403  		ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) < 0
  2404  	default:
  2405  		ret = objectRationalWithError(L, lhs, rhs, "__lt")
  2406  	}
  2407  	return ret
  2408  }
  2409  
  2410  func equals(L *LState, lhs, rhs LValue, raw bool) bool {
  2411  	lt := lhs.Type()
  2412  	if lt != rhs.Type() {
  2413  		return false
  2414  	}
  2415  
  2416  	ret := false
  2417  	switch lt {
  2418  	case LTNil:
  2419  		ret = true
  2420  	case LTNumber:
  2421  		v1, _ := lhs.(LNumber)
  2422  		v2, _ := rhs.(LNumber)
  2423  		ret = v1 == v2
  2424  	case LTBool:
  2425  		ret = bool(lhs.(LBool)) == bool(rhs.(LBool))
  2426  	case LTString:
  2427  		ret = string(lhs.(LString)) == string(rhs.(LString))
  2428  	case LTUserData, LTTable:
  2429  		if lhs == rhs {
  2430  			ret = true
  2431  		} else if !raw {
  2432  			switch objectRational(L, lhs, rhs, "__eq") {
  2433  			case 1:
  2434  				ret = true
  2435  			default:
  2436  				ret = false
  2437  			}
  2438  		}
  2439  	default:
  2440  		ret = lhs == rhs
  2441  	}
  2442  	return ret
  2443  }
  2444  
  2445  func objectRationalWithError(L *LState, lhs, rhs LValue, event string) bool {
  2446  	switch objectRational(L, lhs, rhs, event) {
  2447  	case 1:
  2448  		return true
  2449  	case 0:
  2450  		return false
  2451  	}
  2452  	L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  2453  	return false
  2454  }
  2455  
  2456  func objectRational(L *LState, lhs, rhs LValue, event string) int {
  2457  	m1 := L.metaOp1(lhs, event)
  2458  	m2 := L.metaOp1(rhs, event)
  2459  	if m1.Type() == LTFunction && m1 == m2 {
  2460  		L.reg.Push(m1)
  2461  		L.reg.Push(lhs)
  2462  		L.reg.Push(rhs)
  2463  		L.Call(2, 1)
  2464  		if LVAsBool(L.reg.Pop()) {
  2465  			return 1
  2466  		}
  2467  		return 0
  2468  	}
  2469  	return -1
  2470  }