github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/code/instructions.go (about)

     1  package code
     2  
     3  // Combine encodes r1 <- op(r2, r3)
     4  func Combine(op BinOp, r1, r2, r3 Reg) Opcode {
     5  	return mkType1(op, r1, r2, r3)
     6  }
     7  
     8  // Transform encodes r1 <- op(r2)
     9  func Transform(op UnOp, r1, r2 Reg) Opcode {
    10  	return mkType4a(Off, op, r1, r2)
    11  }
    12  
    13  // LoadConst encodes r <- Ki
    14  func LoadConst(r Reg, i KIndex) Opcode {
    15  	return mkType3(Off, OpK, r, i)
    16  }
    17  
    18  // LoadClosure encodes r <- clos(Ki)
    19  func LoadClosure(r1 Reg, i KIndex) Opcode {
    20  	return mkType3(Off, OpClosureK, r1, i)
    21  }
    22  
    23  // LoadInt16 encodes r <- n
    24  func LoadInt16(r Reg, n int16) Opcode {
    25  	return mkType3(Off, OpInt16, r, Lit16(n))
    26  }
    27  
    28  // LoadSmallInt attempts to load a small integer (atm it has to be representable
    29  // as an int16).
    30  func LoadSmallInt(r Reg, n int) (Opcode, bool) {
    31  	sn := int16(n)
    32  	if int(sn) != n {
    33  		return 0, false
    34  	}
    35  	return LoadInt16(r, sn), true
    36  }
    37  
    38  // LoadStr0 encodes r <- ""
    39  func LoadStr0(r Reg) Opcode {
    40  	return mkType4b(Off, OpStr0, r, 0)
    41  }
    42  
    43  // LoadStr1 encodes r <- "x"
    44  func LoadStr1(r Reg, b []byte) Opcode {
    45  	return mkType4b(Off, OpStr1, r, Lit8FromStr1(b))
    46  }
    47  
    48  // LoadStr2 encodes r <- "xy"
    49  func LoadStr2(r Reg, b []byte) Opcode {
    50  	return mkType3(Off, OpStr2, r, Lit16FromStr2(b))
    51  }
    52  
    53  // LoadShortString attempts to encode loading a short string.  Returns the
    54  // opcode and true if it did.
    55  func LoadShortString(r Reg, b []byte) (Opcode, bool) {
    56  	// This code is commented out because it turns out that it causes many
    57  	// allocations, slowing down the runtime considerably in some cases.
    58  	//
    59  	// switch len(b) {case 0:
    60  	//  return LoadStr0(r), true
    61  	// case 1:
    62  	//  return LoadStr1(r, b), true
    63  	// case 2:
    64  	//  return LoadStr2(r, b), true
    65  	// }
    66  	return 0, false
    67  }
    68  
    69  // LoadBool encodes r <- true or r <- false.
    70  func LoadBool(r Reg, b bool) Opcode {
    71  	return mkType4b(Off, OpBool, r, Lit8FromBool(b))
    72  }
    73  
    74  // LoadEmptyTable encodes r <- {}
    75  func LoadEmptyTable(r Reg) Opcode {
    76  	return mkType4b(Off, OpTable, r, 0)
    77  }
    78  
    79  // LoadNil encodes r <- nil
    80  func LoadNil(r Reg) Opcode {
    81  	return mkType4b(Off, OpNil, r, 0)
    82  }
    83  
    84  // LoadLookup encodes r1 <- r2[r3]
    85  func LoadLookup(r1, r2, r3 Reg) Opcode {
    86  	return mkType2(Off, r1, r2, r3)
    87  }
    88  
    89  // SetIndex encodes r2[r3] <- r1
    90  func SetIndex(r1, r2, r3 Reg) Opcode {
    91  	return mkType2(On, r1, r2, r3)
    92  }
    93  
    94  // Push encodes push r1, r2
    95  //
    96  // r1 must contain a continuation.
    97  func Push(r1, r2 Reg) Opcode {
    98  	return mkType4a(On, OpId, r1, r2)
    99  }
   100  
   101  // PushEtc encodes pushetc r1, ...r2
   102  //
   103  // r1 must contain a continuation, r2 an etc.
   104  func PushEtc(r1, r2 Reg) Opcode {
   105  	return mkType4a(On, OpEtcId, r1, r2)
   106  }
   107  
   108  // Jump encodes an unconditional jump
   109  //
   110  // jump j
   111  func Jump(j Offset) Opcode {
   112  	return mkType5(Off, OpJump, Reg{}, j)
   113  }
   114  
   115  // JumpIf encodes a conditional jump.
   116  //
   117  // jump j if r
   118  func JumpIf(j Offset, r Reg) Opcode {
   119  	return mkType5(On, OpJumpIf, r, j)
   120  }
   121  
   122  // JumpIfNot encodes a conditional jump.
   123  //
   124  // jump j if not r
   125  func JumpIfNot(j Offset, r Reg) Opcode {
   126  	return mkType5(Off, OpJumpIf, r, j)
   127  }
   128  
   129  // Call encodes call r
   130  //
   131  // r must contain a continuation that is ready to be called.
   132  func Call(r Reg) Opcode {
   133  	return mkType5(Off, OpCall, r, Offset(0))
   134  }
   135  
   136  // TailCall encodes tailcall r
   137  //
   138  // r must contain a continuation that is ready to be called.
   139  func TailCall(r Reg) Opcode {
   140  	return mkType5(On, OpCall, r, Offset(0))
   141  }
   142  
   143  // ClTrunc encodes cltrunc h
   144  //
   145  // It truncates the close stack to the given height.  Each value on the close
   146  // stack which is removed should either be nil or false, or be a value with a
   147  // "__close" metamethod, in which case this metamethod is called.  This opcode
   148  // is introduced to support Lua 5.4's "to-be-closed" variables.
   149  func ClTrunc(h uint16) Opcode {
   150  	return mkType5(Off, OpClStack, Reg{}, ClStackOffset(h))
   151  }
   152  
   153  // ClPush encodes clpush r
   154  //
   155  // r should contain either nil, false, or a value with a "__close" metamethod.
   156  // This opcode is introduced to support Lua 5.4's "to-be-closed" variables.
   157  func ClPush(r Reg) Opcode {
   158  	return mkType5(On, OpClStack, r, ClStackOffset(0))
   159  }
   160  
   161  // Upval encodes upval r1, r2
   162  //
   163  // r1 must contain a closure.  This appends the value of r2 to the list of
   164  // upvalues of r1.
   165  func Upval(r1, r2 Reg) Opcode {
   166  	return mkType4a(Off, OpUpvalue, r1, r2)
   167  }
   168  
   169  // Cont encodes r1 <- cont(r2)
   170  //
   171  // r2 must contain a closure, r1 then contains a new continuation for that
   172  // closure, whose next continuation is the cc.
   173  func Cont(r1, r2 Reg) Opcode {
   174  	return mkType4a(Off, OpCont, r1, r2)
   175  }
   176  
   177  // TailCont encodes r1 <- tailcont(r2)
   178  //
   179  // r2 must contain a closure, r1 then contains a new continuatino for that
   180  // closure, whose next continuation is the cc's next continuation.
   181  func TailCont(r1, r2 Reg) Opcode {
   182  	return mkType4a(Off, OpTailCont, r1, r2)
   183  }
   184  
   185  // Clear encodes clear r
   186  //
   187  // This clears the register.  If the register contains a cell, the cell is
   188  // removed, so this is different from r <- nil
   189  func Clear(r Reg) Opcode {
   190  	return mkType4b(Off, OpClear, r, 0)
   191  }
   192  
   193  // Receive encodes recv r
   194  //
   195  // recv r is the pendant of push.
   196  func Receive(r Reg) Opcode {
   197  	return mkType0(Off, r)
   198  }
   199  
   200  // ReceiveEtc encodes recv ...r
   201  //
   202  // accumulates pushes into r (as an Etc)
   203  func ReceiveEtc(r Reg) Opcode {
   204  	return mkType0(On, r)
   205  }
   206  
   207  // LoadEtcLookup encodes r1 <- etclookup(r2, i)
   208  //
   209  // loads the (i + 1)-th element of r2 (as an etc vector) into r1.
   210  func LoadEtcLookup(r1, r2 Reg, i int) Opcode {
   211  	return mkType6(Off, r1, r2, Index8FromInt(i))
   212  }
   213  
   214  // FillTable encodes fill r1, i, r2
   215  //
   216  // This fills the table r1 with all values from r2 (as an etc vector) starting
   217  // from index i.
   218  func FillTable(r1, r2 Reg, i int) Opcode {
   219  	return mkType6(On, r1, r2, Index8FromInt(i))
   220  }
   221  
   222  // PrepForLoop makes sure rStart, rStep, rStop are all numbers and converts
   223  // rStart and rStep to the same numeric type. If the for loop should already
   224  // stop then rStart is set to nil
   225  func PrepForLoop(rStart, rStop, rStep Reg) Opcode {
   226  	return mkType7(Off, rStart, rStop, rStep)
   227  }
   228  
   229  // AdvForLoop increments rStart by rStep, making sure that it doesn't wrap
   230  // around if it is an integer.  If it wraps around then the loop should stop. If
   231  // the loop should stop, rStart is set to nil
   232  func AdvForLoop(rStart, rStop, rStep Reg) Opcode {
   233  	return mkType7(On, rStart, rStop, rStep)
   234  }