github.com/yuin/gopher-lua@v1.1.2-0.20231212122839-2348fd042596/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_MOD
   764  		opArith, // OP_POW
   765  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_UNM
   766  			reg := L.reg
   767  			cf := L.currentFrame
   768  			lbase := cf.LocalBase
   769  			A := int(inst>>18) & 0xff //GETA
   770  			RA := lbase + A
   771  			B := int(inst & 0x1ff) //GETB
   772  			unaryv := L.rkValue(B)
   773  			if nm, ok := unaryv.(LNumber); ok {
   774  				// this section is inlined by go-inline
   775  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   776  				{
   777  					rg := reg
   778  					regi := RA
   779  					vali := -nm
   780  					newSize := regi + 1
   781  					// this section is inlined by go-inline
   782  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   783  					{
   784  						requiredSize := newSize
   785  						if requiredSize > cap(rg.array) {
   786  							rg.resize(requiredSize)
   787  						}
   788  					}
   789  					rg.array[regi] = vali
   790  					if regi >= rg.top {
   791  						rg.top = regi + 1
   792  					}
   793  				}
   794  			} else {
   795  				op := L.metaOp1(unaryv, "__unm")
   796  				if op.Type() == LTFunction {
   797  					reg.Push(op)
   798  					reg.Push(unaryv)
   799  					L.Call(1, 1)
   800  					// this section is inlined by go-inline
   801  					// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   802  					{
   803  						rg := reg
   804  						regi := RA
   805  						vali := reg.Pop()
   806  						newSize := regi + 1
   807  						// this section is inlined by go-inline
   808  						// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   809  						{
   810  							requiredSize := newSize
   811  							if requiredSize > cap(rg.array) {
   812  								rg.resize(requiredSize)
   813  							}
   814  						}
   815  						rg.array[regi] = vali
   816  						if regi >= rg.top {
   817  							rg.top = regi + 1
   818  						}
   819  					}
   820  				} else if str, ok1 := unaryv.(LString); ok1 {
   821  					if num, err := parseNumber(string(str)); err == nil {
   822  						// this section is inlined by go-inline
   823  						// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   824  						{
   825  							rg := reg
   826  							regi := RA
   827  							vali := -num
   828  							newSize := regi + 1
   829  							// this section is inlined by go-inline
   830  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   831  							{
   832  								requiredSize := newSize
   833  								if requiredSize > cap(rg.array) {
   834  									rg.resize(requiredSize)
   835  								}
   836  							}
   837  							rg.array[regi] = vali
   838  							if regi >= rg.top {
   839  								rg.top = regi + 1
   840  							}
   841  						}
   842  					} else {
   843  						L.RaiseError("__unm undefined")
   844  					}
   845  				} else {
   846  					L.RaiseError("__unm undefined")
   847  				}
   848  			}
   849  			return 0
   850  		},
   851  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NOT
   852  			reg := L.reg
   853  			cf := L.currentFrame
   854  			lbase := cf.LocalBase
   855  			A := int(inst>>18) & 0xff //GETA
   856  			RA := lbase + A
   857  			B := int(inst & 0x1ff) //GETB
   858  			if LVIsFalse(reg.Get(lbase + B)) {
   859  				// this section is inlined by go-inline
   860  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   861  				{
   862  					rg := reg
   863  					regi := RA
   864  					vali := LTrue
   865  					newSize := regi + 1
   866  					// this section is inlined by go-inline
   867  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   868  					{
   869  						requiredSize := newSize
   870  						if requiredSize > cap(rg.array) {
   871  							rg.resize(requiredSize)
   872  						}
   873  					}
   874  					rg.array[regi] = vali
   875  					if regi >= rg.top {
   876  						rg.top = regi + 1
   877  					}
   878  				}
   879  			} else {
   880  				// this section is inlined by go-inline
   881  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   882  				{
   883  					rg := reg
   884  					regi := RA
   885  					vali := LFalse
   886  					newSize := regi + 1
   887  					// this section is inlined by go-inline
   888  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   889  					{
   890  						requiredSize := newSize
   891  						if requiredSize > cap(rg.array) {
   892  							rg.resize(requiredSize)
   893  						}
   894  					}
   895  					rg.array[regi] = vali
   896  					if regi >= rg.top {
   897  						rg.top = regi + 1
   898  					}
   899  				}
   900  			}
   901  			return 0
   902  		},
   903  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LEN
   904  			reg := L.reg
   905  			cf := L.currentFrame
   906  			lbase := cf.LocalBase
   907  			A := int(inst>>18) & 0xff //GETA
   908  			RA := lbase + A
   909  			B := int(inst & 0x1ff) //GETB
   910  			switch lv := L.rkValue(B).(type) {
   911  			case LString:
   912  				// this section is inlined by go-inline
   913  				// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
   914  				{
   915  					rg := reg
   916  					regi := RA
   917  					vali := LNumber(len(lv))
   918  					newSize := regi + 1
   919  					// this section is inlined by go-inline
   920  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   921  					{
   922  						requiredSize := newSize
   923  						if requiredSize > cap(rg.array) {
   924  							rg.resize(requiredSize)
   925  						}
   926  					}
   927  					rg.array[regi] = rg.alloc.LNumber2I(vali)
   928  					if regi >= rg.top {
   929  						rg.top = regi + 1
   930  					}
   931  				}
   932  			default:
   933  				op := L.metaOp1(lv, "__len")
   934  				if op.Type() == LTFunction {
   935  					reg.Push(op)
   936  					reg.Push(lv)
   937  					L.Call(1, 1)
   938  					ret := reg.Pop()
   939  					if ret.Type() == LTNumber {
   940  						v, _ := ret.(LNumber)
   941  						// this section is inlined by go-inline
   942  						// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
   943  						{
   944  							rg := reg
   945  							regi := RA
   946  							vali := v
   947  							newSize := regi + 1
   948  							// this section is inlined by go-inline
   949  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   950  							{
   951  								requiredSize := newSize
   952  								if requiredSize > cap(rg.array) {
   953  									rg.resize(requiredSize)
   954  								}
   955  							}
   956  							rg.array[regi] = rg.alloc.LNumber2I(vali)
   957  							if regi >= rg.top {
   958  								rg.top = regi + 1
   959  							}
   960  						}
   961  					} else {
   962  						// this section is inlined by go-inline
   963  						// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
   964  						{
   965  							rg := reg
   966  							regi := RA
   967  							vali := ret
   968  							newSize := regi + 1
   969  							// this section is inlined by go-inline
   970  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   971  							{
   972  								requiredSize := newSize
   973  								if requiredSize > cap(rg.array) {
   974  									rg.resize(requiredSize)
   975  								}
   976  							}
   977  							rg.array[regi] = vali
   978  							if regi >= rg.top {
   979  								rg.top = regi + 1
   980  							}
   981  						}
   982  					}
   983  				} else if lv.Type() == LTTable {
   984  					// this section is inlined by go-inline
   985  					// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
   986  					{
   987  						rg := reg
   988  						regi := RA
   989  						vali := LNumber(lv.(*LTable).Len())
   990  						newSize := regi + 1
   991  						// this section is inlined by go-inline
   992  						// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
   993  						{
   994  							requiredSize := newSize
   995  							if requiredSize > cap(rg.array) {
   996  								rg.resize(requiredSize)
   997  							}
   998  						}
   999  						rg.array[regi] = rg.alloc.LNumber2I(vali)
  1000  						if regi >= rg.top {
  1001  							rg.top = regi + 1
  1002  						}
  1003  					}
  1004  				} else {
  1005  					L.RaiseError("__len undefined")
  1006  				}
  1007  			}
  1008  			return 0
  1009  		},
  1010  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CONCAT
  1011  			reg := L.reg
  1012  			cf := L.currentFrame
  1013  			lbase := cf.LocalBase
  1014  			A := int(inst>>18) & 0xff //GETA
  1015  			RA := lbase + A
  1016  			B := int(inst & 0x1ff)    //GETB
  1017  			C := int(inst>>9) & 0x1ff //GETC
  1018  			RC := lbase + C
  1019  			RB := lbase + B
  1020  			v := stringConcat(L, RC-RB+1, RC)
  1021  			// this section is inlined by go-inline
  1022  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  1023  			{
  1024  				rg := reg
  1025  				regi := RA
  1026  				vali := v
  1027  				newSize := regi + 1
  1028  				// this section is inlined by go-inline
  1029  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1030  				{
  1031  					requiredSize := newSize
  1032  					if requiredSize > cap(rg.array) {
  1033  						rg.resize(requiredSize)
  1034  					}
  1035  				}
  1036  				rg.array[regi] = vali
  1037  				if regi >= rg.top {
  1038  					rg.top = regi + 1
  1039  				}
  1040  			}
  1041  			return 0
  1042  		},
  1043  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_JMP
  1044  			cf := L.currentFrame
  1045  			Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX
  1046  			cf.Pc += Sbx
  1047  			return 0
  1048  		},
  1049  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_EQ
  1050  			cf := L.currentFrame
  1051  			A := int(inst>>18) & 0xff //GETA
  1052  			B := int(inst & 0x1ff)    //GETB
  1053  			C := int(inst>>9) & 0x1ff //GETC
  1054  			ret := equals(L, L.rkValue(B), L.rkValue(C), false)
  1055  			v := 1
  1056  			if ret {
  1057  				v = 0
  1058  			}
  1059  			if v == A {
  1060  				cf.Pc++
  1061  			}
  1062  			return 0
  1063  		},
  1064  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LT
  1065  			cf := L.currentFrame
  1066  			A := int(inst>>18) & 0xff //GETA
  1067  			B := int(inst & 0x1ff)    //GETB
  1068  			C := int(inst>>9) & 0x1ff //GETC
  1069  			ret := lessThan(L, L.rkValue(B), L.rkValue(C))
  1070  			v := 1
  1071  			if ret {
  1072  				v = 0
  1073  			}
  1074  			if v == A {
  1075  				cf.Pc++
  1076  			}
  1077  			return 0
  1078  		},
  1079  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LE
  1080  			cf := L.currentFrame
  1081  			A := int(inst>>18) & 0xff //GETA
  1082  			B := int(inst & 0x1ff)    //GETB
  1083  			C := int(inst>>9) & 0x1ff //GETC
  1084  			lhs := L.rkValue(B)
  1085  			rhs := L.rkValue(C)
  1086  			ret := false
  1087  
  1088  			if v1, ok1 := lhs.(LNumber); ok1 {
  1089  				if v2, ok2 := rhs.(LNumber); ok2 {
  1090  					ret = v1 <= v2
  1091  				} else {
  1092  					L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  1093  				}
  1094  			} else {
  1095  				if lhs.Type() != rhs.Type() {
  1096  					L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  1097  				}
  1098  				switch lhs.Type() {
  1099  				case LTString:
  1100  					ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) <= 0
  1101  				default:
  1102  					switch objectRational(L, lhs, rhs, "__le") {
  1103  					case 1:
  1104  						ret = true
  1105  					case 0:
  1106  						ret = false
  1107  					default:
  1108  						ret = !objectRationalWithError(L, rhs, lhs, "__lt")
  1109  					}
  1110  				}
  1111  			}
  1112  
  1113  			v := 1
  1114  			if ret {
  1115  				v = 0
  1116  			}
  1117  			if v == A {
  1118  				cf.Pc++
  1119  			}
  1120  			return 0
  1121  		},
  1122  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TEST
  1123  			reg := L.reg
  1124  			cf := L.currentFrame
  1125  			lbase := cf.LocalBase
  1126  			A := int(inst>>18) & 0xff //GETA
  1127  			RA := lbase + A
  1128  			C := int(inst>>9) & 0x1ff //GETC
  1129  			if LVAsBool(reg.Get(RA)) == (C == 0) {
  1130  				cf.Pc++
  1131  			}
  1132  			return 0
  1133  		},
  1134  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TESTSET
  1135  			reg := L.reg
  1136  			cf := L.currentFrame
  1137  			lbase := cf.LocalBase
  1138  			A := int(inst>>18) & 0xff //GETA
  1139  			RA := lbase + A
  1140  			B := int(inst & 0x1ff)    //GETB
  1141  			C := int(inst>>9) & 0x1ff //GETC
  1142  			if value := reg.Get(lbase + B); LVAsBool(value) != (C == 0) {
  1143  				// this section is inlined by go-inline
  1144  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  1145  				{
  1146  					rg := reg
  1147  					regi := RA
  1148  					vali := value
  1149  					newSize := regi + 1
  1150  					// this section is inlined by go-inline
  1151  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1152  					{
  1153  						requiredSize := newSize
  1154  						if requiredSize > cap(rg.array) {
  1155  							rg.resize(requiredSize)
  1156  						}
  1157  					}
  1158  					rg.array[regi] = vali
  1159  					if regi >= rg.top {
  1160  						rg.top = regi + 1
  1161  					}
  1162  				}
  1163  			} else {
  1164  				cf.Pc++
  1165  			}
  1166  			return 0
  1167  		},
  1168  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CALL
  1169  			reg := L.reg
  1170  			cf := L.currentFrame
  1171  			lbase := cf.LocalBase
  1172  			A := int(inst>>18) & 0xff //GETA
  1173  			RA := lbase + A
  1174  			B := int(inst & 0x1ff)    //GETB
  1175  			C := int(inst>>9) & 0x1ff //GETC
  1176  			nargs := B - 1
  1177  			if B == 0 {
  1178  				nargs = reg.Top() - (RA + 1)
  1179  			}
  1180  			lv := reg.Get(RA)
  1181  			nret := C - 1
  1182  			var callable *LFunction
  1183  			var meta bool
  1184  			if fn, ok := lv.(*LFunction); ok {
  1185  				callable = fn
  1186  				meta = false
  1187  			} else {
  1188  				callable, meta = L.metaCall(lv)
  1189  			}
  1190  			// this section is inlined by go-inline
  1191  			// source function is 'func (ls *LState) pushCallFrame(cf callFrame, fn LValue, meta bool) ' in '_state.go'
  1192  			{
  1193  				ls := L
  1194  				cf := callFrame{Fn: callable, Pc: 0, Base: RA, LocalBase: RA + 1, ReturnBase: RA, NArgs: nargs, NRet: nret, Parent: cf, TailCall: 0}
  1195  				fn := lv
  1196  				if meta {
  1197  					cf.NArgs++
  1198  					ls.reg.Insert(fn, cf.LocalBase)
  1199  				}
  1200  				if cf.Fn == nil {
  1201  					ls.RaiseError("attempt to call a non-function object")
  1202  				}
  1203  				if ls.stack.IsFull() {
  1204  					ls.RaiseError("stack overflow")
  1205  				}
  1206  				ls.stack.Push(cf)
  1207  				newcf := ls.stack.Last()
  1208  				// this section is inlined by go-inline
  1209  				// source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go'
  1210  				{
  1211  					cf := newcf
  1212  					if cf.Fn.IsG {
  1213  						ls.reg.SetTop(cf.LocalBase + cf.NArgs)
  1214  					} else {
  1215  						proto := cf.Fn.Proto
  1216  						nargs := cf.NArgs
  1217  						np := int(proto.NumParameters)
  1218  						if nargs < np {
  1219  							// default any missing arguments to nil
  1220  							newSize := cf.LocalBase + np
  1221  							// this section is inlined by go-inline
  1222  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1223  							{
  1224  								rg := ls.reg
  1225  								requiredSize := newSize
  1226  								if requiredSize > cap(rg.array) {
  1227  									rg.resize(requiredSize)
  1228  								}
  1229  							}
  1230  							for i := nargs; i < np; i++ {
  1231  								ls.reg.array[cf.LocalBase+i] = LNil
  1232  							}
  1233  							nargs = np
  1234  							ls.reg.top = newSize
  1235  						}
  1236  
  1237  						if (proto.IsVarArg & VarArgIsVarArg) == 0 {
  1238  							if nargs < int(proto.NumUsedRegisters) {
  1239  								nargs = int(proto.NumUsedRegisters)
  1240  							}
  1241  							newSize := cf.LocalBase + nargs
  1242  							// this section is inlined by go-inline
  1243  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1244  							{
  1245  								rg := ls.reg
  1246  								requiredSize := newSize
  1247  								if requiredSize > cap(rg.array) {
  1248  									rg.resize(requiredSize)
  1249  								}
  1250  							}
  1251  							for i := np; i < nargs; i++ {
  1252  								ls.reg.array[cf.LocalBase+i] = LNil
  1253  							}
  1254  							ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters)
  1255  						} else {
  1256  							/* swap vararg positions:
  1257  									   closure
  1258  									   namedparam1 <- lbase
  1259  									   namedparam2
  1260  									   vararg1
  1261  									   vararg2
  1262  
  1263  							           TO
  1264  
  1265  									   closure
  1266  									   nil
  1267  									   nil
  1268  									   vararg1
  1269  									   vararg2
  1270  									   namedparam1 <- lbase
  1271  									   namedparam2
  1272  							*/
  1273  							nvarargs := nargs - np
  1274  							if nvarargs < 0 {
  1275  								nvarargs = 0
  1276  							}
  1277  
  1278  							ls.reg.SetTop(cf.LocalBase + nargs + np)
  1279  							for i := 0; i < np; i++ {
  1280  								//ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i))
  1281  								ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i]
  1282  								//ls.reg.Set(cf.LocalBase+i, LNil)
  1283  								ls.reg.array[cf.LocalBase+i] = LNil
  1284  							}
  1285  
  1286  							if CompatVarArg {
  1287  								ls.reg.SetTop(cf.LocalBase + nargs + np + 1)
  1288  								if (proto.IsVarArg & VarArgNeedsArg) != 0 {
  1289  									argtb := newLTable(nvarargs, 0)
  1290  									for i := 0; i < nvarargs; i++ {
  1291  										argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i))
  1292  									}
  1293  									argtb.RawSetString("n", LNumber(nvarargs))
  1294  									//ls.reg.Set(cf.LocalBase+nargs+np, argtb)
  1295  									ls.reg.array[cf.LocalBase+nargs+np] = argtb
  1296  								} else {
  1297  									ls.reg.array[cf.LocalBase+nargs+np] = LNil
  1298  								}
  1299  							}
  1300  							cf.LocalBase += nargs
  1301  							maxreg := cf.LocalBase + int(proto.NumUsedRegisters)
  1302  							ls.reg.SetTop(maxreg)
  1303  						}
  1304  					}
  1305  				}
  1306  				ls.currentFrame = newcf
  1307  			}
  1308  			if callable.IsG && callGFunction(L, false) {
  1309  				return 1
  1310  			}
  1311  			return 0
  1312  		},
  1313  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TAILCALL
  1314  			reg := L.reg
  1315  			cf := L.currentFrame
  1316  			lbase := cf.LocalBase
  1317  			A := int(inst>>18) & 0xff //GETA
  1318  			RA := lbase + A
  1319  			B := int(inst & 0x1ff) //GETB
  1320  			nargs := B - 1
  1321  			if B == 0 {
  1322  				nargs = reg.Top() - (RA + 1)
  1323  			}
  1324  			lv := reg.Get(RA)
  1325  			var callable *LFunction
  1326  			var meta bool
  1327  			if fn, ok := lv.(*LFunction); ok {
  1328  				callable = fn
  1329  				meta = false
  1330  			} else {
  1331  				callable, meta = L.metaCall(lv)
  1332  			}
  1333  			if callable == nil {
  1334  				L.RaiseError("attempt to call a non-function object")
  1335  			}
  1336  			// this section is inlined by go-inline
  1337  			// source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go'
  1338  			{
  1339  				ls := L
  1340  				idx := lbase
  1341  				if ls.uvcache != nil {
  1342  					var prev *Upvalue
  1343  					for uv := ls.uvcache; uv != nil; uv = uv.next {
  1344  						if uv.index >= idx {
  1345  							if prev != nil {
  1346  								prev.next = nil
  1347  							} else {
  1348  								ls.uvcache = nil
  1349  							}
  1350  							uv.Close()
  1351  						}
  1352  						prev = uv
  1353  					}
  1354  				}
  1355  			}
  1356  			if callable.IsG {
  1357  				luaframe := cf
  1358  				L.pushCallFrame(callFrame{
  1359  					Fn:         callable,
  1360  					Pc:         0,
  1361  					Base:       RA,
  1362  					LocalBase:  RA + 1,
  1363  					ReturnBase: cf.ReturnBase,
  1364  					NArgs:      nargs,
  1365  					NRet:       cf.NRet,
  1366  					Parent:     cf,
  1367  					TailCall:   0,
  1368  				}, lv, meta)
  1369  				if callGFunction(L, true) {
  1370  					return 1
  1371  				}
  1372  				if L.currentFrame == nil || L.currentFrame.Fn.IsG || luaframe == baseframe {
  1373  					return 1
  1374  				}
  1375  			} else {
  1376  				base := cf.Base
  1377  				cf.Fn = callable
  1378  				cf.Pc = 0
  1379  				cf.Base = RA
  1380  				cf.LocalBase = RA + 1
  1381  				cf.ReturnBase = cf.ReturnBase
  1382  				cf.NArgs = nargs
  1383  				cf.NRet = cf.NRet
  1384  				cf.TailCall++
  1385  				lbase := cf.LocalBase
  1386  				if meta {
  1387  					cf.NArgs++
  1388  					L.reg.Insert(lv, cf.LocalBase)
  1389  				}
  1390  				// this section is inlined by go-inline
  1391  				// source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go'
  1392  				{
  1393  					ls := L
  1394  					if cf.Fn.IsG {
  1395  						ls.reg.SetTop(cf.LocalBase + cf.NArgs)
  1396  					} else {
  1397  						proto := cf.Fn.Proto
  1398  						nargs := cf.NArgs
  1399  						np := int(proto.NumParameters)
  1400  						if nargs < np {
  1401  							// default any missing arguments to nil
  1402  							newSize := cf.LocalBase + np
  1403  							// this section is inlined by go-inline
  1404  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1405  							{
  1406  								rg := ls.reg
  1407  								requiredSize := newSize
  1408  								if requiredSize > cap(rg.array) {
  1409  									rg.resize(requiredSize)
  1410  								}
  1411  							}
  1412  							for i := nargs; i < np; i++ {
  1413  								ls.reg.array[cf.LocalBase+i] = LNil
  1414  							}
  1415  							nargs = np
  1416  							ls.reg.top = newSize
  1417  						}
  1418  
  1419  						if (proto.IsVarArg & VarArgIsVarArg) == 0 {
  1420  							if nargs < int(proto.NumUsedRegisters) {
  1421  								nargs = int(proto.NumUsedRegisters)
  1422  							}
  1423  							newSize := cf.LocalBase + nargs
  1424  							// this section is inlined by go-inline
  1425  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1426  							{
  1427  								rg := ls.reg
  1428  								requiredSize := newSize
  1429  								if requiredSize > cap(rg.array) {
  1430  									rg.resize(requiredSize)
  1431  								}
  1432  							}
  1433  							for i := np; i < nargs; i++ {
  1434  								ls.reg.array[cf.LocalBase+i] = LNil
  1435  							}
  1436  							ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters)
  1437  						} else {
  1438  							/* swap vararg positions:
  1439  									   closure
  1440  									   namedparam1 <- lbase
  1441  									   namedparam2
  1442  									   vararg1
  1443  									   vararg2
  1444  
  1445  							           TO
  1446  
  1447  									   closure
  1448  									   nil
  1449  									   nil
  1450  									   vararg1
  1451  									   vararg2
  1452  									   namedparam1 <- lbase
  1453  									   namedparam2
  1454  							*/
  1455  							nvarargs := nargs - np
  1456  							if nvarargs < 0 {
  1457  								nvarargs = 0
  1458  							}
  1459  
  1460  							ls.reg.SetTop(cf.LocalBase + nargs + np)
  1461  							for i := 0; i < np; i++ {
  1462  								//ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i))
  1463  								ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i]
  1464  								//ls.reg.Set(cf.LocalBase+i, LNil)
  1465  								ls.reg.array[cf.LocalBase+i] = LNil
  1466  							}
  1467  
  1468  							if CompatVarArg {
  1469  								ls.reg.SetTop(cf.LocalBase + nargs + np + 1)
  1470  								if (proto.IsVarArg & VarArgNeedsArg) != 0 {
  1471  									argtb := newLTable(nvarargs, 0)
  1472  									for i := 0; i < nvarargs; i++ {
  1473  										argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i))
  1474  									}
  1475  									argtb.RawSetString("n", LNumber(nvarargs))
  1476  									//ls.reg.Set(cf.LocalBase+nargs+np, argtb)
  1477  									ls.reg.array[cf.LocalBase+nargs+np] = argtb
  1478  								} else {
  1479  									ls.reg.array[cf.LocalBase+nargs+np] = LNil
  1480  								}
  1481  							}
  1482  							cf.LocalBase += nargs
  1483  							maxreg := cf.LocalBase + int(proto.NumUsedRegisters)
  1484  							ls.reg.SetTop(maxreg)
  1485  						}
  1486  					}
  1487  				}
  1488  				// this section is inlined by go-inline
  1489  				// source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go'
  1490  				{
  1491  					rg := L.reg
  1492  					regv := base
  1493  					start := RA
  1494  					limit := -1
  1495  					n := reg.Top() - RA - 1
  1496  					newSize := regv + n
  1497  					// this section is inlined by go-inline
  1498  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1499  					{
  1500  						requiredSize := newSize
  1501  						if requiredSize > cap(rg.array) {
  1502  							rg.resize(requiredSize)
  1503  						}
  1504  					}
  1505  					if limit == -1 || limit > rg.top {
  1506  						limit = rg.top
  1507  					}
  1508  					for i := 0; i < n; i++ {
  1509  						srcIdx := start + i
  1510  						if srcIdx >= limit || srcIdx < 0 {
  1511  							rg.array[regv+i] = LNil
  1512  						} else {
  1513  							rg.array[regv+i] = rg.array[srcIdx]
  1514  						}
  1515  					}
  1516  
  1517  					// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1518  					// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1519  					oldtop := rg.top
  1520  					rg.top = regv + n
  1521  					if rg.top < oldtop {
  1522  						nilRange := rg.array[rg.top:oldtop]
  1523  						for i := range nilRange {
  1524  							nilRange[i] = nil
  1525  						}
  1526  					}
  1527  				}
  1528  				cf.Base = base
  1529  				cf.LocalBase = base + (cf.LocalBase - lbase + 1)
  1530  			}
  1531  			return 0
  1532  		},
  1533  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_RETURN
  1534  			reg := L.reg
  1535  			cf := L.currentFrame
  1536  			lbase := cf.LocalBase
  1537  			A := int(inst>>18) & 0xff //GETA
  1538  			RA := lbase + A
  1539  			B := int(inst & 0x1ff) //GETB
  1540  			// this section is inlined by go-inline
  1541  			// source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go'
  1542  			{
  1543  				ls := L
  1544  				idx := lbase
  1545  				if ls.uvcache != nil {
  1546  					var prev *Upvalue
  1547  					for uv := ls.uvcache; uv != nil; uv = uv.next {
  1548  						if uv.index >= idx {
  1549  							if prev != nil {
  1550  								prev.next = nil
  1551  							} else {
  1552  								ls.uvcache = nil
  1553  							}
  1554  							uv.Close()
  1555  						}
  1556  						prev = uv
  1557  					}
  1558  				}
  1559  			}
  1560  			nret := B - 1
  1561  			if B == 0 {
  1562  				nret = reg.Top() - RA
  1563  			}
  1564  			n := cf.NRet
  1565  			if cf.NRet == MultRet {
  1566  				n = nret
  1567  			}
  1568  
  1569  			if L.Parent != nil && L.stack.Sp() == 1 {
  1570  				// this section is inlined by go-inline
  1571  				// source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go'
  1572  				{
  1573  					regv := reg.Top()
  1574  					start := RA
  1575  					b := B
  1576  					if b == 1 {
  1577  						// this section is inlined by go-inline
  1578  						// source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go'
  1579  						{
  1580  							rg := L.reg
  1581  							regm := regv
  1582  							newSize := regm + n
  1583  							// this section is inlined by go-inline
  1584  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1585  							{
  1586  								requiredSize := newSize
  1587  								if requiredSize > cap(rg.array) {
  1588  									rg.resize(requiredSize)
  1589  								}
  1590  							}
  1591  							for i := 0; i < n; i++ {
  1592  								rg.array[regm+i] = LNil
  1593  							}
  1594  							// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1595  							// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1596  							oldtop := rg.top
  1597  							rg.top = regm + n
  1598  							if rg.top < oldtop {
  1599  								nilRange := rg.array[rg.top:oldtop]
  1600  								for i := range nilRange {
  1601  									nilRange[i] = nil
  1602  								}
  1603  							}
  1604  						}
  1605  					} else {
  1606  						// this section is inlined by go-inline
  1607  						// source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go'
  1608  						{
  1609  							rg := L.reg
  1610  							limit := -1
  1611  							newSize := regv + n
  1612  							// this section is inlined by go-inline
  1613  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1614  							{
  1615  								requiredSize := newSize
  1616  								if requiredSize > cap(rg.array) {
  1617  									rg.resize(requiredSize)
  1618  								}
  1619  							}
  1620  							if limit == -1 || limit > rg.top {
  1621  								limit = rg.top
  1622  							}
  1623  							for i := 0; i < n; i++ {
  1624  								srcIdx := start + i
  1625  								if srcIdx >= limit || srcIdx < 0 {
  1626  									rg.array[regv+i] = LNil
  1627  								} else {
  1628  									rg.array[regv+i] = rg.array[srcIdx]
  1629  								}
  1630  							}
  1631  
  1632  							// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1633  							// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1634  							oldtop := rg.top
  1635  							rg.top = regv + n
  1636  							if rg.top < oldtop {
  1637  								nilRange := rg.array[rg.top:oldtop]
  1638  								for i := range nilRange {
  1639  									nilRange[i] = nil
  1640  								}
  1641  							}
  1642  						}
  1643  						if b > 1 && n > (b-1) {
  1644  							// this section is inlined by go-inline
  1645  							// source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go'
  1646  							{
  1647  								rg := L.reg
  1648  								regm := regv + b - 1
  1649  								n := n - (b - 1)
  1650  								newSize := regm + n
  1651  								// this section is inlined by go-inline
  1652  								// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1653  								{
  1654  									requiredSize := newSize
  1655  									if requiredSize > cap(rg.array) {
  1656  										rg.resize(requiredSize)
  1657  									}
  1658  								}
  1659  								for i := 0; i < n; i++ {
  1660  									rg.array[regm+i] = LNil
  1661  								}
  1662  								// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1663  								// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1664  								oldtop := rg.top
  1665  								rg.top = regm + n
  1666  								if rg.top < oldtop {
  1667  									nilRange := rg.array[rg.top:oldtop]
  1668  									for i := range nilRange {
  1669  										nilRange[i] = nil
  1670  									}
  1671  								}
  1672  							}
  1673  						}
  1674  					}
  1675  				}
  1676  				switchToParentThread(L, n, false, true)
  1677  				return 1
  1678  			}
  1679  			islast := baseframe == L.stack.Pop() || L.stack.IsEmpty()
  1680  			// this section is inlined by go-inline
  1681  			// source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go'
  1682  			{
  1683  				regv := cf.ReturnBase
  1684  				start := RA
  1685  				b := B
  1686  				if b == 1 {
  1687  					// this section is inlined by go-inline
  1688  					// source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go'
  1689  					{
  1690  						rg := L.reg
  1691  						regm := regv
  1692  						newSize := regm + n
  1693  						// this section is inlined by go-inline
  1694  						// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1695  						{
  1696  							requiredSize := newSize
  1697  							if requiredSize > cap(rg.array) {
  1698  								rg.resize(requiredSize)
  1699  							}
  1700  						}
  1701  						for i := 0; i < n; i++ {
  1702  							rg.array[regm+i] = LNil
  1703  						}
  1704  						// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1705  						// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1706  						oldtop := rg.top
  1707  						rg.top = regm + n
  1708  						if rg.top < oldtop {
  1709  							nilRange := rg.array[rg.top:oldtop]
  1710  							for i := range nilRange {
  1711  								nilRange[i] = nil
  1712  							}
  1713  						}
  1714  					}
  1715  				} else {
  1716  					// this section is inlined by go-inline
  1717  					// source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go'
  1718  					{
  1719  						rg := L.reg
  1720  						limit := -1
  1721  						newSize := regv + n
  1722  						// this section is inlined by go-inline
  1723  						// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1724  						{
  1725  							requiredSize := newSize
  1726  							if requiredSize > cap(rg.array) {
  1727  								rg.resize(requiredSize)
  1728  							}
  1729  						}
  1730  						if limit == -1 || limit > rg.top {
  1731  							limit = rg.top
  1732  						}
  1733  						for i := 0; i < n; i++ {
  1734  							srcIdx := start + i
  1735  							if srcIdx >= limit || srcIdx < 0 {
  1736  								rg.array[regv+i] = LNil
  1737  							} else {
  1738  								rg.array[regv+i] = rg.array[srcIdx]
  1739  							}
  1740  						}
  1741  
  1742  						// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1743  						// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1744  						oldtop := rg.top
  1745  						rg.top = regv + n
  1746  						if rg.top < oldtop {
  1747  							nilRange := rg.array[rg.top:oldtop]
  1748  							for i := range nilRange {
  1749  								nilRange[i] = nil
  1750  							}
  1751  						}
  1752  					}
  1753  					if b > 1 && n > (b-1) {
  1754  						// this section is inlined by go-inline
  1755  						// source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go'
  1756  						{
  1757  							rg := L.reg
  1758  							regm := regv + b - 1
  1759  							n := n - (b - 1)
  1760  							newSize := regm + n
  1761  							// this section is inlined by go-inline
  1762  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1763  							{
  1764  								requiredSize := newSize
  1765  								if requiredSize > cap(rg.array) {
  1766  									rg.resize(requiredSize)
  1767  								}
  1768  							}
  1769  							for i := 0; i < n; i++ {
  1770  								rg.array[regm+i] = LNil
  1771  							}
  1772  							// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1773  							// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1774  							oldtop := rg.top
  1775  							rg.top = regm + n
  1776  							if rg.top < oldtop {
  1777  								nilRange := rg.array[rg.top:oldtop]
  1778  								for i := range nilRange {
  1779  									nilRange[i] = nil
  1780  								}
  1781  							}
  1782  						}
  1783  					}
  1784  				}
  1785  			}
  1786  			L.currentFrame = L.stack.Last()
  1787  			if islast || L.currentFrame == nil || L.currentFrame.Fn.IsG {
  1788  				return 1
  1789  			}
  1790  			return 0
  1791  		},
  1792  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_FORLOOP
  1793  			reg := L.reg
  1794  			cf := L.currentFrame
  1795  			lbase := cf.LocalBase
  1796  			A := int(inst>>18) & 0xff //GETA
  1797  			RA := lbase + A
  1798  			if init, ok1 := reg.Get(RA).(LNumber); ok1 {
  1799  				if limit, ok2 := reg.Get(RA + 1).(LNumber); ok2 {
  1800  					if step, ok3 := reg.Get(RA + 2).(LNumber); ok3 {
  1801  						init += step
  1802  						v := LNumber(init)
  1803  						// this section is inlined by go-inline
  1804  						// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
  1805  						{
  1806  							rg := reg
  1807  							regi := RA
  1808  							vali := v
  1809  							newSize := regi + 1
  1810  							// this section is inlined by go-inline
  1811  							// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1812  							{
  1813  								requiredSize := newSize
  1814  								if requiredSize > cap(rg.array) {
  1815  									rg.resize(requiredSize)
  1816  								}
  1817  							}
  1818  							rg.array[regi] = rg.alloc.LNumber2I(vali)
  1819  							if regi >= rg.top {
  1820  								rg.top = regi + 1
  1821  							}
  1822  						}
  1823  						if (step > 0 && init <= limit) || (step <= 0 && init >= limit) {
  1824  							Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX
  1825  							cf.Pc += Sbx
  1826  							// this section is inlined by go-inline
  1827  							// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
  1828  							{
  1829  								rg := reg
  1830  								regi := RA + 3
  1831  								vali := v
  1832  								newSize := regi + 1
  1833  								// this section is inlined by go-inline
  1834  								// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1835  								{
  1836  									requiredSize := newSize
  1837  									if requiredSize > cap(rg.array) {
  1838  										rg.resize(requiredSize)
  1839  									}
  1840  								}
  1841  								rg.array[regi] = rg.alloc.LNumber2I(vali)
  1842  								if regi >= rg.top {
  1843  									rg.top = regi + 1
  1844  								}
  1845  							}
  1846  						} else {
  1847  							// this section is inlined by go-inline
  1848  							// source function is 'func (rg *registry) SetTop(topi int) ' in '_state.go'
  1849  							{
  1850  								rg := reg
  1851  								topi := RA + 1
  1852  								// this section is inlined by go-inline
  1853  								// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1854  								{
  1855  									requiredSize := topi
  1856  									if requiredSize > cap(rg.array) {
  1857  										rg.resize(requiredSize)
  1858  									}
  1859  								}
  1860  								oldtopi := rg.top
  1861  								rg.top = topi
  1862  								for i := oldtopi; i < rg.top; i++ {
  1863  									rg.array[i] = LNil
  1864  								}
  1865  								// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1866  								// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1867  								if rg.top < oldtopi {
  1868  									nilRange := rg.array[rg.top:oldtopi]
  1869  									for i := range nilRange {
  1870  										nilRange[i] = nil
  1871  									}
  1872  								}
  1873  								//for i := rg.top; i < oldtop; i++ {
  1874  								//	rg.array[i] = LNil
  1875  								//}
  1876  							}
  1877  						}
  1878  					} else {
  1879  						L.RaiseError("for statement step must be a number")
  1880  					}
  1881  				} else {
  1882  					L.RaiseError("for statement limit must be a number")
  1883  				}
  1884  			} else {
  1885  				L.RaiseError("for statement init must be a number")
  1886  			}
  1887  			return 0
  1888  		},
  1889  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_FORPREP
  1890  			reg := L.reg
  1891  			cf := L.currentFrame
  1892  			lbase := cf.LocalBase
  1893  			A := int(inst>>18) & 0xff //GETA
  1894  			RA := lbase + A
  1895  			Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX
  1896  			if init, ok1 := reg.Get(RA).(LNumber); ok1 {
  1897  				if step, ok2 := reg.Get(RA + 2).(LNumber); ok2 {
  1898  					// this section is inlined by go-inline
  1899  					// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
  1900  					{
  1901  						rg := reg
  1902  						regi := RA
  1903  						vali := LNumber(init - step)
  1904  						newSize := regi + 1
  1905  						// this section is inlined by go-inline
  1906  						// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1907  						{
  1908  							requiredSize := newSize
  1909  							if requiredSize > cap(rg.array) {
  1910  								rg.resize(requiredSize)
  1911  							}
  1912  						}
  1913  						rg.array[regi] = rg.alloc.LNumber2I(vali)
  1914  						if regi >= rg.top {
  1915  							rg.top = regi + 1
  1916  						}
  1917  					}
  1918  				} else {
  1919  					L.RaiseError("for statement step must be a number")
  1920  				}
  1921  			} else {
  1922  				L.RaiseError("for statement init must be a number")
  1923  			}
  1924  			cf.Pc += Sbx
  1925  			return 0
  1926  		},
  1927  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TFORLOOP
  1928  			reg := L.reg
  1929  			cf := L.currentFrame
  1930  			lbase := cf.LocalBase
  1931  			A := int(inst>>18) & 0xff //GETA
  1932  			RA := lbase + A
  1933  			C := int(inst>>9) & 0x1ff //GETC
  1934  			nret := C
  1935  			// this section is inlined by go-inline
  1936  			// source function is 'func (rg *registry) SetTop(topi int) ' in '_state.go'
  1937  			{
  1938  				rg := reg
  1939  				topi := RA + 3 + 2
  1940  				// this section is inlined by go-inline
  1941  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1942  				{
  1943  					requiredSize := topi
  1944  					if requiredSize > cap(rg.array) {
  1945  						rg.resize(requiredSize)
  1946  					}
  1947  				}
  1948  				oldtopi := rg.top
  1949  				rg.top = topi
  1950  				for i := oldtopi; i < rg.top; i++ {
  1951  					rg.array[i] = LNil
  1952  				}
  1953  				// values beyond top don't need to be valid LValues, so setting them to nil is fine
  1954  				// setting them to nil rather than LNil lets us invoke the golang memclr opto
  1955  				if rg.top < oldtopi {
  1956  					nilRange := rg.array[rg.top:oldtopi]
  1957  					for i := range nilRange {
  1958  						nilRange[i] = nil
  1959  					}
  1960  				}
  1961  				//for i := rg.top; i < oldtop; i++ {
  1962  				//	rg.array[i] = LNil
  1963  				//}
  1964  			}
  1965  			// this section is inlined by go-inline
  1966  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  1967  			{
  1968  				rg := reg
  1969  				regi := RA + 3 + 2
  1970  				vali := reg.Get(RA + 2)
  1971  				newSize := regi + 1
  1972  				// this section is inlined by go-inline
  1973  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1974  				{
  1975  					requiredSize := newSize
  1976  					if requiredSize > cap(rg.array) {
  1977  						rg.resize(requiredSize)
  1978  					}
  1979  				}
  1980  				rg.array[regi] = vali
  1981  				if regi >= rg.top {
  1982  					rg.top = regi + 1
  1983  				}
  1984  			}
  1985  			// this section is inlined by go-inline
  1986  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  1987  			{
  1988  				rg := reg
  1989  				regi := RA + 3 + 1
  1990  				vali := reg.Get(RA + 1)
  1991  				newSize := regi + 1
  1992  				// this section is inlined by go-inline
  1993  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  1994  				{
  1995  					requiredSize := newSize
  1996  					if requiredSize > cap(rg.array) {
  1997  						rg.resize(requiredSize)
  1998  					}
  1999  				}
  2000  				rg.array[regi] = vali
  2001  				if regi >= rg.top {
  2002  					rg.top = regi + 1
  2003  				}
  2004  			}
  2005  			// this section is inlined by go-inline
  2006  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  2007  			{
  2008  				rg := reg
  2009  				regi := RA + 3
  2010  				vali := reg.Get(RA)
  2011  				newSize := regi + 1
  2012  				// this section is inlined by go-inline
  2013  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2014  				{
  2015  					requiredSize := newSize
  2016  					if requiredSize > cap(rg.array) {
  2017  						rg.resize(requiredSize)
  2018  					}
  2019  				}
  2020  				rg.array[regi] = vali
  2021  				if regi >= rg.top {
  2022  					rg.top = regi + 1
  2023  				}
  2024  			}
  2025  			L.callR(2, nret, RA+3)
  2026  			if value := reg.Get(RA + 3); value != LNil {
  2027  				// this section is inlined by go-inline
  2028  				// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  2029  				{
  2030  					rg := reg
  2031  					regi := RA + 2
  2032  					vali := value
  2033  					newSize := regi + 1
  2034  					// this section is inlined by go-inline
  2035  					// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2036  					{
  2037  						requiredSize := newSize
  2038  						if requiredSize > cap(rg.array) {
  2039  							rg.resize(requiredSize)
  2040  						}
  2041  					}
  2042  					rg.array[regi] = vali
  2043  					if regi >= rg.top {
  2044  						rg.top = regi + 1
  2045  					}
  2046  				}
  2047  				pc := cf.Fn.Proto.Code[cf.Pc]
  2048  				cf.Pc += int(pc&0x3ffff) - opMaxArgSbx
  2049  			}
  2050  			cf.Pc++
  2051  			return 0
  2052  		},
  2053  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETLIST
  2054  			reg := L.reg
  2055  			cf := L.currentFrame
  2056  			lbase := cf.LocalBase
  2057  			A := int(inst>>18) & 0xff //GETA
  2058  			RA := lbase + A
  2059  			B := int(inst & 0x1ff)    //GETB
  2060  			C := int(inst>>9) & 0x1ff //GETC
  2061  			if C == 0 {
  2062  				C = int(cf.Fn.Proto.Code[cf.Pc])
  2063  				cf.Pc++
  2064  			}
  2065  			offset := (C - 1) * FieldsPerFlush
  2066  			table := reg.Get(RA).(*LTable)
  2067  			nelem := B
  2068  			if B == 0 {
  2069  				nelem = reg.Top() - RA - 1
  2070  			}
  2071  			for i := 1; i <= nelem; i++ {
  2072  				table.RawSetInt(offset+i, reg.Get(RA+i))
  2073  			}
  2074  			return 0
  2075  		},
  2076  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CLOSE
  2077  			cf := L.currentFrame
  2078  			lbase := cf.LocalBase
  2079  			A := int(inst>>18) & 0xff //GETA
  2080  			RA := lbase + A
  2081  			// this section is inlined by go-inline
  2082  			// source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go'
  2083  			{
  2084  				ls := L
  2085  				idx := RA
  2086  				if ls.uvcache != nil {
  2087  					var prev *Upvalue
  2088  					for uv := ls.uvcache; uv != nil; uv = uv.next {
  2089  						if uv.index >= idx {
  2090  							if prev != nil {
  2091  								prev.next = nil
  2092  							} else {
  2093  								ls.uvcache = nil
  2094  							}
  2095  							uv.Close()
  2096  						}
  2097  						prev = uv
  2098  					}
  2099  				}
  2100  			}
  2101  			return 0
  2102  		},
  2103  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CLOSURE
  2104  			reg := L.reg
  2105  			cf := L.currentFrame
  2106  			lbase := cf.LocalBase
  2107  			A := int(inst>>18) & 0xff //GETA
  2108  			RA := lbase + A
  2109  			Bx := int(inst & 0x3ffff) //GETBX
  2110  			proto := cf.Fn.Proto.FunctionPrototypes[Bx]
  2111  			closure := newLFunctionL(proto, cf.Fn.Env, int(proto.NumUpvalues))
  2112  			// this section is inlined by go-inline
  2113  			// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  2114  			{
  2115  				rg := reg
  2116  				regi := RA
  2117  				vali := closure
  2118  				newSize := regi + 1
  2119  				// this section is inlined by go-inline
  2120  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2121  				{
  2122  					requiredSize := newSize
  2123  					if requiredSize > cap(rg.array) {
  2124  						rg.resize(requiredSize)
  2125  					}
  2126  				}
  2127  				rg.array[regi] = vali
  2128  				if regi >= rg.top {
  2129  					rg.top = regi + 1
  2130  				}
  2131  			}
  2132  			for i := 0; i < int(proto.NumUpvalues); i++ {
  2133  				inst = cf.Fn.Proto.Code[cf.Pc]
  2134  				cf.Pc++
  2135  				B := opGetArgB(inst)
  2136  				switch opGetOpCode(inst) {
  2137  				case OP_MOVE:
  2138  					closure.Upvalues[i] = L.findUpvalue(lbase + B)
  2139  				case OP_GETUPVAL:
  2140  					closure.Upvalues[i] = cf.Fn.Upvalues[B]
  2141  				}
  2142  			}
  2143  			return 0
  2144  		},
  2145  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_VARARG
  2146  			reg := L.reg
  2147  			cf := L.currentFrame
  2148  			lbase := cf.LocalBase
  2149  			A := int(inst>>18) & 0xff //GETA
  2150  			RA := lbase + A
  2151  			B := int(inst & 0x1ff) //GETB
  2152  			nparams := int(cf.Fn.Proto.NumParameters)
  2153  			nvarargs := cf.NArgs - nparams
  2154  			if nvarargs < 0 {
  2155  				nvarargs = 0
  2156  			}
  2157  			nwant := B - 1
  2158  			if B == 0 {
  2159  				nwant = nvarargs
  2160  			}
  2161  			// this section is inlined by go-inline
  2162  			// source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go'
  2163  			{
  2164  				rg := reg
  2165  				regv := RA
  2166  				start := cf.Base + nparams + 1
  2167  				limit := cf.LocalBase
  2168  				n := nwant
  2169  				newSize := regv + n
  2170  				// this section is inlined by go-inline
  2171  				// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2172  				{
  2173  					requiredSize := newSize
  2174  					if requiredSize > cap(rg.array) {
  2175  						rg.resize(requiredSize)
  2176  					}
  2177  				}
  2178  				if limit == -1 || limit > rg.top {
  2179  					limit = rg.top
  2180  				}
  2181  				for i := 0; i < n; i++ {
  2182  					srcIdx := start + i
  2183  					if srcIdx >= limit || srcIdx < 0 {
  2184  						rg.array[regv+i] = LNil
  2185  					} else {
  2186  						rg.array[regv+i] = rg.array[srcIdx]
  2187  					}
  2188  				}
  2189  
  2190  				// values beyond top don't need to be valid LValues, so setting them to nil is fine
  2191  				// setting them to nil rather than LNil lets us invoke the golang memclr opto
  2192  				oldtop := rg.top
  2193  				rg.top = regv + n
  2194  				if rg.top < oldtop {
  2195  					nilRange := rg.array[rg.top:oldtop]
  2196  					for i := range nilRange {
  2197  						nilRange[i] = nil
  2198  					}
  2199  				}
  2200  			}
  2201  			return 0
  2202  		},
  2203  		func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NOP
  2204  			return 0
  2205  		},
  2206  	}
  2207  }
  2208  
  2209  func opArith(L *LState, inst uint32, baseframe *callFrame) int { //OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_POW
  2210  	reg := L.reg
  2211  	cf := L.currentFrame
  2212  	lbase := cf.LocalBase
  2213  	A := int(inst>>18) & 0xff //GETA
  2214  	RA := lbase + A
  2215  	opcode := int(inst >> 26) //GETOPCODE
  2216  	B := int(inst & 0x1ff)    //GETB
  2217  	C := int(inst>>9) & 0x1ff //GETC
  2218  	lhs := L.rkValue(B)
  2219  	rhs := L.rkValue(C)
  2220  	v1, ok1 := lhs.(LNumber)
  2221  	v2, ok2 := rhs.(LNumber)
  2222  	if ok1 && ok2 {
  2223  		v := numberArith(L, opcode, LNumber(v1), LNumber(v2))
  2224  		// this section is inlined by go-inline
  2225  		// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
  2226  		{
  2227  			rg := reg
  2228  			regi := RA
  2229  			vali := v
  2230  			newSize := regi + 1
  2231  			// this section is inlined by go-inline
  2232  			// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2233  			{
  2234  				requiredSize := newSize
  2235  				if requiredSize > cap(rg.array) {
  2236  					rg.resize(requiredSize)
  2237  				}
  2238  			}
  2239  			rg.array[regi] = rg.alloc.LNumber2I(vali)
  2240  			if regi >= rg.top {
  2241  				rg.top = regi + 1
  2242  			}
  2243  		}
  2244  	} else {
  2245  		v := objectArith(L, opcode, lhs, rhs)
  2246  		// this section is inlined by go-inline
  2247  		// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
  2248  		{
  2249  			rg := reg
  2250  			regi := RA
  2251  			vali := v
  2252  			newSize := regi + 1
  2253  			// this section is inlined by go-inline
  2254  			// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
  2255  			{
  2256  				requiredSize := newSize
  2257  				if requiredSize > cap(rg.array) {
  2258  					rg.resize(requiredSize)
  2259  				}
  2260  			}
  2261  			rg.array[regi] = vali
  2262  			if regi >= rg.top {
  2263  				rg.top = regi + 1
  2264  			}
  2265  		}
  2266  	}
  2267  	return 0
  2268  }
  2269  
  2270  func luaModulo(lhs, rhs LNumber) LNumber {
  2271  	flhs := float64(lhs)
  2272  	frhs := float64(rhs)
  2273  	v := math.Mod(flhs, frhs)
  2274  	if frhs > 0 && v < 0 || frhs < 0 && v > 0 {
  2275  		v += frhs
  2276  	}
  2277  	return LNumber(v)
  2278  }
  2279  
  2280  func numberArith(L *LState, opcode int, lhs, rhs LNumber) LNumber {
  2281  	switch opcode {
  2282  	case OP_ADD:
  2283  		return lhs + rhs
  2284  	case OP_SUB:
  2285  		return lhs - rhs
  2286  	case OP_MUL:
  2287  		return lhs * rhs
  2288  	case OP_DIV:
  2289  		return lhs / rhs
  2290  	case OP_MOD:
  2291  		return luaModulo(lhs, rhs)
  2292  	case OP_POW:
  2293  		flhs := float64(lhs)
  2294  		frhs := float64(rhs)
  2295  		return LNumber(math.Pow(flhs, frhs))
  2296  	}
  2297  	panic("should not reach here")
  2298  	return LNumber(0)
  2299  }
  2300  
  2301  func objectArith(L *LState, opcode int, lhs, rhs LValue) LValue {
  2302  	event := ""
  2303  	switch opcode {
  2304  	case OP_ADD:
  2305  		event = "__add"
  2306  	case OP_SUB:
  2307  		event = "__sub"
  2308  	case OP_MUL:
  2309  		event = "__mul"
  2310  	case OP_DIV:
  2311  		event = "__div"
  2312  	case OP_MOD:
  2313  		event = "__mod"
  2314  	case OP_POW:
  2315  		event = "__pow"
  2316  	}
  2317  	op := L.metaOp2(lhs, rhs, event)
  2318  	if _, ok := op.(*LFunction); ok {
  2319  		L.reg.Push(op)
  2320  		L.reg.Push(lhs)
  2321  		L.reg.Push(rhs)
  2322  		L.Call(2, 1)
  2323  		return L.reg.Pop()
  2324  	}
  2325  	if str, ok := lhs.(LString); ok {
  2326  		if lnum, err := parseNumber(string(str)); err == nil {
  2327  			lhs = lnum
  2328  		}
  2329  	}
  2330  	if str, ok := rhs.(LString); ok {
  2331  		if rnum, err := parseNumber(string(str)); err == nil {
  2332  			rhs = rnum
  2333  		}
  2334  	}
  2335  	if v1, ok1 := lhs.(LNumber); ok1 {
  2336  		if v2, ok2 := rhs.(LNumber); ok2 {
  2337  			return numberArith(L, opcode, LNumber(v1), LNumber(v2))
  2338  		}
  2339  	}
  2340  	L.RaiseError(fmt.Sprintf("cannot perform %v operation between %v and %v",
  2341  		strings.TrimLeft(event, "_"), lhs.Type().String(), rhs.Type().String()))
  2342  
  2343  	return LNil
  2344  }
  2345  
  2346  func stringConcat(L *LState, total, last int) LValue {
  2347  	rhs := L.reg.Get(last)
  2348  	total--
  2349  	for i := last - 1; total > 0; {
  2350  		lhs := L.reg.Get(i)
  2351  		if !(LVCanConvToString(lhs) && LVCanConvToString(rhs)) {
  2352  			op := L.metaOp2(lhs, rhs, "__concat")
  2353  			if op.Type() == LTFunction {
  2354  				L.reg.Push(op)
  2355  				L.reg.Push(lhs)
  2356  				L.reg.Push(rhs)
  2357  				L.Call(2, 1)
  2358  				rhs = L.reg.Pop()
  2359  				total--
  2360  				i--
  2361  			} else {
  2362  				L.RaiseError("cannot perform concat operation between %v and %v", lhs.Type().String(), rhs.Type().String())
  2363  				return LNil
  2364  			}
  2365  		} else {
  2366  			buf := make([]string, total+1)
  2367  			buf[total] = LVAsString(rhs)
  2368  			for total > 0 {
  2369  				lhs = L.reg.Get(i)
  2370  				if !LVCanConvToString(lhs) {
  2371  					break
  2372  				}
  2373  				buf[total-1] = LVAsString(lhs)
  2374  				i--
  2375  				total--
  2376  			}
  2377  			rhs = LString(strings.Join(buf, ""))
  2378  		}
  2379  	}
  2380  	return rhs
  2381  }
  2382  
  2383  func lessThan(L *LState, lhs, rhs LValue) bool {
  2384  	// optimization for numbers
  2385  	if v1, ok1 := lhs.(LNumber); ok1 {
  2386  		if v2, ok2 := rhs.(LNumber); ok2 {
  2387  			return v1 < v2
  2388  		}
  2389  		L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  2390  	}
  2391  	if lhs.Type() != rhs.Type() {
  2392  		L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  2393  		return false
  2394  	}
  2395  	ret := false
  2396  	switch lhs.Type() {
  2397  	case LTString:
  2398  		ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) < 0
  2399  	default:
  2400  		ret = objectRationalWithError(L, lhs, rhs, "__lt")
  2401  	}
  2402  	return ret
  2403  }
  2404  
  2405  func equals(L *LState, lhs, rhs LValue, raw bool) bool {
  2406  	lt := lhs.Type()
  2407  	if lt != rhs.Type() {
  2408  		return false
  2409  	}
  2410  
  2411  	ret := false
  2412  	switch lt {
  2413  	case LTNil:
  2414  		ret = true
  2415  	case LTNumber:
  2416  		v1, _ := lhs.(LNumber)
  2417  		v2, _ := rhs.(LNumber)
  2418  		ret = v1 == v2
  2419  	case LTBool:
  2420  		ret = bool(lhs.(LBool)) == bool(rhs.(LBool))
  2421  	case LTString:
  2422  		ret = string(lhs.(LString)) == string(rhs.(LString))
  2423  	case LTUserData, LTTable:
  2424  		if lhs == rhs {
  2425  			ret = true
  2426  		} else if !raw {
  2427  			switch objectRational(L, lhs, rhs, "__eq") {
  2428  			case 1:
  2429  				ret = true
  2430  			default:
  2431  				ret = false
  2432  			}
  2433  		}
  2434  	default:
  2435  		ret = lhs == rhs
  2436  	}
  2437  	return ret
  2438  }
  2439  
  2440  func objectRationalWithError(L *LState, lhs, rhs LValue, event string) bool {
  2441  	switch objectRational(L, lhs, rhs, event) {
  2442  	case 1:
  2443  		return true
  2444  	case 0:
  2445  		return false
  2446  	}
  2447  	L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  2448  	return false
  2449  }
  2450  
  2451  func objectRational(L *LState, lhs, rhs LValue, event string) int {
  2452  	m1 := L.metaOp1(lhs, event)
  2453  	m2 := L.metaOp1(rhs, event)
  2454  	if m1.Type() == LTFunction && m1 == m2 {
  2455  		L.reg.Push(m1)
  2456  		L.reg.Push(lhs)
  2457  		L.reg.Push(rhs)
  2458  		L.Call(2, 1)
  2459  		if LVAsBool(L.reg.Pop()) {
  2460  			return 1
  2461  		}
  2462  		return 0
  2463  	}
  2464  	return -1
  2465  }