|
|
@@ -0,0 +1,138 @@
|
|
|
+// Author: simon
|
|
|
+// Author: ynwdlxm@163.com
|
|
|
+// Date: 2024/4/13 22:53
|
|
|
+// Desc: 操作码 每条指令占4 个字节(32 比特),其中 6 比特用于操作码(Opcode),26 比特用于操作数(Operand)
|
|
|
+// * iABC 模式指令可以携带 A、B、C 三个操作数,分别占用 8、9、9 个比特
|
|
|
+// * iABx 模式指令可以携带 A 和 Bx 两个操作数,分别占用 8 和 18 个比特
|
|
|
+// * iAsBx 模式的指令可以携带 A 和 sBx 两个操作数,分别占用 8 和 18 个比特
|
|
|
+// * iAx 模式的指令中携带一个操作数,占用全部 26 比特
|
|
|
+// * 在 四种模式中,只用 iAsBx 模式下的 sBx 操作数会被解释成有符号整数,其他情况下操作数均被解释成无符号整数
|
|
|
+
|
|
|
+package vm
|
|
|
+
|
|
|
+// op MODE
|
|
|
+const (
|
|
|
+ IABC = iota
|
|
|
+ IABx
|
|
|
+ IAsBx
|
|
|
+ IAx
|
|
|
+)
|
|
|
+
|
|
|
+// Lua 5.3 共定义了 47 条指令,按照作用,
|
|
|
+// 可大致分为 常量加载指令、运算符相关指令、循环和跳转指令、函数调用相关指令、表操作指令以及 Upvalue 操作指令
|
|
|
+const (
|
|
|
+ MOVE = iota
|
|
|
+ LOADK
|
|
|
+ LOADKX
|
|
|
+
|
|
|
+ LOADBOOL
|
|
|
+ LOADNIL
|
|
|
+ GETUPVAL
|
|
|
+ GETTABUP
|
|
|
+ GETTABLE
|
|
|
+ SETTABUP
|
|
|
+ SETUPVAL
|
|
|
+ SETTABLE
|
|
|
+ NEWTABLE
|
|
|
+ SELF
|
|
|
+ ADD
|
|
|
+ SUB
|
|
|
+ MUL
|
|
|
+ MOD
|
|
|
+ POW
|
|
|
+ DIV
|
|
|
+ IDIV
|
|
|
+ BAND
|
|
|
+ BOR
|
|
|
+ BXOR
|
|
|
+ SHL
|
|
|
+ SHR
|
|
|
+ UNM
|
|
|
+ BNOT
|
|
|
+ NOT
|
|
|
+ LEN
|
|
|
+ CONCAT
|
|
|
+ JMP
|
|
|
+ EQ
|
|
|
+ LT
|
|
|
+ LE
|
|
|
+ TEST
|
|
|
+ TESTSET
|
|
|
+ CALL
|
|
|
+ TALLCALL
|
|
|
+ RETURN
|
|
|
+ FORLOOP
|
|
|
+ FORPREP
|
|
|
+ TFORCALL
|
|
|
+ TFORLOOP
|
|
|
+ SETLIST
|
|
|
+ CLOSURE
|
|
|
+ VARARG
|
|
|
+ EXTRAARG
|
|
|
+)
|
|
|
+
|
|
|
+// 操作数
|
|
|
+const (
|
|
|
+ OpArgN = iota // argument is not used
|
|
|
+ OpArgU // argument is used
|
|
|
+ OpArgR // argument is a register or a jump offset
|
|
|
+ OpArgK // argument is a constant or register/constant
|
|
|
+)
|
|
|
+
|
|
|
+type opcode struct {
|
|
|
+ testFlag byte // operator is a test (next instruction must be a jump)
|
|
|
+ setAFlag byte // instruction set register A
|
|
|
+ argBMode byte // B arg mode
|
|
|
+ argCMode byte // C arg mode
|
|
|
+ opMode byte // op mode
|
|
|
+ name string
|
|
|
+}
|
|
|
+
|
|
|
+var opcodes = []opcode{
|
|
|
+ /*testFlag setAFlag argBMode argCMode opMode name */
|
|
|
+ {0, 1, OpArgR, OpArgN, IABC, "MOVE "},
|
|
|
+ {0, 1, OpArgK, OpArgN, IABx, "LOADK "},
|
|
|
+ {0, 1, OpArgN, OpArgN, IABx, "LOADKX "},
|
|
|
+ {0, 1, OpArgU, OpArgU, IABC, "LOADBOOL "},
|
|
|
+ {0, 1, OpArgU, OpArgN, IABC, "LOADNIl "},
|
|
|
+ {0, 1, OpArgU, OpArgN, IABC, "GETUPVAL "},
|
|
|
+ {0, 1, OpArgU, OpArgK, IABC, "GETTABUP "},
|
|
|
+ {0, 1, OpArgR, OpArgK, IABC, "GETTABLE "},
|
|
|
+ {0, 0, OpArgK, OpArgK, IABC, "GETTABUP "},
|
|
|
+ {0, 0, OpArgU, OpArgN, IABC, "SETUPVAL "},
|
|
|
+ {0, 0, OpArgK, OpArgK, IABC, "SETTABLE "},
|
|
|
+ {0, 1, OpArgU, OpArgU, IABC, "NEWTABLE "},
|
|
|
+ {0, 1, OpArgR, OpArgK, IABC, "SELF "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "ADD "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "SUB "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "MUL "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "MOD "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "POW "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "DIV "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "IDIV "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "BAND "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "BOR "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "BXOR "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "SHL "},
|
|
|
+ {0, 1, OpArgK, OpArgK, IABC, "SHR "},
|
|
|
+ {0, 1, OpArgR, OpArgN, IABC, "UNM "},
|
|
|
+ {0, 1, OpArgR, OpArgN, IABC, "BNOT "},
|
|
|
+ {0, 1, OpArgR, OpArgN, IABC, "NOT "},
|
|
|
+ {0, 1, OpArgR, OpArgN, IABC, "LEN "},
|
|
|
+ {0, 1, OpArgR, OpArgR, IABC, "CONCAT "},
|
|
|
+ {0, 0, OpArgR, OpArgN, IAsBx, "JMP "},
|
|
|
+ {1, 0, OpArgK, OpArgK, IABC, "EQ "},
|
|
|
+ {1, 0, OpArgK, OpArgK, IABC, "LT "},
|
|
|
+ {1, 0, OpArgK, OpArgK, IABC, "LE "},
|
|
|
+ {1, 0, OpArgN, OpArgU, IABC, "TEST "},
|
|
|
+ {1, 1, OpArgR, OpArgU, IABC, "TESTSET "},
|
|
|
+ {0, 1, OpArgU, OpArgU, IABC, "CALL "},
|
|
|
+ {0, 1, OpArgU, OpArgU, IABC, "TALLCALL "},
|
|
|
+ {0, 0, OpArgU, OpArgN, IABC, "RETURN "},
|
|
|
+ {0, 1, OpArgR, OpArgN, IAsBx, "FORLOOP "},
|
|
|
+ {0, 1, OpArgR, OpArgN, IAsBx, "FORREEP "},
|
|
|
+ {0, 0, OpArgU, OpArgU, IABC, "SETLIST "},
|
|
|
+ {0, 1, OpArgU, OpArgN, IABx, "CLOSURE "},
|
|
|
+ {0, 1, OpArgU, OpArgN, IABC, "VARARG "},
|
|
|
+ {0, 0, OpArgU, OpArgU, IAx, "EXTRAARG "},
|
|
|
+}
|