├── .gitignore ├── README.md ├── com └── nwdxlgzs │ └── xasm │ ├── LocVar.java │ ├── Upvaldesc.java │ ├── Assembler.java │ ├── Proto.java │ ├── Instruction.java │ ├── Dump.java │ ├── Undump.java │ ├── OPCode.java │ ├── Parser.java │ ├── TValue.java │ ├── bindInst.java │ ├── defines.java │ ├── Lexer.java │ └── Disassembler.java └── LICENSE.md /.gitignore: -------------------------------------------------------------------------------- 1 | /com/dingyi 2 | /com/nwdxlgzs/* 3 | !/com/nwdxlgzs/xasm/ 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Xasm 2 | 一个适用于Androlua+(Lua53)的反汇编器。汇编器以后再说。 3 | 4 | # 协议:基于CC-BY-NC-SA-4.0(LICENSE.md)并如下调整 5 | 署名:允许他人对享有著作权的作品及演绎作品进行复制、运行、放映、广播或通过信息网络向公众传播,但在这些过程中对方必须保留对原作品的署名。 6 | 7 | 非商业性使用:允许他人对享有著作权的作品及演绎作品进行复制、运行、放映、广播或通过信息网络向公众传播,但仅限于非商业性目的。 8 | 9 | 禁止演绎:允许他人对作品原封不动地进行复制、运行、放映、广播或通过信息网络向公众传播,但不得进行演绎创作。 10 | 11 | 授权制:经过分享,修改方案改进的使用经过同意的,允许在修改的基础之上进行上述活动。 12 | 13 | 开发限定:只允许用于分析字节码的工具,不可用于字节码混淆等类似功能的应用,如果开发需要提交并通知作者后核查是否可以被授权(包括但不限于被授权人的软件提供的批处理程序接口脚本等)。 14 | 15 | >(特别的,授权寒歌、泥人、dingyi为MIT规则,但他人继续fork仍然需要遵守本规则)。 16 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/LocVar.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | import java.io.Serializable; 4 | 5 | public class LocVar implements Serializable { 6 | public TValue varname = TValue.NIL; 7 | public int startpc = 0; 8 | public int endpc = 0; 9 | 10 | public LocVar() { 11 | } 12 | 13 | @Override 14 | public String toString() { 15 | return "LocVar{" + "\n" + 16 | "varname=" + varname + "\n" + 17 | ", startpc=" + startpc + "\n" + 18 | ", endpc=" + endpc + "\n" + 19 | '}'; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/Upvaldesc.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | import java.io.Serializable; 4 | 5 | public class Upvaldesc implements Serializable { 6 | public TValue name = TValue.NIL; 7 | public boolean instack = true; 8 | public short idx = 0;//实际是byte,但是这傻逼signed,只好用更大范围的short了 9 | 10 | public Upvaldesc() { 11 | } 12 | 13 | @Override 14 | public String toString() { 15 | return "Upvaldesc{" + "\n" + 16 | "name=" + name + "\n" + 17 | ", instack=" + instack + "\n" + 18 | ", idx=" + idx + "\n" + 19 | '}'; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/Assembler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Xasm汇编文件结构: 3 | * 1:.function到.end之间为一个函数原型 4 | * 2:.function后跟索引路径,根为main,索引路径用/分割,如main/0/1/2 5 | * 3:.sub-parse 是否这个汇编文件也解析了目标函数子函数 6 | * 4:.source 对应Proto的source,nil表示没有 7 | * 5:.is_vararg/.maxstacksize/.numparams/.linedefined/.lastlinedefined 对应Proto的is_vararg/maxstacksize/numparams/linedefined/lastlinedefined 8 | * 6:sizep/sizek/sizecode/sizeupvalues/sizelineinfo/sizelocvars等不使用,根据解析内容自动回补 9 | * 7:.locvars -> 对应Proto的locvars,第一个string为name(可以是nil),第二个int为startpc,第三个int为endpc 10 | * 8:.upvaldesc 对应Proto的upvalues,第一个string为name(可以是nil),第一个int为idx,第一个bool为instack 11 | * 9:.code-start到.code-end为一个块,块内只允许指令数据或者.line 或者.goto_XX存在 12 | * 10:.line 对应Proto的lineinfo,int为行号(特别的,0不会显示,上一次的line和本次一致也会不显示) 13 | * 11:.goto_XX是辅助表示跳转指令的跳转目的地 14 | * 12:每个指令表示结构并不完全一样,请看case分支处注释。 15 | * 13:字符串转义规则:\t\n\b\f\"\r\\\0,\xXX表示16进制字符 16 | */ 17 | package com.nwdxlgzs.xasm; 18 | 19 | import static com.nwdxlgzs.xasm.TValue.*; 20 | import static com.nwdxlgzs.xasm.defines.*; 21 | 22 | public class Assembler { 23 | private final CharSequence source; 24 | 25 | 26 | public Assembler(CharSequence source) { 27 | this.source = source; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/Proto.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | 4 | import java.io.Serializable; 5 | 6 | import static com.nwdxlgzs.xasm.defines.*; 7 | 8 | public class Proto implements Serializable { 9 | public String XasmFuncName;//.function XX中的XX 10 | public byte numparams = 0; 11 | public byte is_vararg = 0; 12 | public byte maxstacksize = 0; 13 | public int linedefined = 0; 14 | public int lastlinedefined = 0; 15 | public TValue[] k = null; 16 | public Instruction[] code = null; 17 | public Proto[] p = null; 18 | public Integer[] lineinfo = null; 19 | public LocVar[] locvars = null; 20 | public Upvaldesc[] upvalues = null; 21 | public TValue source = TValue.NIL; 22 | 23 | public int sizeupvalues() { 24 | return upvalues == null ? 0 : upvalues.length; 25 | } 26 | 27 | public void sizeupvalues(int newsize) { 28 | upvalues = realloc(upvalues, newsize); 29 | } 30 | 31 | public int sizek() { 32 | return k == null ? 0 : k.length; 33 | } 34 | 35 | public void sizek(int newsize) { 36 | k = realloc(k, newsize); 37 | } 38 | 39 | public int sizecode() { 40 | return code == null ? 0 : code.length; 41 | } 42 | 43 | public void sizecode(int newsize) { 44 | code = realloc(code, newsize); 45 | } 46 | 47 | public int sizelineinfo() { 48 | return lineinfo == null ? 0 : lineinfo.length; 49 | } 50 | 51 | public void sizelineinfo(int newsize) { 52 | lineinfo = realloc(lineinfo, newsize); 53 | } 54 | 55 | public int sizep() { 56 | return p == null ? 0 : p.length; 57 | } 58 | 59 | public void sizep(int newsize) { 60 | p = realloc(p, newsize); 61 | } 62 | 63 | public int sizelocvars() { 64 | return locvars == null ? 0 : locvars.length; 65 | } 66 | 67 | public void sizelocvars(int newsize) { 68 | locvars = realloc(locvars, newsize); 69 | } 70 | 71 | public Proto() { 72 | } 73 | 74 | public Proto findSub(String path) { 75 | if (path == null || path.isEmpty() || "main".equals(path)) return this; 76 | if (path.startsWith("main/")) path = path.substring(5); 77 | if (path.startsWith("/")) path = path.substring(1); 78 | String[] split = path.split("/"); 79 | Proto f = this; 80 | for (String s : split) { 81 | int index = Integer.parseInt(s); 82 | if (index < 0 || index >= f.sizep()) return null; 83 | f = f.p[index]; 84 | } 85 | if (f == this) return null; 86 | return f; 87 | } 88 | 89 | @Override 90 | public String toString() { 91 | StringBuilder sb = new StringBuilder(); 92 | sb.append("Proto{ ").append(XasmFuncName == null ? "" : XasmFuncName).append("\n") 93 | .append(" numparams=").append(numparams).append("\n") 94 | .append(", is_vararg=").append(is_vararg).append("\n") 95 | .append(", maxstacksize=").append(maxstacksize).append("\n") 96 | .append(", sizeupvalues=").append(sizeupvalues()).append("\n") 97 | .append(", sizek=").append(sizek()).append("\n") 98 | .append(", sizecode=").append(sizecode()).append("\n") 99 | .append(", sizelineinfo=").append(sizelineinfo()).append("\n") 100 | .append(", sizep=").append(sizep()).append("\n") 101 | .append(", sizelocvars=").append(sizelocvars()).append("\n") 102 | .append(", linedefined=").append(linedefined).append("\n") 103 | .append(", lastlinedefined=").append(lastlinedefined).append("\n"); 104 | sb.append(", k="); 105 | if (k != null) { 106 | sb.append("[" + "\n"); 107 | for (TValue tValue : k) { 108 | sb.append(tValue).append(",\n"); 109 | } 110 | sb.append("]" + "\n"); 111 | } else { 112 | sb.append("null" + "\n"); 113 | } 114 | sb.append(", code="); 115 | if (code != null) { 116 | sb.append("[" + "\n"); 117 | for (Instruction instruction : code) { 118 | sb.append(instruction).append(",\n"); 119 | } 120 | sb.append("]" + "\n"); 121 | } else { 122 | sb.append("null" + "\n"); 123 | } 124 | sb.append(", p="); 125 | if (p != null) { 126 | sb.append("[" + "\n"); 127 | for (Proto proto : p) { 128 | sb.append(proto).append(",\n"); 129 | } 130 | sb.append("]" + "\n"); 131 | } else { 132 | sb.append("null" + "\n"); 133 | } 134 | sb.append(", lineinfo="); 135 | if (lineinfo != null) { 136 | sb.append("[" + "\n"); 137 | for (Integer integer : lineinfo) { 138 | sb.append(integer).append(",\n"); 139 | } 140 | sb.append("]" + "\n"); 141 | } else { 142 | sb.append("null" + "\n"); 143 | } 144 | sb.append(", locvars="); 145 | if (locvars != null) { 146 | sb.append("[" + "\n"); 147 | for (LocVar locVar : locvars) { 148 | sb.append(locVar).append(",\n"); 149 | } 150 | sb.append("]" + "\n"); 151 | } else { 152 | sb.append("null" + "\n"); 153 | } 154 | sb.append(", upvalues="); 155 | if (upvalues != null) { 156 | sb.append("[" + "\n"); 157 | for (Upvaldesc upvaldesc : upvalues) { 158 | sb.append(upvaldesc).append(",\n"); 159 | } 160 | sb.append("]" + "\n"); 161 | } else { 162 | sb.append("null" + "\n"); 163 | } 164 | sb.append(", source=").append(source).append("\n") 165 | .append('}'); 166 | return sb.toString(); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/Instruction.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | import static com.nwdxlgzs.xasm.defines.*; 4 | 5 | import java.io.Serializable; 6 | 7 | public class Instruction implements Serializable { 8 | private int value = 0; 9 | //下方几个辅助汇编用的,不是Instruction该有的信息,toString我就不处理了 10 | public boolean isCanJump2There = false; 11 | public boolean isRealFake = false; 12 | public boolean isStartRealFake = false; 13 | public boolean isEndRealFake = false; 14 | 15 | public Instruction(int instruction) { 16 | value = instruction; 17 | } 18 | 19 | public OPCode getOpCode() { 20 | return OPCode.fromValue(opcode()); 21 | } 22 | 23 | public OPCode.OpMode getOpMode() { 24 | return getOpCode().getMode(); 25 | } 26 | 27 | public OPCode.OpArgMask getOpArgB() { 28 | return getOpCode().getB(); 29 | } 30 | 31 | public OPCode.OpArgMask getOpArgC() { 32 | return getOpCode().getC(); 33 | } 34 | 35 | /* 36 | * 下方是设置和获取的方法 37 | */ 38 | public int opcode() { 39 | return GET_OPCODE(value); 40 | } 41 | 42 | public void opcode(int opcode) { 43 | value = SET_OPCODE(value, opcode); 44 | } 45 | 46 | public int A() { 47 | return GETARG_A(value); 48 | } 49 | 50 | public void A(int a) { 51 | value = SETARG_A(value, a); 52 | } 53 | 54 | public int B() { 55 | return GETARG_B(value); 56 | } 57 | 58 | public void B(int b) { 59 | value = SETARG_B(value, b); 60 | } 61 | 62 | public int C() { 63 | return GETARG_C(value); 64 | } 65 | 66 | public void C(int c) { 67 | value = SETARG_C(value, c); 68 | } 69 | 70 | public int Bx() { 71 | return GETARG_Bx(value); 72 | } 73 | 74 | public void Bx(int bx) { 75 | value = SETARG_Bx(value, bx); 76 | } 77 | 78 | public int sBx() { 79 | return GETARG_sBx(value); 80 | } 81 | 82 | public void sBx(int sbx) { 83 | value = SETARG_sBx(value, sbx); 84 | } 85 | 86 | public int Ax() { 87 | return GETARG_Ax(value); 88 | } 89 | 90 | public void Ax(int ax) { 91 | value = SETARG_Ax(value, ax); 92 | } 93 | 94 | public int value() { 95 | return value; 96 | } 97 | 98 | public void value(int value) { 99 | this.value = value; 100 | } 101 | 102 | @Override 103 | public String toString() { 104 | int A = 0; 105 | int B = 0; 106 | int C = 0; 107 | int Bx = 0; 108 | int sBx = 0; 109 | int Ax = 0; 110 | int opcode = GET_OPCODE(value); 111 | OPCode opName = OPCode.fromValue(opcode); 112 | switch (opName.getMode()) { 113 | case iABC: { 114 | A = GETARG_A(value); 115 | B = GETARG_B(value); 116 | C = GETARG_C(value); 117 | break; 118 | } 119 | case iABx: { 120 | A = GETARG_A(value); 121 | Bx = GETARG_Bx(value); 122 | break; 123 | } 124 | case iAsBx: { 125 | A = GETARG_A(value); 126 | sBx = GETARG_sBx(value); 127 | break; 128 | } 129 | case iAx: { 130 | Ax = GETARG_Ax(value); 131 | break; 132 | } 133 | default: { 134 | A = GETARG_A(value); 135 | B = GETARG_B(value); 136 | C = GETARG_C(value); 137 | Bx = GETARG_Bx(value); 138 | sBx = GETARG_sBx(value); 139 | Ax = GETARG_Ax(value); 140 | break; 141 | } 142 | } 143 | switch (opName.getMode()) { 144 | case iABC: { 145 | return "Instruction{" + "\n" + 146 | "value=" + value + "\n" + 147 | ", opcode=" + opcode + "\n" + 148 | ", opName=" + opName + "\n" + 149 | ", A=" + A + "\n" + 150 | ", B=" + B + "\n" + 151 | ", C=" + C + "\n" + 152 | '}'; 153 | } 154 | case iABx: { 155 | return "Instruction{" + "\n" + 156 | "value=" + value + "\n" + 157 | ", opcode=" + opcode + "\n" + 158 | ", opName=" + opName + "\n" + 159 | ", A=" + A + "\n" + 160 | ", Bx=" + Bx + "\n" + 161 | '}'; 162 | } 163 | case iAsBx: { 164 | return "Instruction{" + "\n" + 165 | "value=" + value + "\n" + 166 | ", opcode=" + opcode + "\n" + 167 | ", opName=" + opName + "\n" + 168 | ", A=" + A + "\n" + 169 | ", sBx=" + sBx + "\n" + 170 | '}'; 171 | } 172 | case iAx: { 173 | return "Instruction{" + "\n" + 174 | "value=" + value + "\n" + 175 | ", opcode=" + opcode + "\n" + 176 | ", opName=" + opName + "\n" + 177 | ", Ax=" + Ax + "\n" + 178 | '}'; 179 | } 180 | default: { 181 | return "Instruction{" + "\n" + 182 | "value=" + value + "\n" + 183 | ", opcode=" + opcode + "\n" + 184 | ", opName=" + opName + "\n" + 185 | ", A=" + A + "\n" + 186 | ", B=" + B + "\n" + 187 | ", C=" + C + "\n" + 188 | ", Bx=" + Bx + "\n" + 189 | ", sBx=" + sBx + "\n" + 190 | ", Ax=" + Ax + "\n" + 191 | '}'; 192 | } 193 | } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/Dump.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | import static com.nwdxlgzs.xasm.TValue.*; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.IOException; 7 | 8 | public class Dump extends defines { 9 | private boolean strip; 10 | private Proto proto; 11 | private ByteArrayOutputStream stream; 12 | 13 | 14 | public Dump(Proto proto, boolean strip) { 15 | this.proto = proto; 16 | this.strip = strip; 17 | } 18 | 19 | private void writeHeader() throws IOException { 20 | writeLiteral(LUA_SIGNATURE); 21 | writeByte(LUAC_VERSION[0]); 22 | writeByte(LUAC_FORMAT[0]); 23 | writeLiteral(LUAC_DATA); 24 | writeByte((byte) sizeof_int); 25 | writeByte((byte) sizeof_size_t); 26 | writeByte((byte) sizeof_Instruction); 27 | writeByte((byte) sizeof_lua_Integer); 28 | writeByte((byte) sizeof_lua_Number); 29 | writeLiteral(LUAC_INT);// 0x5678 30 | writeLiteral(LUAC_NUM);// 370.5 31 | } 32 | 33 | private void writeCode(Proto f) throws IOException { 34 | int sizecode = f.sizecode(); 35 | writeInt(sizecode); 36 | for (int i = 0; i < sizecode; i++) { 37 | writeInstruction(f.code[i]); 38 | } 39 | } 40 | 41 | private void writeConstants(Proto f) throws IOException { 42 | int sizek = f.sizek(); 43 | writeInt(sizek); 44 | for (int i = 0; i < sizek; i++) { 45 | TValue o = f.k[i]; 46 | writeByte((byte) o.tt_); 47 | switch (o.tt_) { 48 | case LUA_TNIL: 49 | break; 50 | case LUA_TBOOLEAN: 51 | writeByte((byte) (o.getBoolean() ? 1 : 0)); 52 | break; 53 | case LUA_TNUMFLT: 54 | writeNumber(o.getFLT()); 55 | break; 56 | case LUA_TNUMINT: 57 | writeInteger(o.getINT()); 58 | break; 59 | case LUA_TSHRSTR: 60 | case LUA_TLNGSTR: 61 | writeString(o); 62 | break; 63 | default: 64 | // throw new RuntimeException("无效的常量类型"); 65 | break; 66 | } 67 | } 68 | } 69 | 70 | private void writeProtos(Proto f) throws IOException { 71 | int sizep = f.sizep(); 72 | writeInt(sizep); 73 | for (int i = 0; i < sizep; i++) { 74 | writeFunction(f.p[i], f.source); 75 | } 76 | } 77 | 78 | private void writeUpvalues(Proto f) throws IOException { 79 | int sizeupvalues = f.sizeupvalues(); 80 | writeInt(sizeupvalues); 81 | for (int i = 0; i < sizeupvalues; i++) { 82 | Upvaldesc uv = f.upvalues[i]; 83 | writeByte((byte) (uv.instack ? 1 : 0)); 84 | writeByte((byte) uv.idx); 85 | } 86 | } 87 | 88 | private void writeDebug(Proto f) throws IOException { 89 | if (strip) { 90 | writeInt(0); 91 | writeInt(0); 92 | writeInt(0); 93 | } else { 94 | int sizelineinfo = f.sizelineinfo(); 95 | writeInt(sizelineinfo); 96 | for (int i = 0; i < sizelineinfo; i++) { 97 | writeInt(f.lineinfo[i]); 98 | } 99 | int sizelocvars = f.sizelocvars(); 100 | writeInt(sizelocvars); 101 | for (int i = 0; i < sizelocvars; i++) { 102 | LocVar lv = f.locvars[i]; 103 | writeString(lv.varname); 104 | writeInt(lv.startpc); 105 | writeInt(lv.endpc); 106 | } 107 | int sizeupvalues = f.sizeupvalues(); 108 | writeInt(sizeupvalues); 109 | for (int i = 0; i < sizeupvalues; i++) { 110 | Upvaldesc uv = f.upvalues[i]; 111 | writeString(uv.name); 112 | } 113 | } 114 | } 115 | 116 | private void writeFunction(Proto f, TValue source) throws IOException { 117 | if (strip || f.source == null || f.source.equals(source)) { 118 | writeString(NIL); 119 | } else { 120 | writeString(f.source); 121 | } 122 | writeInt(f.linedefined); 123 | writeInt(f.lastlinedefined); 124 | writeByte(f.numparams); 125 | writeByte(f.is_vararg); 126 | writeByte(f.maxstacksize); 127 | writeCode(f); 128 | writeConstants(f); 129 | writeUpvalues(f); 130 | writeProtos(f); 131 | writeDebug(f); 132 | } 133 | 134 | public byte[] dump() throws IOException { 135 | // try { 136 | stream = new ByteArrayOutputStream(); 137 | writeHeader(); 138 | writeByte((byte) (proto.sizeupvalues() & 0xFF)); 139 | writeFunction(proto, NIL); 140 | byte[] ret = stream.toByteArray(); 141 | stream.close(); 142 | return ret; 143 | // } catch (Throwable e) { 144 | // StringBuilder sb = new StringBuilder(); 145 | // sb.append(e.getMessage()).append("\n"); 146 | // for (StackTraceElement stackTraceElement : e.getStackTrace()) { 147 | // sb.append(stackTraceElement.toString()).append("\n"); 148 | // } 149 | // throw new RuntimeException(sb.toString()); 150 | // } 151 | } 152 | 153 | private void writeByte(byte b) { 154 | stream.write(b); 155 | } 156 | 157 | private void writeLiteral(String s) throws IOException { 158 | writeLiteral(s.getBytes()); 159 | } 160 | 161 | private void writeLiteral(byte[] s) throws IOException { 162 | stream.write(s); 163 | } 164 | 165 | private void writeInt(int x) throws IOException { 166 | byte[] b = int2bytes(x); 167 | stream.write(b); 168 | } 169 | 170 | private void writeNumber(double x) throws IOException { 171 | byte[] b = FLT2bytes(x); 172 | stream.write(b); 173 | } 174 | 175 | private void writeInteger(long x) throws IOException { 176 | byte[] b = INT2bytes(x); 177 | stream.write(b); 178 | } 179 | 180 | private void writeString(TValue o) throws IOException { 181 | if (o == null || o == TValue.NIL || o.tt_ == LUA_TNIL) { 182 | writeByte((byte) 0); 183 | return; 184 | } 185 | byte[] bytes = o.getStringBytes(); 186 | int size = bytes.length + 1;//加上尾0 187 | if (size < 0xFF) { 188 | writeByte((byte) size); 189 | } else { 190 | writeByte((byte) 0xFF); 191 | writeInt(size); 192 | } 193 | writeLiteral(bytes); 194 | } 195 | 196 | private void writeInstruction(Instruction i) throws IOException { 197 | int x = i.value(); 198 | byte[] b = Instruction2bytes(x); 199 | stream.write(b); 200 | } 201 | 202 | } 203 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/Undump.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | import java.io.FileNotFoundException; 4 | import java.io.FileOutputStream; 5 | import java.lang.reflect.Array; 6 | import java.util.Arrays; 7 | import java.util.Collections; 8 | import java.util.HashMap; 9 | 10 | public class Undump extends defines { 11 | private byte[] data; 12 | private int pos; 13 | 14 | public Undump(byte[] data) { 15 | this.data = data; 16 | this.pos = 0; 17 | } 18 | 19 | private byte[] readBlock(int size) { 20 | if (pos + size > data.length) { 21 | if (pos + size > data.length + 1024 * 256) {//VirtualMemorySize虚拟扩容,包装读取正常(C的Lua会内存溢出去读,通常在malloc块没有报错) 22 | throw new RuntimeException("读取数据溢出!企图从" + pos + "读取长度为" + size + 23 | "的数据(已经溢出),但是实际数据长度为" + data.length + ",虚拟扩容为256KB"); 24 | } else { 25 | byte[] block = new byte[size]; 26 | System.arraycopy(data, pos, block, 0, data.length - pos); 27 | pos = data.length; 28 | return block; 29 | } 30 | } else { 31 | byte[] block = new byte[size]; 32 | System.arraycopy(data, pos, block, 0, size); 33 | pos += size; 34 | return block; 35 | } 36 | } 37 | 38 | private void readHeader() { 39 | byte[] buff_temp; 40 | buff_temp = readBlock(LUA_SIGNATURE.length); 41 | int i; 42 | for (i = 0; i < LUA_SIGNATURE.length; i++) { 43 | if (buff_temp[i] != LUA_SIGNATURE[i]) { 44 | throw new RuntimeException("不是一个LuaC文件!LuaC头部错误!头部应为" + Collections.singletonList(LUA_SIGNATURE) + ",但是读取到的头部为" + Collections.singletonList(buff_temp)); 45 | } 46 | } 47 | if (readByte() != LUAC_VERSION[0]) { 48 | throw new RuntimeException("在LuaC文件中丢失版本匹配"); 49 | } 50 | if (readByte() != LUAC_FORMAT[0]) { 51 | throw new RuntimeException("在LuaC文件中丢失格式匹配"); 52 | } 53 | buff_temp = readBlock(LUAC_DATA.length); 54 | for (i = 0; i < LUAC_DATA.length; i++) { 55 | if (buff_temp[i] != LUAC_DATA[i]) { 56 | throw new RuntimeException("不是一个LuaC文件!LuaC数据错误!数据应为" + Collections.singletonList(LUAC_DATA) + ",但是读取到的数据为" + Collections.singletonList(buff_temp)); 57 | } 58 | } 59 | sizeof_int = readByte(); 60 | sizeof_size_t = readByte(); 61 | sizeof_Instruction = readByte(); 62 | sizeof_lua_Integer = readByte(); 63 | sizeof_lua_Number = readByte(); 64 | buff_temp = readBlock(sizeof_lua_Integer); 65 | for (i = 0; i < sizeof_lua_Integer; i++) { 66 | if (buff_temp[i] != LUAC_INT[i]) { 67 | throw new RuntimeException("不是一个LuaC文件!LuaC整数错误!整数数据应为" + Collections.singletonList(LUAC_INT) + ",但是读取到的整数数据为" + Collections.singletonList(buff_temp)); 68 | } 69 | } 70 | buff_temp = readBlock(sizeof_lua_Number); 71 | for (i = 0; i < sizeof_lua_Number; i++) { 72 | if (buff_temp[i] != LUAC_NUM[i]) { 73 | throw new RuntimeException("不是一个LuaC文件!LuaC数字错误!浮点数据应为" + Collections.singletonList(LUAC_NUM) + ",但是读取到的浮点数据为" + Collections.singletonList(buff_temp)); 74 | } 75 | } 76 | } 77 | 78 | private void readCode(Proto f) { 79 | int n = (int) readInt(); 80 | f.sizecode(n); 81 | for (int i = 0; i < n; i++) { 82 | Instruction I = new Instruction(readInstruction()); 83 | f.code[i] = I; 84 | } 85 | } 86 | 87 | private void readUpvalues(Proto f) { 88 | int n = (int) readInt(); 89 | f.sizeupvalues(n); 90 | for (int i = 0; i < n; i++) { 91 | Upvaldesc upvaldesc = new Upvaldesc(); 92 | upvaldesc.instack = readByte() != 0; 93 | upvaldesc.idx = (short) (readByte() & 0xff); 94 | f.upvalues[i] = upvaldesc; 95 | } 96 | } 97 | 98 | private void readProtos(Proto f) { 99 | int n = (int) readInt(); 100 | f.sizep(n); 101 | for (int i = 0; i < n; i++) { 102 | Proto p = new Proto(); 103 | readFunction(p); 104 | f.p[i] = p; 105 | } 106 | } 107 | 108 | private void readDebug(Proto f) { 109 | int n = (int) readInt(); 110 | f.sizelineinfo(n); 111 | for (int i = 0; i < n; i++) { 112 | f.lineinfo[i] = (int) readInt(); 113 | } 114 | n = (int) readInt(); 115 | f.sizelocvars(n); 116 | for (int i = 0; i < n; i++) { 117 | LocVar locVar = new LocVar(); 118 | locVar.varname = readTString(); 119 | locVar.startpc = (int) readInt(); 120 | locVar.endpc = (int) readInt(); 121 | f.locvars[i] = locVar; 122 | } 123 | n = (int) readInt(); 124 | for (int i = 0; i < n; i++) { 125 | Upvaldesc upvaldesc = f.upvalues[i]; 126 | if (upvaldesc != null) { 127 | upvaldesc.name = readTString(); 128 | } 129 | } 130 | } 131 | 132 | private void readFunction(Proto f) { 133 | f.source = readTString(); 134 | f.linedefined = (int) readInt(); 135 | f.lastlinedefined = (int) readInt(); 136 | f.numparams = readByte(); 137 | f.is_vararg = readByte(); 138 | f.maxstacksize = readByte(); 139 | readCode(f); 140 | readConstants(f); 141 | readUpvalues(f); 142 | readProtos(f); 143 | readDebug(f); 144 | } 145 | 146 | private void readConstants(Proto f) { 147 | int n = (int) readInt(); 148 | f.sizek(n); 149 | for (int i = 0; i < n; i++) { 150 | int t = readByte() & 0xFF; 151 | switch (t) { 152 | case TValue.LUA_TNIL: { 153 | f.k[i] = TValue.NIL; 154 | break; 155 | } 156 | case TValue.LUA_TBOOLEAN: { 157 | f.k[i] = readByte() != 0 ? TValue.TRUE : TValue.FALSE; 158 | break; 159 | } 160 | case TValue.LUA_TNUMFLT: { 161 | f.k[i] = TValue.createNumber(readNumber()); 162 | break; 163 | } 164 | case TValue.LUA_TNUMINT: { 165 | f.k[i] = TValue.createInteger(readInteger()); 166 | break; 167 | } 168 | case TValue.LUA_TSHRSTR: 169 | case TValue.LUA_TLNGSTR: { 170 | f.k[i] = readTString(); 171 | break; 172 | } 173 | default: { 174 | // throw new RuntimeException("unknown type"); 175 | f.k[i] = TValue.NIL; 176 | } 177 | } 178 | } 179 | } 180 | 181 | public Proto parse() { 182 | // try { 183 | Proto f = new Proto(); 184 | readHeader(); 185 | readByte(); // sizeupvalues在Proto处就有了,我不管了 186 | readFunction(f); 187 | return f; 188 | // }catch (Throwable e){ 189 | // StringBuilder sb = new StringBuilder(); 190 | // sb.append(e.getMessage()).append("\n"); 191 | // for (StackTraceElement stackTraceElement : e.getStackTrace()) { 192 | // sb.append(stackTraceElement.toString()).append("\n"); 193 | // } 194 | // throw new RuntimeException(sb.toString()); 195 | // } 196 | } 197 | 198 | private byte readByte() { 199 | return readBlock(1)[0]; 200 | } 201 | 202 | private long readInt() { 203 | return bytes2int(readBlock(sizeof_int)); 204 | } 205 | 206 | private int readInstruction() { 207 | byte[] bytes = readBlock(sizeof_Instruction); 208 | long result = 0; 209 | for (int i = 0; i < sizeof_Instruction; i++) { 210 | // result |= ((long) (readByte() & 0xFF) << (i * 8)); 211 | result |= ((long) (bytes[i] & 0xFF) << (i * 8)); 212 | } 213 | return (int) result; 214 | } 215 | 216 | private long readSizeT() { 217 | byte[] bytes = readBlock(sizeof_size_t); 218 | long result = 0; 219 | for (int i = 0; i < sizeof_size_t; i++) { 220 | // result |= ((long) (readByte() & 0xFF) << (i * 8)); 221 | result |= ((long) (bytes[i] & 0xFF) << (i * 8)); 222 | } 223 | return result; 224 | } 225 | 226 | private double readNumber() { 227 | return bytes2FLT(readBlock(sizeof_lua_Number)); 228 | } 229 | 230 | private long readInteger() { 231 | return bytes2INT(readBlock(sizeof_lua_Integer)); 232 | } 233 | 234 | private TValue readTString() { 235 | TValue ret = null; 236 | int size = readByte() & 0xff; 237 | if (size == 0xFF) {//长字符 238 | size = (int) readSizeT(); 239 | size--; 240 | byte[] bytes = readBlock(size); 241 | ret = TValue.createString(bytes); 242 | } else if (size == 0) {//""是1,所以0表示nil 243 | ret = TValue.NIL; 244 | } else if (size == 1) {//""是1 245 | ret = TValue.EMPTY_STRING; 246 | } else {//短字符 247 | size--; 248 | byte[] bytes = readBlock(size); 249 | ret = TValue.createString(bytes); 250 | } 251 | return ret; 252 | } 253 | 254 | } 255 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/OPCode.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | import static com.nwdxlgzs.xasm.OPCode.OpArgMask.*; 4 | import static com.nwdxlgzs.xasm.OPCode.OpMode.*; 5 | 6 | public enum OPCode { 7 | UNKNOWN(-1, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "unknown"), 8 | OP_MOVE(0, 0, 1, OpArgR, OpArgN, iABC, "move"), 9 | OP_LOADK(1, 0, 1, OpArgK, OpArgN, iABx, "loadk"), 10 | OP_LOADKX(2, 0, 1, OpArgN, OpArgN, iABx, "loadkx"), 11 | OP_LOADBOOL(3, 0, 1, OpArgU, OpArgU, iABC, "loadbool"), 12 | OP_LOADNIL(4, 0, 1, OpArgU, OpArgN, iABC, "loadnil"), 13 | OP_GETUPVAL(5, 0, 1, OpArgU, OpArgN, iABC, "getupval"), 14 | OP_GETTABUP(6, 0, 1, OpArgU, OpArgK, iABC, "gettabup"), 15 | OP_GETTABLE(7, 0, 1, OpArgR, OpArgK, iABC, "gettable"), 16 | OP_SETTABUP(8, 0, 0, OpArgK, OpArgK, iABC, "settabup"), 17 | OP_SETUPVAL(9, 0, 0, OpArgU, OpArgN, iABC, "setupval"), 18 | OP_SETTABLE(10, 0, 0, OpArgK, OpArgK, iABC, "settable"), 19 | OP_NEWTABLE(11, 0, 1, OpArgU, OpArgU, iABC, "newtable"), 20 | OP_SELF(12, 0, 1, OpArgR, OpArgK, iABC, "self"), 21 | OP_ADD(13, 0, 1, OpArgK, OpArgK, iABC, "add"), 22 | OP_SUB(14, 0, 1, OpArgK, OpArgK, iABC, "sub"), 23 | OP_MUL(15, 0, 1, OpArgK, OpArgK, iABC, "mul"), 24 | OP_MOD(16, 0, 1, OpArgK, OpArgK, iABC, "mod"), 25 | OP_POW(17, 0, 1, OpArgK, OpArgK, iABC, "pow"), 26 | OP_DIV(18, 0, 1, OpArgK, OpArgK, iABC, "div"), 27 | OP_IDIV(19, 0, 1, OpArgK, OpArgK, iABC, "idiv"), 28 | OP_BAND(20, 0, 1, OpArgK, OpArgK, iABC, "band"), 29 | OP_BOR(21, 0, 1, OpArgK, OpArgK, iABC, "bor"), 30 | OP_BXOR(22, 0, 1, OpArgK, OpArgK, iABC, "bxor"), 31 | OP_SHL(23, 0, 1, OpArgK, OpArgK, iABC, "shl"), 32 | OP_SHR(24, 0, 1, OpArgK, OpArgK, iABC, "shr"), 33 | OP_UNM(25, 0, 1, OpArgR, OpArgN, iABC, "unm"), 34 | OP_BNOT(26, 0, 1, OpArgR, OpArgN, iABC, "bnot"), 35 | OP_NOT(27, 0, 1, OpArgR, OpArgN, iABC, "not"), 36 | OP_LEN(28, 0, 1, OpArgR, OpArgN, iABC, "len"), 37 | OP_CONCAT(29, 0, 1, OpArgR, OpArgR, iABC, "concat"), 38 | OP_JMP(30, 0, 0, OpArgR, OpArgN, iAsBx, "jmp"), 39 | OP_EQ(31, 1, 0, OpArgK, OpArgK, iABC, "eq"), 40 | OP_LT(32, 1, 0, OpArgK, OpArgK, iABC, "lt"), 41 | OP_LE(33, 1, 0, OpArgK, OpArgK, iABC, "le"), 42 | OP_TEST(34, 1, 0, OpArgR, OpArgU, iABC, "test"), 43 | OP_TESTSET(35, 1, 1, OpArgR, OpArgU, iABC, "testset"), 44 | OP_CALL(36, 0, 1, OpArgU, OpArgU, iABC, "call"), 45 | OP_TAILCALL(37, 0, 0, OpArgU, OpArgU, iABC, "tailcall"), 46 | OP_RETURN(38, 0, 0, OpArgU, OpArgN, iABC, "return"), 47 | OP_FORLOOP(39, 1, 0, OpArgR, OpArgN, iAsBx, "forloop"), 48 | OP_FORPREP(40, 1, 0, OpArgR, OpArgN, iAsBx, "forprep"), 49 | OP_TFORCALL(41, 0, 0, OpArgU, OpArgU, iABC, "tforcall"), 50 | OP_TFORLOOP(42, 1, 0, OpArgR, OpArgN, iAsBx, "tforloop"), 51 | OP_SETLIST(43, 0, 0, OpArgU, OpArgU, iABC, "setlist"), 52 | OP_CLOSURE(44, 0, 1, OpArgU, OpArgN, iABx, "closure"), 53 | OP_VARARG(45, 0, 1, OpArgU, OpArgN, iABC, "vararg"), 54 | OP_EXTRAARG(46, 0, 0, OpArgU, OpArgU, iAx, "extraarg"), 55 | //下头三个是nirenr的Androlua+自定义指令,其中TFOREACH只是保留指令,还未实现 56 | OP_TBC(47, 0, 0, OpArgN, OpArgN, iABC, "tbc"), 57 | OP_NEWARRAY(48, 0, 1, OpArgU, OpArgN, iABC, "newarray"), 58 | OP_TFOREACH(49, 0, 0, OpArgN, OpArgU, iABC, "tforeach"), 59 | //下头是不存在的op 60 | OP_OP50(50, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op50"), 61 | OP_OP51(51, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op51"), 62 | OP_OP52(52, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op52"), 63 | OP_OP53(53, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op53"), 64 | OP_OP54(54, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op54"), 65 | OP_OP55(55, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op55"), 66 | OP_OP56(56, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op56"), 67 | OP_OP57(57, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op57"), 68 | OP_OP58(58, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op58"), 69 | OP_OP59(59, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op59"), 70 | OP_OP60(60, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op60"), 71 | OP_OP61(61, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op61"), 72 | OP_OP62(62, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op62"), 73 | OP_OP63(63, 0, 0, OpArgMask.UNKNOWN, OpArgMask.UNKNOWN, OpMode.UNKNOWN, "op63"); 74 | 75 | private int op; 76 | private int T; 77 | private int A; 78 | private OpArgMask B; 79 | private OpArgMask C; 80 | private OpMode Mode; 81 | private String name; 82 | 83 | OPCode(int op, int T, int A, OpArgMask B, OpArgMask C, OpMode Mode, String name) { 84 | this.op = op; 85 | this.T = T; 86 | this.A = A; 87 | this.B = B; 88 | this.C = C; 89 | this.Mode = Mode; 90 | this.name = name; 91 | } 92 | 93 | public int getOP() { 94 | return op; 95 | } 96 | 97 | public int getT() { 98 | return T; 99 | } 100 | 101 | public int getA() { 102 | return A; 103 | } 104 | 105 | public OpArgMask getB() { 106 | return B; 107 | } 108 | 109 | public OpArgMask getC() { 110 | return C; 111 | } 112 | 113 | public OpMode getMode() { 114 | return Mode; 115 | } 116 | 117 | public String getName() { 118 | return name; 119 | } 120 | 121 | public static OPCode fromValue(int value) { 122 | for (OPCode opCode : OPCode.values()) { 123 | if (opCode.getOP() == value) { 124 | return opCode; 125 | } 126 | } 127 | return UNKNOWN; 128 | } 129 | 130 | public static OPCode fromName(String name) { 131 | name = name.toLowerCase(); 132 | for (OPCode opCode : OPCode.values()) { 133 | if (opCode.getName().equals(name)) { 134 | return opCode; 135 | } 136 | } 137 | if ("neq".equals(name) || "~=".equals(name) || "!=".equals(name) || "==".equals(name)) { 138 | return OP_EQ; 139 | } 140 | if ("nlt".equals(name) || ">".equals(name) || "<".equals(name)) { 141 | return OP_LT; 142 | } 143 | if ("nle".equals(name) || ">=".equals(name) || "<=".equals(name)) { 144 | return OP_LE; 145 | } 146 | if ("func".equals(name) || "def".equals(name)) { 147 | return OP_CLOSURE; 148 | } 149 | if ("+".equals(name)) { 150 | return OP_ADD; 151 | } 152 | if ("-".equals(name)) { 153 | return OP_SUB; 154 | } 155 | if ("*".equals(name)) { 156 | return OP_MUL; 157 | } 158 | if ("%".equals(name)) { 159 | return OP_MOD; 160 | } 161 | if ("^".equals(name)) { 162 | return OP_POW; 163 | } 164 | if ("/".equals(name)) { 165 | return OP_DIV; 166 | } 167 | if ("//".equals(name)) { 168 | return OP_IDIV; 169 | } 170 | if ("&".equals(name)) { 171 | return OP_BAND; 172 | } 173 | if ("|".equals(name)) { 174 | return OP_BOR; 175 | } 176 | if ("~".equals(name)) { 177 | return OP_BXOR; 178 | } 179 | if ("<<".equals(name)) { 180 | return OP_SHL; 181 | } 182 | if (">>".equals(name)) { 183 | return OP_SHR; 184 | } 185 | if ("-()".equals(name)) { 186 | return OP_UNM; 187 | } 188 | if ("~()".equals(name)) { 189 | return OP_BNOT; 190 | } 191 | if ("!()".equals(name)) { 192 | return OP_NOT; 193 | } 194 | if ("#".equals(name)) { 195 | return OP_LEN; 196 | } 197 | if ("..".equals(name)) { 198 | return OP_CONCAT; 199 | } 200 | if ("{}".equals(name)) { 201 | return OP_NEWTABLE; 202 | } 203 | if ("[]".equals(name)) { 204 | return OP_NEWARRAY; 205 | } 206 | 207 | 208 | //特殊支持一下:opXX 209 | if (name.startsWith("op")) { 210 | try { 211 | int op = Integer.parseInt(name.substring(2)); 212 | return fromValue(op); 213 | } catch (Exception e) { 214 | //ignore 215 | } 216 | } 217 | return UNKNOWN; 218 | } 219 | 220 | public enum OpArgMask { 221 | OpArgN(0), 222 | OpArgU(1), 223 | OpArgR(2), 224 | OpArgK(3), 225 | UNKNOWN(-1); 226 | public int value; 227 | 228 | OpArgMask(int value) { 229 | this.value = value; 230 | } 231 | 232 | public int getValue() { 233 | return value; 234 | } 235 | 236 | public static OpArgMask fromValue(int value) { 237 | for (OpArgMask opArgMask : OpArgMask.values()) { 238 | if (opArgMask.getValue() == value) { 239 | return opArgMask; 240 | } 241 | } 242 | return UNKNOWN; 243 | } 244 | } 245 | 246 | public enum OpMode { 247 | iABC(0), 248 | iABx(1), 249 | iAsBx(2), 250 | iAx(3), 251 | UNKNOWN(-1); 252 | public int value; 253 | 254 | OpMode(int value) { 255 | this.value = value; 256 | } 257 | 258 | public int getValue() { 259 | return value; 260 | } 261 | 262 | public static OpMode fromValue(int value) { 263 | for (OpMode opMode : OpMode.values()) { 264 | if (opMode.getValue() == value) { 265 | return opMode; 266 | } 267 | } 268 | return UNKNOWN; 269 | } 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/Parser.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | import java.util.ArrayList; 4 | 5 | import static com.nwdxlgzs.xasm.defines.*; 6 | 7 | public class Parser { 8 | /* 9 | * 切块解析,所以Parser责任同时切块和解析 10 | */ 11 | private final CharSequence source; 12 | private final ArrayList allProtoXasm = new ArrayList<>(); 13 | private final ArrayList allProto = new ArrayList<>(); 14 | 15 | public Parser(CharSequence source) { 16 | this.source = source; 17 | } 18 | 19 | public void splitXasm() { 20 | Lexer lexer = new Lexer(source); 21 | boolean onFunction = false; 22 | int functionStart = 0; 23 | while (true) { 24 | Lexer.Tokens token = lexer.nextToken(); 25 | if (token == Lexer.Tokens.EOF) { 26 | break; 27 | } 28 | if (token == Lexer.Tokens.FUNCTION_KEYWORD) { 29 | String txt = lexer.getTokenText(); 30 | if (".function".equals(txt)) { 31 | onFunction = true; 32 | functionStart = lexer.getIndex(); 33 | } else if (onFunction && ".end".equals(txt)) { 34 | onFunction = false; 35 | allProtoXasm.add(source.subSequence(functionStart, lexer.getIndex()).toString()); 36 | } 37 | } 38 | } 39 | } 40 | 41 | public void parse() { 42 | if (allProtoXasm.size() == 0 || allProto.size() != 0) { 43 | splitXasm(); 44 | } 45 | String xasm; 46 | Proto proto; 47 | Lexer lexer; 48 | String txt; 49 | Lexer.Tokens token = Lexer.Tokens.UNKNOWN; 50 | for (int i = 0; i < allProtoXasm.size(); i++) { 51 | proto = new Proto(); 52 | allProto.add(proto); 53 | xasm = allProtoXasm.get(i); 54 | lexer = new Lexer(xasm); 55 | // lexer.gotoNextToken(Lexer.Tokens.FUNCTION_KEYWORD, true);//直接跳到目标 56 | // lexer.testNextToken(Lexer.Tokens.FUNCTION_KEYWORD, true, true);//测试下一个token是否是目标,如果是则跳到目标,否则按参数回滚 57 | lexer.gotoNextToken(Lexer.Tokens.FUNCTION_KEYWORD, true); 58 | txt = lexer.getTokenText(); 59 | if (".function".equals(txt)) { 60 | lexer.gotoNextToken(Lexer.Tokens.IDENTIFIER, true); 61 | proto.XasmFuncName = lexer.getTokenText(); 62 | boolean doBreak = false; 63 | while (true) { 64 | if (doBreak) { 65 | break; 66 | } 67 | token = lexer.skipUselessToken(); 68 | txt = lexer.getTokenText(); 69 | switch (token) { 70 | case PROTO_KEYWORD: { 71 | onProtoKeyword(lexer, proto, txt, token, i); 72 | continue; 73 | } 74 | case CODE_KEYWORD: { 75 | if (".code-start".equals(txt)) { 76 | Lexer.LexerSnapshot snapshot = lexer.snapshot(); 77 | boolean doBreak_Code = false; 78 | while (true) { 79 | if (doBreak_Code) { 80 | break; 81 | } 82 | token = lexer.skipUselessToken(); 83 | txt = lexer.getTokenText(); 84 | if (Lexer.Tokens.CODE_KEYWORD == token) { 85 | if (".code-end".equals(txt)) { 86 | doBreak_Code = true; 87 | break; 88 | } else { 89 | throw new RuntimeException("解析错误(CODE_KEYWORD.code-start):" + token + "(" + txt + ")不应该在这里。(索引" + i + ")"); 90 | } 91 | } 92 | } 93 | } else { 94 | throw new RuntimeException("解析错误(CODE_KEYWORD):" + token + "(" + txt + ")不应该在这里。(索引" + i + ")"); 95 | } 96 | break; 97 | } 98 | case FUNCTION_KEYWORD: { 99 | if (".end".equals(txt)) { 100 | doBreak = true; 101 | } else { 102 | throw new RuntimeException("解析错误(FUNCTION_KEYWORD):" + token + "(" + txt + ")不应该在这里。(索引" + i + ")"); 103 | } 104 | break; 105 | } 106 | default: { 107 | throw new RuntimeException("解析错误(default):" + token + "(" + txt + ")不应该在这里。(索引" + i + ")"); 108 | } 109 | } 110 | } 111 | } else { 112 | throw new RuntimeException("解析错误:" + token + "(" + txt + ")不应该在这里。(索引" + i + ")"); 113 | } 114 | } 115 | 116 | } 117 | 118 | private static void onProtoKeyword(Lexer lexer, Proto proto, String txt, Lexer.Tokens token, int i) { 119 | if (".sub-parse".equals(txt)) {//这个是给人看的,解析工具其实可以不认的,只是告诉人这个函数会解析子函数 120 | lexer.gotoNextToken(Lexer.Tokens.VALUE_KEYWORD, true); 121 | } else if (".source".equals(txt)) { 122 | token = lexer.skipUselessToken(); 123 | txt = lexer.getTokenText(); 124 | if (Lexer.Tokens.STRING == token) { 125 | proto.source = readAsTString(txt); 126 | } else if (Lexer.Tokens.VALUE_KEYWORD == token && ("null".equals(txt) || "nil".equals(txt))) { 127 | proto.source = TValue.createNil(); 128 | } else { 129 | throw new RuntimeException("解析错误(PROTO_KEYWORD.source):" + token + "(" + txt + ")不应该在这里。(索引" + i + ")"); 130 | } 131 | } else if (".is_vararg".equals(txt)) { 132 | lexer.gotoNextToken(Lexer.Tokens.INTEGER_LITERAL, true); 133 | txt = lexer.getTokenText(); 134 | proto.is_vararg = (byte) (Integer.parseInt(txt) & 0xff); 135 | } else if (".maxstacksize".equals(txt)) { 136 | lexer.gotoNextToken(Lexer.Tokens.INTEGER_LITERAL, true); 137 | txt = lexer.getTokenText(); 138 | proto.maxstacksize = (byte) (Integer.parseInt(txt) & 0xff); 139 | } else if (".numparams".equals(txt)) { 140 | lexer.gotoNextToken(Lexer.Tokens.INTEGER_LITERAL, true); 141 | txt = lexer.getTokenText(); 142 | proto.numparams = (byte) (Integer.parseInt(txt) & 0xff); 143 | } else if (".linedefined".equals(txt)) { 144 | lexer.gotoNextToken(Lexer.Tokens.INTEGER_LITERAL, true); 145 | txt = lexer.getTokenText(); 146 | proto.linedefined = Integer.parseInt(txt); 147 | } else if (".lastlinedefined".equals(txt)) { 148 | lexer.gotoNextToken(Lexer.Tokens.INTEGER_LITERAL, true); 149 | txt = lexer.getTokenText(); 150 | proto.lastlinedefined = Integer.parseInt(txt); 151 | } else if (".locvars".equals(txt)) { 152 | token = lexer.skipUselessToken(); 153 | txt = lexer.getTokenText(); 154 | int idx = proto.sizelocvars(); 155 | if (Lexer.Tokens.STRING == token) { 156 | proto.locvars = realloc(proto.locvars, idx + 1); 157 | proto.locvars[idx] = new LocVar(); 158 | proto.locvars[idx].varname = readAsTString(txt); 159 | } else if (Lexer.Tokens.VALUE_KEYWORD == token && ("null".equals(txt) || "nil".equals(txt))) { 160 | proto.locvars = realloc(proto.locvars, idx + 1); 161 | proto.locvars[idx] = new LocVar(); 162 | proto.locvars[idx].varname = TValue.createNil(); 163 | } else { 164 | throw new RuntimeException("解析错误(PROTO_KEYWORD.locvars):" + token + "(" + txt + ")不应该在这里。(索引" + i + ")"); 165 | } 166 | lexer.gotoNextToken(Lexer.Tokens.INTEGER_LITERAL, true); 167 | txt = lexer.getTokenText(); 168 | proto.locvars[idx].startpc = Integer.parseInt(txt); 169 | lexer.gotoNextToken(Lexer.Tokens.INTEGER_LITERAL, true); 170 | txt = lexer.getTokenText(); 171 | proto.locvars[idx].endpc = Integer.parseInt(txt); 172 | } else if (".upvaldesc".equals(txt)) { 173 | token = lexer.skipUselessToken(); 174 | txt = lexer.getTokenText(); 175 | int idx = proto.sizeupvalues(); 176 | if (Lexer.Tokens.STRING == token) { 177 | proto.upvalues = realloc(proto.upvalues, idx + 1); 178 | proto.upvalues[idx] = new Upvaldesc(); 179 | proto.upvalues[idx].name = readAsTString(txt); 180 | } else if (Lexer.Tokens.VALUE_KEYWORD == token && ("null".equals(txt) || "nil".equals(txt))) { 181 | proto.upvalues = realloc(proto.upvalues, idx + 1); 182 | proto.upvalues[idx] = new Upvaldesc(); 183 | proto.upvalues[idx].name = TValue.createNil(); 184 | } else { 185 | throw new RuntimeException("解析错误(PROTO_KEYWORD.upvaldesc):" + token + "(" + txt + ")不应该在这里。(索引" + i + ")"); 186 | } 187 | lexer.gotoNextToken(Lexer.Tokens.INTEGER_LITERAL, true); 188 | txt = lexer.getTokenText(); 189 | proto.upvalues[idx].idx = (byte) (Integer.parseInt(txt) & 0xff); 190 | lexer.gotoNextToken(Lexer.Tokens.VALUE_KEYWORD, true); 191 | txt = lexer.getTokenText(); 192 | if ("true".equals(txt)) { 193 | proto.upvalues[idx].instack = true; 194 | } else if ("false".equals(txt)) { 195 | proto.upvalues[idx].instack = false; 196 | } else { 197 | throw new RuntimeException("解析错误(PROTO_KEYWORD.upvaldesc):" + token + "(" + txt + ")不应该在这里。(索引" + i + ")"); 198 | } 199 | } else { 200 | throw new RuntimeException("解析错误(PROTO_KEYWORD):" + token + "(" + txt + ")不应该在这里。(索引" + i + ")"); 201 | } 202 | } 203 | 204 | public ArrayList getAllProtoXasm() { 205 | return allProtoXasm; 206 | } 207 | 208 | public ArrayList getAllProto() { 209 | return allProto; 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/TValue.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | import java.io.Serializable; 4 | 5 | import static com.nwdxlgzs.xasm.defines.*; 6 | 7 | public class TValue implements Serializable { 8 | public static final int LUA_TNIL = 0; 9 | public static final int LUA_TBOOLEAN = 1; 10 | public static final int LUA_TNUMBER = 3; 11 | public static final int LUA_TNUMFLT = LUA_TNUMBER | (0 << 4); 12 | public static final int LUA_TNUMINT = LUA_TNUMBER | (1 << 4); 13 | public static final int LUA_TSTRING = 4; 14 | public static final int LUA_TSHRSTR = LUA_TSTRING | (0 << 4); 15 | public static final int LUA_TLNGSTR = LUA_TSTRING | (1 << 4); 16 | public static final int LUAI_MAXSHORTLEN = 40; 17 | 18 | public static final TValue NIL = TValue.createNil(); 19 | public static final TValue TRUE = TValue.createBoolean(true); 20 | public static final TValue FALSE = TValue.createBoolean(false); 21 | public static final TValue EMPTY_STRING = TValue.createString(""); 22 | 23 | public Object value_; 24 | public int tt_; 25 | 26 | public TValue() { 27 | } 28 | 29 | public void getNil() { 30 | if (tt_ != LUA_TNIL) { 31 | throw new RuntimeException("TValue不是LUA_TNIL"); 32 | } 33 | } 34 | 35 | public boolean getBoolean() { 36 | if (tt_ != LUA_TBOOLEAN) { 37 | throw new RuntimeException("TValue不是LUA_TBOOLEAN"); 38 | } 39 | return (boolean) value_; 40 | } 41 | 42 | public String getString() { 43 | if (tt_ != LUA_TSHRSTR && tt_ != LUA_TLNGSTR) { 44 | throw new RuntimeException("TValue不是LUA_TSHRSTR或LUA_TLNGSTR"); 45 | } 46 | return (String) new String((byte[]) value_); 47 | } 48 | 49 | public byte[] getStringBytes() { 50 | if (tt_ != LUA_TSHRSTR && tt_ != LUA_TLNGSTR) { 51 | throw new RuntimeException("TValue不是LUA_TSHRSTR或LUA_TLNGSTR"); 52 | } 53 | return (byte[]) value_; 54 | } 55 | 56 | public double getFLT() { 57 | if (tt_ != LUA_TNUMFLT) { 58 | throw new RuntimeException("TValue不是LUA_TNUMFLT"); 59 | } 60 | return (double) value_; 61 | } 62 | 63 | public long getINT() { 64 | if (tt_ != LUA_TNUMINT) { 65 | throw new RuntimeException("TValue不是LUA_TNUMINT"); 66 | } 67 | return (long) value_; 68 | } 69 | 70 | public static TValue createNil() { 71 | if (NIL == null) { 72 | TValue tv = new TValue(); 73 | tv.tt_ = LUA_TNIL; 74 | return tv; 75 | } 76 | return NIL; 77 | } 78 | 79 | public static TValue createBoolean(boolean b) { 80 | if (b) { 81 | if (TRUE == null) { 82 | TValue tv = new TValue(); 83 | tv.tt_ = LUA_TBOOLEAN; 84 | tv.value_ = true; 85 | return tv; 86 | } 87 | return TRUE; 88 | } else { 89 | if (FALSE == null) { 90 | TValue tv = new TValue(); 91 | tv.tt_ = LUA_TBOOLEAN; 92 | tv.value_ = false; 93 | return tv; 94 | } 95 | return FALSE; 96 | } 97 | } 98 | 99 | public static TValue createNumber(double d) { 100 | TValue tv = new TValue(); 101 | tv.tt_ = LUA_TNUMFLT; 102 | tv.value_ = d; 103 | return tv; 104 | } 105 | 106 | public static TValue createInteger(long l) { 107 | TValue tv = new TValue(); 108 | tv.tt_ = LUA_TNUMINT; 109 | tv.value_ = l; 110 | return tv; 111 | } 112 | 113 | public static TValue createString(String str) { 114 | return createString(str.getBytes()); 115 | } 116 | 117 | public static TValue createString(byte[] data) { 118 | if (data == null || data.length == 0) { 119 | if (EMPTY_STRING == null) {//初始化EMPTY_STRING 120 | TValue tv = new TValue(); 121 | tv.tt_ = LUA_TSHRSTR; 122 | tv.value_ = new byte[0]; 123 | return tv; 124 | } 125 | return EMPTY_STRING; 126 | } 127 | TValue ts = new TValue(); 128 | ts.value_ = data; 129 | ts.tt_ = data.length <= LUAI_MAXSHORTLEN ? LUA_TSHRSTR : LUA_TLNGSTR; 130 | return ts; 131 | } 132 | 133 | public static TValue createString(byte[] data, int length) { 134 | return createString(data, 0, length); 135 | } 136 | 137 | public static TValue createString(byte[] data, int offset, int length) { 138 | byte[] newData = new byte[length]; 139 | System.arraycopy(data, offset, newData, 0, length); 140 | return createString(newData); 141 | } 142 | 143 | public String toWarpString() { 144 | if (tt_ == LUA_TNIL) { 145 | return "\"nil\""; 146 | } else if (tt_ == LUA_TBOOLEAN) { 147 | return (boolean) value_ ? "\"true\"" : "\"false\""; 148 | } else if (tt_ == LUA_TNUMFLT) { 149 | return "\"" + String.valueOf((double) value_) + "\""; 150 | } else if (tt_ == LUA_TNUMINT) { 151 | return "\"" + String.valueOf((long) value_) + "\""; 152 | } else if (tt_ == LUA_TSHRSTR || tt_ == LUA_TLNGSTR) { 153 | byte[] data = (byte[]) value_; 154 | StringContentLevel level = TStringCheck(data); 155 | switch (level) { 156 | case STR_CONTENT_BUFFER: { 157 | StringBuilder sb = new StringBuilder(); 158 | sb.append("\""); 159 | for (int i = 0; i < data.length; i++) { 160 | sb.append(String.format("\\x%02X", data[i])); 161 | } 162 | sb.append("\""); 163 | return sb.toString(); 164 | } 165 | case STR_CONTENT_STRING: 166 | default: { 167 | StringBuilder sb = new StringBuilder(); 168 | sb.append("\""); 169 | int start = 0; 170 | for (int i = 0; i < data.length; i++) { 171 | byte b = data[i]; 172 | boolean startTrans = true; 173 | switch (data[i]) { 174 | case '"': { 175 | b = '\"'; 176 | break; 177 | } 178 | case '\0': { 179 | b = '0'; 180 | break; 181 | } 182 | case '\\': { 183 | b = '\\'; 184 | break; 185 | } 186 | case '\b': { 187 | b = 'b'; 188 | break; 189 | } 190 | case '\f': { 191 | b = 'f'; 192 | break; 193 | } 194 | case '\n': { 195 | b = 'n'; 196 | break; 197 | } 198 | case '\r': { 199 | b = 'r'; 200 | break; 201 | } 202 | case '\t': { 203 | b = 't'; 204 | break; 205 | } 206 | default: { 207 | startTrans = false; 208 | break; 209 | } 210 | } 211 | if (startTrans) { 212 | sb.append(new String(data, start, i - start)); 213 | sb.append("\\"); 214 | sb.append((char) b); 215 | start = i + 1; 216 | } 217 | } 218 | if (start < data.length) { 219 | sb.append(new String(data, start, data.length - start)); 220 | } 221 | sb.append("\""); 222 | return sb.toString(); 223 | } 224 | } 225 | } else { 226 | return "\"\""; 227 | } 228 | } 229 | 230 | public String toVarString() { 231 | if (tt_ == LUA_TSHRSTR || tt_ == LUA_TLNGSTR) { 232 | return toWarpString(); 233 | } else { 234 | return toString(); 235 | } 236 | } 237 | 238 | @Override 239 | public String toString() { 240 | switch (tt_) { 241 | case LUA_TNIL: { 242 | return "nil"; 243 | } 244 | case LUA_TBOOLEAN: { 245 | return (boolean) value_ ? "true" : "false"; 246 | } 247 | case LUA_TNUMFLT: { 248 | return String.valueOf((double) value_); 249 | } 250 | case LUA_TNUMINT: { 251 | return String.valueOf((long) value_); 252 | } 253 | case LUA_TSHRSTR: 254 | case LUA_TLNGSTR: { 255 | if (value_ == null) { 256 | return "null"; 257 | } 258 | return new String((byte[]) value_); 259 | } 260 | default: { 261 | return "unknown type"; 262 | } 263 | } 264 | } 265 | 266 | @Override 267 | public boolean equals(Object other) { 268 | if (other == null) { 269 | return false; 270 | } 271 | if (other instanceof TValue) { 272 | TValue otherTValue = (TValue) other; 273 | if (tt_ != otherTValue.tt_) { 274 | //LUA_TNUMFLT和LUA_TNUMINT可以相互转换 275 | if (tt_ == LUA_TNUMFLT && otherTValue.tt_ == LUA_TNUMINT) { 276 | return (double) value_ == (long) otherTValue.value_; 277 | } else if (tt_ == LUA_TNUMINT && otherTValue.tt_ == LUA_TNUMFLT) { 278 | return (long) value_ == (double) otherTValue.value_; 279 | } 280 | return false; 281 | } 282 | switch (tt_) { 283 | case LUA_TNIL: { 284 | return true; 285 | } 286 | case LUA_TBOOLEAN: { 287 | return (boolean) value_ == (boolean) otherTValue.value_; 288 | } 289 | case LUA_TNUMFLT: { 290 | return (double) value_ == (double) otherTValue.value_; 291 | } 292 | case LUA_TNUMINT: { 293 | return (long) value_ == (long) otherTValue.value_; 294 | } 295 | case LUA_TSHRSTR: 296 | case LUA_TLNGSTR: { 297 | if (value_ == null) { 298 | return otherTValue.value_ == null; 299 | } 300 | byte[] data = (byte[]) value_; 301 | byte[] otherData = (byte[]) otherTValue.value_; 302 | if (data.length != otherData.length) { 303 | return false; 304 | } 305 | for (int i = 0; i < data.length; i++) { 306 | if (data[i] != otherData[i]) { 307 | return false; 308 | } 309 | } 310 | } 311 | default: { 312 | return false; 313 | } 314 | } 315 | } 316 | return false; 317 | } 318 | 319 | @Override 320 | public int hashCode() { 321 | switch (tt_) { 322 | case LUA_TNIL: { 323 | return 0; 324 | } 325 | case LUA_TBOOLEAN: { 326 | return (boolean) value_ ? 1 : 0; 327 | } 328 | case LUA_TNUMFLT: { 329 | return (int) (double) value_; 330 | } 331 | case LUA_TNUMINT: { 332 | return (int) (long) value_; 333 | } 334 | case LUA_TSHRSTR: 335 | case LUA_TLNGSTR: { 336 | if (value_ == null) { 337 | return 0; 338 | } 339 | byte[] data = (byte[]) value_; 340 | int hash = 0; 341 | for (int i = 0; i < data.length; i++) { 342 | hash = hash * 131 + data[i]; 343 | } 344 | return hash; 345 | } 346 | default: { 347 | return -1; 348 | } 349 | } 350 | } 351 | } 352 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/bindInst.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | import static com.nwdxlgzs.xasm.OPCode.*; 4 | import static com.nwdxlgzs.xasm.defines.*; 5 | 6 | public class bindInst { 7 | public static void bind(Proto f) { 8 | int i; 9 | Instruction[] code = f.code; 10 | int sizek = f.sizek(); 11 | int sizeupvalues = f.sizeupvalues(); 12 | int sizep = f.sizep(); 13 | int sizecode = f.sizecode(); 14 | for (i = 0; i < sizecode; i++) { 15 | Instruction instruction = code[i]; 16 | OPCode op = instruction.getOpCode(); 17 | switch (op) { 18 | case OP_CLOSURE: {//溢出检查 19 | if (instruction.Bx() >= sizep) { 20 | instruction.isRealFake = true; 21 | } 22 | break; 23 | } 24 | case OP_LOADK: {//溢出检查 25 | if (instruction.B() >= sizek) { 26 | instruction.isRealFake = true; 27 | } 28 | break; 29 | } 30 | case OP_SETTABUP: {//溢出检查 31 | if (instruction.A() >= sizeupvalues) { 32 | instruction.isRealFake = true; 33 | } 34 | //这里不用break,因为还要溢出检查 35 | } 36 | case OP_SETTABLE: 37 | case OP_ADD: 38 | case OP_SUB: 39 | case OP_MUL: 40 | case OP_MOD: 41 | case OP_POW: 42 | case OP_DIV: 43 | case OP_IDIV: 44 | case OP_BAND: 45 | case OP_BOR: 46 | case OP_BXOR: 47 | case OP_SHL: 48 | case OP_SHR: {//溢出检查 49 | if (ISK(instruction.B()) && INDEXK(instruction.B()) >= sizek) { 50 | instruction.isRealFake = true; 51 | } 52 | //这里不用break,因为还要检查C 53 | } 54 | case OP_GETTABLE: 55 | case OP_SELF: {//溢出检查 56 | if (ISK(instruction.C()) && INDEXK(instruction.C()) >= sizek) { 57 | instruction.isRealFake = true; 58 | } 59 | break; 60 | } 61 | case OP_GETTABUP: { 62 | if (ISK(instruction.C()) && INDEXK(instruction.C()) >= sizek) {//溢出检查 63 | instruction.isRealFake = true; 64 | } 65 | if (instruction.B() >= sizeupvalues) {//溢出检查 66 | instruction.isRealFake = true; 67 | } 68 | break; 69 | } 70 | case OP_SETUPVAL: { 71 | if (instruction.C() != 0) {//填补没用的操作数C 72 | instruction.C(0); 73 | } 74 | if (instruction.B() >= sizeupvalues) {//溢出检查 75 | instruction.isRealFake = true; 76 | } 77 | break; 78 | } 79 | case OP_GETUPVAL: {//溢出检查 80 | if (instruction.B() >= sizeupvalues) { 81 | instruction.isRealFake = true; 82 | } 83 | //这里不用break,因为还要检查C 84 | } 85 | case OP_MOVE: 86 | case OP_LOADNIL: 87 | case OP_NEWARRAY: 88 | case OP_UNM: 89 | case OP_BNOT: 90 | case OP_NOT: 91 | case OP_LEN: 92 | case OP_TAILCALL: 93 | case OP_RETURN: 94 | case OP_VARARG: {//填补没用的操作数C 95 | if (instruction.C() != 0) { 96 | instruction.C(0); 97 | } 98 | break; 99 | } 100 | case OP_TFOREACH: 101 | case OP_TBC: {//填补没用的操作数B&C 102 | if (instruction.B() != 0) { 103 | instruction.B(0); 104 | } 105 | if (instruction.C() != 0) { 106 | instruction.C(0); 107 | } 108 | break; 109 | } 110 | case OP_LOADKX: {//OP_LOADKX特例 111 | int target = i + 1; 112 | if (target < sizecode) { 113 | code[target].isCanJump2There = true; 114 | Instruction instruction2 = code[target]; 115 | if (instruction2.Ax() >= sizek) { 116 | instruction2.isRealFake = true; 117 | } 118 | } else { 119 | instruction.isRealFake = true; 120 | } 121 | if (instruction.Bx() != 0) {//填补没用的操作数Bx 122 | instruction.Bx(0); 123 | } 124 | break; 125 | } 126 | case OP_LOADBOOL: {//OP_LOADBOOL特例 127 | if (instruction.C() != 0) { 128 | int target = i + 2; 129 | if (target < sizecode) { 130 | code[target].isCanJump2There = true; 131 | } else { 132 | instruction.isRealFake = true; 133 | } 134 | } 135 | if (instruction.B() > 1) {//B就只有0和非0(1)两种情况 136 | instruction.B(1); 137 | } 138 | break; 139 | } 140 | case OP_JMP: 141 | case OP_FORLOOP: 142 | case OP_FORPREP: 143 | case OP_TFORLOOP: {//sBx 144 | int sBx = instruction.sBx(); 145 | int target = i + 1 + sBx; 146 | if (target >= 0 && target < sizecode) { 147 | code[target].isCanJump2There = true; 148 | } else { 149 | instruction.isRealFake = true; 150 | } 151 | break; 152 | } 153 | case OP_TFORCALL: {//填补没用的操作数B以及当前指令+下一句sBx 154 | if (instruction.B() != 0) { 155 | instruction.B(0); 156 | } 157 | int target = i + 1; 158 | if (target < sizecode) { 159 | code[target].isCanJump2There = true; 160 | Instruction instruction2 = code[target]; 161 | int sBx = instruction2.sBx(); 162 | target = i + 2 + sBx; 163 | if (target >= 0 && target < sizecode) { 164 | code[target].isCanJump2There = true; 165 | } else { 166 | instruction.isRealFake = true; 167 | } 168 | } else { 169 | instruction.isRealFake = true; 170 | } 171 | break; 172 | } 173 | case OP_EQ: 174 | case OP_LT: 175 | case OP_LE: { 176 | if (instruction.A() > 1) {//A就只有0和非0(1)两种情况 177 | instruction.A(1); 178 | } 179 | if (ISK(instruction.B()) && INDEXK(instruction.B()) >= sizek) {//溢出检查 180 | instruction.isRealFake = true; 181 | } 182 | if (ISK(instruction.C()) && INDEXK(instruction.C()) >= sizek) {//溢出检查 183 | instruction.isRealFake = true; 184 | } 185 | //没有break,因为还有后续处理 186 | } 187 | case OP_TEST: 188 | case OP_TESTSET: {//当前指令+下一句sBx 189 | int target = i + 1; 190 | if (target < sizecode) { 191 | code[target].isCanJump2There = true; 192 | Instruction instruction2 = code[target]; 193 | int sBx = instruction2.sBx(); 194 | target = i + 2 + sBx; 195 | if (target >= 0 && target < sizecode) { 196 | code[target].isCanJump2There = true; 197 | } else { 198 | instruction.isRealFake = true; 199 | } 200 | } else { 201 | instruction.isRealFake = true; 202 | } 203 | break; 204 | } 205 | case OP_SETLIST: {//OP_SETLIST特例 206 | if (instruction.C() == 0) { 207 | int target = i + 1; 208 | if (target < sizecode) { 209 | code[target].isCanJump2There = true; 210 | } else { 211 | instruction.isRealFake = true; 212 | } 213 | } 214 | break; 215 | } 216 | default: { 217 | if (op.getOP() >= OP_OP50.getOP()) { 218 | instruction.isRealFake = true; 219 | } 220 | break; 221 | } 222 | } 223 | } 224 | for (i = 0; i < sizecode; i++) { 225 | Instruction instruction = code[i]; 226 | if (instruction.isRealFake) { 227 | //上一个isCanJump2There(i:inst goto _inst)到下一个isCanJump2There(i-1:_inst goto inst)之间的指令都是假的 228 | int j; 229 | for (j = i; j > 0; j--) { 230 | if (j == 1) {//第一个指令一定是JMP了 231 | code[j].isStartRealFake = true; 232 | break; 233 | } 234 | if (code[j].isCanJump2There || 235 | code[j].getOpCode() == OP_RETURN || 236 | code[j].getOpCode() == OP_TFORLOOP || 237 | code[j].getOpCode() == OP_JMP || 238 | code[j].getOpCode() == OP_FORLOOP || 239 | code[j].getOpCode() == OP_FORPREP) { 240 | boolean dobreak = false; 241 | Instruction instruction2 = code[j]; 242 | switch (instruction2.getOpCode()) { 243 | case OP_LOADKX: 244 | case OP_EQ: 245 | case OP_LT: 246 | case OP_LE: 247 | case OP_TEST: 248 | case OP_TESTSET: {//忽略这个情况 249 | break; 250 | } 251 | default: { 252 | code[j].isStartRealFake = true; 253 | dobreak = true; 254 | break; 255 | } 256 | } 257 | if (dobreak) { 258 | break; 259 | } 260 | } 261 | } 262 | for (j = i + 1; j < sizecode; j++) { 263 | if (j == sizecode - 1) { 264 | code[j].isEndRealFake = true; 265 | break; 266 | } 267 | if (code[j].isCanJump2There || 268 | code[j].getOpCode() == OP_RETURN || 269 | code[j].getOpCode() == OP_TFORLOOP || 270 | code[j].getOpCode() == OP_JMP || 271 | code[j].getOpCode() == OP_FORLOOP || 272 | code[j].getOpCode() == OP_FORPREP) { 273 | boolean dobreak = false; 274 | Instruction instruction2 = code[j - 1]; 275 | switch (instruction2.getOpCode()) { 276 | case OP_LOADKX: 277 | case OP_EQ: 278 | case OP_LT: 279 | case OP_LE: 280 | case OP_TEST: 281 | case OP_TESTSET: {//忽略这个情况 282 | break; 283 | } 284 | default: { 285 | code[j - 1].isEndRealFake = true; 286 | dobreak = true; 287 | break; 288 | } 289 | } 290 | if (dobreak) { 291 | break; 292 | } 293 | } 294 | } 295 | } 296 | } 297 | for (i = 0; i < sizecode; i++) {//合并Start和End 298 | Instruction instruction = code[i]; 299 | //End和Start前后脚或者同一个的就合并 300 | if (instruction.isEndRealFake && instruction.isStartRealFake) { 301 | instruction.isEndRealFake = false; 302 | instruction.isStartRealFake = false; 303 | } 304 | if (instruction.isEndRealFake) { 305 | if (i > 0) { 306 | Instruction instruction2 = code[i - 1]; 307 | if (instruction2.isStartRealFake) { 308 | instruction.isEndRealFake = false; 309 | instruction2.isStartRealFake = false; 310 | } 311 | } 312 | } 313 | } 314 | for (i = 0; i < sizecode; i++) {//剔除重复的Start 315 | Instruction instruction = code[i]; 316 | if (instruction.isStartRealFake) { 317 | int j; 318 | for (j = i + 1; j < sizecode; j++) { 319 | Instruction instruction2 = code[j]; 320 | if (instruction2.isEndRealFake) { 321 | break; 322 | } 323 | if (instruction2.isStartRealFake) { 324 | instruction2.isStartRealFake = false; 325 | } 326 | } 327 | } 328 | } 329 | } 330 | 331 | } 332 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/defines.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.nio.ByteBuffer; 8 | import java.nio.charset.CharacterCodingException; 9 | import java.nio.charset.Charset; 10 | import java.nio.charset.CharsetDecoder; 11 | 12 | public class defines { 13 | public static byte[] LUA_SIGNATURE = {0x1b, 0x4c, 0x75, 0x61}; 14 | public static byte[] LUAC_VERSION = {0x53}; 15 | public static byte[] LUAC_FORMAT = {0}; 16 | public static byte[] LUAC_DATA = {0x19, (byte) 0x93, 0x0d, 0x0a, 0x1a, 0x0a}; 17 | public static byte[] LUAC_INT = {0x78, 0x56, 0, 0, 0, 0, 0, 0};/* 0x5678 */ 18 | public static byte[] LUAC_NUM = {0, 0, 0, 0, 0, 0x28, 0x77, 0x40};/* 370.5 */ 19 | 20 | public static int sizeof_int = 4; 21 | public static int sizeof_size_t = 4;//nirenr魔改:unsigned int 22 | public static int sizeof_Instruction = 4; 23 | public static int sizeof_lua_Integer = 8; 24 | public static int sizeof_lua_Number = 8; 25 | 26 | public static int SIZE_C = 9; 27 | public static int SIZE_B = 9; 28 | public static int SIZE_Bx = SIZE_C + SIZE_B; 29 | public static int SIZE_A = 8; 30 | public static int SIZE_Ax = SIZE_C + SIZE_B + SIZE_A; 31 | public static int SIZE_OP = 6; 32 | public static int POS_OP = 0; 33 | public static int POS_A = POS_OP + SIZE_OP; 34 | public static int POS_C = POS_A + SIZE_A; 35 | public static int POS_B = POS_C + SIZE_C; 36 | public static int POS_Bx = POS_C; 37 | public static int POS_Ax = POS_A; 38 | public static int MAXARG_Bx = (1 << SIZE_Bx) - 1; 39 | public static int MAXARG_sBx = MAXARG_Bx >> 1; 40 | public static int MAXARG_Ax = (1 << SIZE_Ax) - 1; 41 | public static int MAXARG_A = (1 << SIZE_A) - 1; 42 | public static int MAXARG_B = (1 << SIZE_B) - 1; 43 | public static int MAXARG_C = (1 << SIZE_C) - 1; 44 | 45 | public static int MASK1(int n, int p) { 46 | return ((~((~(int) 0) << (n))) << (p)); 47 | } 48 | 49 | public static int MASK0(int n, int p) { 50 | return (~MASK1(n, p)); 51 | } 52 | 53 | public static int GET_OPCODE(int i) { 54 | return ((i >> POS_OP) & MASK1(SIZE_OP, 0)); 55 | } 56 | 57 | public static int SET_OPCODE(int i, int o) { 58 | return ((i & MASK0(SIZE_OP, POS_OP)) | ((o << POS_OP) & MASK1(SIZE_OP, POS_OP))); 59 | } 60 | 61 | public static int getarg(int i, int pos, int size) { 62 | return ((i >> pos) & MASK1(size, 0)); 63 | } 64 | 65 | public static int setarg(int i, int v, int pos, int size) { 66 | return ((i & MASK0(size, pos)) | ((v << pos) & MASK1(size, pos))); 67 | } 68 | 69 | public static int GETARG_A(int i) { 70 | return getarg(i, POS_A, SIZE_A); 71 | } 72 | 73 | public static int SETARG_A(int i, int v) { 74 | return setarg(i, v, POS_A, SIZE_A); 75 | } 76 | 77 | public static int GETARG_B(int i) { 78 | return getarg(i, POS_B, SIZE_B); 79 | } 80 | 81 | public static int SETARG_B(int i, int v) { 82 | return setarg(i, v, POS_B, SIZE_B); 83 | } 84 | 85 | public static int GETARG_C(int i) { 86 | return getarg(i, POS_C, SIZE_C); 87 | } 88 | 89 | public static int SETARG_C(int i, int v) { 90 | return setarg(i, v, POS_C, SIZE_C); 91 | } 92 | 93 | public static int GETARG_Bx(int i) { 94 | return getarg(i, POS_Bx, SIZE_Bx); 95 | } 96 | 97 | public static int SETARG_Bx(int i, int v) { 98 | return setarg(i, v, POS_Bx, SIZE_Bx); 99 | } 100 | 101 | public static int GETARG_sBx(int i) { 102 | return (GETARG_Bx(i) - MAXARG_sBx); 103 | } 104 | 105 | public static int SETARG_sBx(int i, int v) { 106 | return SETARG_Bx(i, v + MAXARG_sBx); 107 | } 108 | 109 | public static int GETARG_Ax(int i) { 110 | return getarg(i, POS_Ax, SIZE_Ax); 111 | } 112 | 113 | public static int SETARG_Ax(int i, int v) { 114 | return setarg(i, v, POS_Ax, SIZE_Ax); 115 | } 116 | 117 | public static int CREATE_ABC(int o, int a, int b, int c) { 118 | return (SET_OPCODE(0, o) | SETARG_A(0, a) | SETARG_B(0, b) | SETARG_C(0, c)); 119 | } 120 | 121 | public static int CREATE_ABx(int o, int a, int bc) { 122 | return (SET_OPCODE(0, o) | SETARG_A(0, a) | SETARG_Bx(0, bc)); 123 | } 124 | 125 | public static int CREATE_AsBx(int o, int a, int bc) { 126 | return (SET_OPCODE(0, o) | SETARG_A(0, a) | SETARG_sBx(0, bc)); 127 | } 128 | 129 | public static int CREATE_Ax(int o, int a) { 130 | return (SET_OPCODE(0, o) | SETARG_Ax(0, a)); 131 | } 132 | 133 | public static int BITRK = 1 << (SIZE_B - 1); 134 | 135 | public static boolean ISK(int x) { 136 | return (x & BITRK) != 0; 137 | } 138 | 139 | public static int INDEXK(long r) { 140 | return ((int) (r) & ~BITRK); 141 | } 142 | 143 | public static int MAXINDEXRK = BITRK - 1; 144 | 145 | public static int RKASK(int x) { 146 | return (x | BITRK); 147 | } 148 | 149 | public static int NO_REG = MAXARG_A; 150 | 151 | 152 | /** 153 | * 重新绑定指令结构的分配 154 | */ 155 | public static void rebindInstructionStructure() { 156 | SIZE_Bx = SIZE_C + SIZE_B; 157 | SIZE_Ax = SIZE_C + SIZE_B + SIZE_A; 158 | POS_A = POS_OP + SIZE_OP; 159 | POS_C = POS_A + SIZE_A; 160 | POS_B = POS_C + SIZE_C; 161 | POS_Bx = POS_C; 162 | POS_Ax = POS_A; 163 | MAXARG_Bx = (1 << SIZE_Bx) - 1; 164 | MAXARG_sBx = MAXARG_Bx >> 1; 165 | MAXARG_Ax = (1 << SIZE_Ax) - 1; 166 | MAXARG_A = (1 << SIZE_A) - 1; 167 | MAXARG_B = (1 << SIZE_B) - 1; 168 | MAXARG_C = (1 << SIZE_C) - 1; 169 | BITRK = 1 << (SIZE_B - 1); 170 | MAXINDEXRK = BITRK - 1; 171 | NO_REG = MAXARG_A; 172 | } 173 | 174 | public static byte[] FLT2bytes(double n) { 175 | byte[] bytes = new byte[sizeof_lua_Number]; 176 | long l = Double.doubleToRawLongBits(n); 177 | for (int i = 0; i < sizeof_lua_Number; i++) { 178 | bytes[i] = (byte) (l & 0xff); 179 | l >>= 8; 180 | } 181 | return bytes; 182 | } 183 | 184 | public static double bytes2FLT(byte[] bytes) { 185 | long l = 0; 186 | for (int i = 0; i < sizeof_lua_Number; i++) { 187 | l |= (long) (bytes[i] & 0xff) << (i * 8); 188 | } 189 | return Double.longBitsToDouble(l); 190 | } 191 | 192 | public static byte[] INT2bytes(long n) { 193 | byte[] bytes = new byte[sizeof_lua_Integer]; 194 | for (int i = 0; i < sizeof_lua_Integer; i++) { 195 | bytes[i] = (byte) (n & 0xff); 196 | n >>= 8; 197 | } 198 | return bytes; 199 | } 200 | 201 | public static long bytes2INT(byte[] bytes) { 202 | long l = 0; 203 | for (int i = 0; i < sizeof_lua_Integer; i++) { 204 | l |= (long) (bytes[i] & 0xff) << (i * 8); 205 | } 206 | return l; 207 | } 208 | 209 | public static byte[] int2bytes(long n) { 210 | byte[] bytes = new byte[sizeof_int]; 211 | for (int i = 0; i < sizeof_int; i++) { 212 | bytes[i] = (byte) (n & 0xff); 213 | n >>= 8; 214 | } 215 | return bytes; 216 | } 217 | 218 | public static long bytes2int(byte[] bytes) { 219 | long l = 0; 220 | for (int i = 0; i < sizeof_int; i++) { 221 | l |= (long) (bytes[i] & 0xff) << (i * 8); 222 | } 223 | return l; 224 | } 225 | 226 | public static byte[] long2bytes(long n) { 227 | byte[] bytes = new byte[8]; 228 | for (int i = 0; i < 8; i++) { 229 | bytes[i] = (byte) (n & 0xff); 230 | n >>= 8; 231 | } 232 | return bytes; 233 | } 234 | 235 | public static long bytes2long(byte[] bytes) { 236 | long l = 0; 237 | for (int i = 0; i < 8; i++) { 238 | l |= (long) (bytes[i] & 0xff) << (i * 8); 239 | } 240 | return l; 241 | } 242 | 243 | public static byte[] Instruction2bytes(int i) { 244 | if (sizeof_Instruction == 4) { 245 | return int2bytes(i); 246 | } else { 247 | return long2bytes(i); 248 | } 249 | } 250 | 251 | public static long bytes2Instruction(byte[] bytes) { 252 | if (sizeof_Instruction == 4) { 253 | return (long) bytes2int(bytes); 254 | } else { 255 | return (long) bytes2long(bytes); 256 | } 257 | } 258 | 259 | public static int[] realloc(int[] old, int newsize) { 260 | if (old == null || newsize == 0) { 261 | return new int[newsize]; 262 | } 263 | int[] newarr = new int[newsize]; 264 | System.arraycopy(old, 0, newarr, 0, old.length); 265 | return newarr; 266 | } 267 | 268 | public static Integer[] realloc(Integer[] old, int newsize) { 269 | if (old == null || newsize == 0) { 270 | return new Integer[newsize]; 271 | } 272 | Integer[] newarr = new Integer[newsize]; 273 | System.arraycopy(old, 0, newarr, 0, old.length); 274 | return newarr; 275 | } 276 | 277 | public static long[] realloc(long[] old, int newsize) { 278 | if (old == null || newsize == 0) { 279 | return new long[newsize]; 280 | } 281 | long[] newarr = new long[newsize]; 282 | System.arraycopy(old, 0, newarr, 0, old.length); 283 | return newarr; 284 | } 285 | 286 | public static double[] realloc(double[] old, int newsize) { 287 | if (old == null || newsize == 0) { 288 | return new double[newsize]; 289 | } 290 | double[] newarr = new double[newsize]; 291 | System.arraycopy(old, 0, newarr, 0, old.length); 292 | return newarr; 293 | } 294 | 295 | public static byte[] realloc(byte[] old, int newsize) { 296 | if (old == null || newsize == 0) { 297 | return new byte[newsize]; 298 | } 299 | byte[] newarr = new byte[newsize]; 300 | System.arraycopy(old, 0, newarr, 0, old.length); 301 | return newarr; 302 | } 303 | 304 | public static char[] realloc(char[] old, int newsize) { 305 | if (old == null || newsize == 0) { 306 | return new char[newsize]; 307 | } 308 | char[] newarr = new char[newsize]; 309 | System.arraycopy(old, 0, newarr, 0, old.length); 310 | return newarr; 311 | } 312 | 313 | public static boolean[] realloc(boolean[] old, int newsize) { 314 | if (old == null || newsize == 0) { 315 | return new boolean[newsize]; 316 | } 317 | boolean[] newarr = new boolean[newsize]; 318 | System.arraycopy(old, 0, newarr, 0, old.length); 319 | return newarr; 320 | } 321 | 322 | public static short[] realloc(short[] old, int newsize) { 323 | if (old == null || newsize == 0) { 324 | return new short[newsize]; 325 | } 326 | short[] newarr = new short[newsize]; 327 | System.arraycopy(old, 0, newarr, 0, old.length); 328 | return newarr; 329 | } 330 | 331 | public static TValue[] realloc(TValue[] old, int newsize) { 332 | if (old == null || newsize == 0) { 333 | return new TValue[newsize]; 334 | } 335 | TValue[] newarr = new TValue[newsize]; 336 | System.arraycopy(old, 0, newarr, 0, old.length); 337 | return newarr; 338 | } 339 | 340 | public static Instruction[] realloc(Instruction[] old, int newsize) { 341 | if (old == null || newsize == 0) { 342 | return new Instruction[newsize]; 343 | } 344 | Instruction[] newarr = new Instruction[newsize]; 345 | System.arraycopy(old, 0, newarr, 0, old.length); 346 | return newarr; 347 | } 348 | 349 | public static Proto[] realloc(Proto[] old, int newsize) { 350 | if (old == null || newsize == 0) { 351 | return new Proto[newsize]; 352 | } 353 | Proto[] newarr = new Proto[newsize]; 354 | System.arraycopy(old, 0, newarr, 0, old.length); 355 | return newarr; 356 | } 357 | 358 | public static LocVar[] realloc(LocVar[] old, int newsize) { 359 | if (old == null || newsize == 0) { 360 | return new LocVar[newsize]; 361 | } 362 | LocVar[] newarr = new LocVar[newsize]; 363 | System.arraycopy(old, 0, newarr, 0, old.length); 364 | return newarr; 365 | } 366 | 367 | public static Upvaldesc[] realloc(Upvaldesc[] old, int newsize) { 368 | if (old == null || newsize == 0) { 369 | return new Upvaldesc[newsize]; 370 | } 371 | Upvaldesc[] newarr = new Upvaldesc[newsize]; 372 | System.arraycopy(old, 0, newarr, 0, old.length); 373 | return newarr; 374 | } 375 | 376 | public static byte[] readFile(String path) throws IOException { 377 | FileInputStream fis = new FileInputStream(path); 378 | byte[] data = new byte[fis.available()]; 379 | fis.read(data); 380 | fis.close(); 381 | return data; 382 | } 383 | 384 | public static void writeFile(String path, byte[] data) throws IOException { 385 | FileOutputStream fos = new FileOutputStream(path); 386 | fos.write(data); 387 | fos.close(); 388 | } 389 | 390 | public static String safeToVarString(Proto p, int i) { 391 | if (i < 0) { 392 | return "nil"; 393 | } 394 | if (i >= p.sizek()) { 395 | return "k" + i; 396 | } 397 | return p.k[i].toVarString(); 398 | } 399 | 400 | public static enum StringContentLevel { 401 | STR_CONTENT_STRING, 402 | STR_CONTENT_BUFFER, 403 | } 404 | 405 | public static StringContentLevel TStringCheck(byte[] str) { 406 | boolean passAllSymbolAnd09azAz = true;//是否全是符号 407 | int i; 408 | byte[] str2 = new byte[str.length]; 409 | for (i = 0; i < str.length; i++) { 410 | if (str[i] < 32 || str[i] > 126) { 411 | passAllSymbolAnd09azAz = false; 412 | str2[i] = str[i]; 413 | } else { 414 | str2[i] = (byte) 'a';//字符有问题,很奇怪 415 | } 416 | } 417 | if (passAllSymbolAnd09azAz) { 418 | return StringContentLevel.STR_CONTENT_STRING; 419 | } 420 | //测试UTF8和GBK编码,没通过那就认为是乱码 421 | CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder(); 422 | try { 423 | decoder.decode(ByteBuffer.wrap(str2)); 424 | } catch (CharacterCodingException e) { 425 | return StringContentLevel.STR_CONTENT_BUFFER; 426 | } 427 | decoder = Charset.forName("GBK").newDecoder(); 428 | try { 429 | decoder.decode(ByteBuffer.wrap(str2)); 430 | } catch (CharacterCodingException e) { 431 | return StringContentLevel.STR_CONTENT_BUFFER; 432 | } 433 | return StringContentLevel.STR_CONTENT_STRING; 434 | } 435 | 436 | public static int hexvalue(int c) { 437 | return c <= '9' ? c - '0' : c <= 'F' ? c + 10 - 'A' : c + 10 - 'a'; 438 | } 439 | 440 | public static boolean isxdigit(int c) { 441 | return (c >= '0' && c <= '9') 442 | || (c >= 'a' && c <= 'f') 443 | || (c >= 'A' && c <= 'F'); 444 | } 445 | 446 | public static TValue readAsTString(String str) { 447 | byte[] strbuf = str.getBytes(); 448 | byte[] savebuff = new byte[strbuf.length]; 449 | int save = 0; 450 | int pos = 0; 451 | pos++; /* skip the first `"' */ 452 | int current = strbuf[pos++]; 453 | boolean doBreak = false; 454 | while (current != '"' && pos < strbuf.length) { 455 | if (doBreak) { 456 | break; 457 | } 458 | switch (current) { 459 | case '\n': 460 | case '\r': 461 | throw new IllegalArgumentException("未完善的字符串"); 462 | case '\\': { 463 | int c = 0; 464 | current = strbuf[pos++];//skip the first `\' 465 | switch (current) { 466 | case '\\': 467 | c = '\\'; 468 | break; 469 | case 't': 470 | c = '\t'; 471 | break; 472 | case 'f': 473 | c = '\f'; 474 | break; 475 | case 'n': 476 | c = '\n'; 477 | break; 478 | case 'r': 479 | c = '\r'; 480 | break; 481 | case '0': 482 | c = '\0'; 483 | break; 484 | case '"': 485 | c = '"'; 486 | break; 487 | case 'b': 488 | c = '\b'; 489 | break; 490 | case 'x': { 491 | if (pos < strbuf.length) { 492 | current = strbuf[pos++]; 493 | } else { 494 | doBreak = true; 495 | break; 496 | } 497 | int c1 = current; 498 | if (pos < strbuf.length) { 499 | current = strbuf[pos++]; 500 | } else { 501 | doBreak = true; 502 | break; 503 | } 504 | int c2 = current; 505 | if (!isxdigit(c1) || !isxdigit(c2)) 506 | throw new IllegalArgumentException("期待HEX编码符号,但是得到:0x" + ((char) c1) + ((char) c2)); 507 | c = (hexvalue(c1) << 4) + hexvalue(c2); 508 | break; 509 | } 510 | default: { 511 | throw new IllegalArgumentException("转义符错误:只支持的转义符:\\\\,\\t,\\f,\\n,\\r,\\0,\\\",\\b,\\x,当前得到" + (char) current); 512 | } 513 | } 514 | savebuff[save++] = (byte) c; 515 | if (pos < strbuf.length) { 516 | current = strbuf[pos++]; 517 | } else { 518 | doBreak = true; 519 | } 520 | continue; 521 | } 522 | default: { 523 | savebuff[save++] = (byte) current; 524 | current = strbuf[pos++]; 525 | break; 526 | } 527 | } 528 | } 529 | if (current != '"') { 530 | throw new IllegalArgumentException("字符串未完结"); 531 | } 532 | return TValue.createString(savebuff, save); 533 | } 534 | } 535 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/Lexer.java: -------------------------------------------------------------------------------- 1 | package com.nwdxlgzs.xasm; 2 | 3 | public class Lexer { 4 | 5 | private CharSequence source; 6 | protected int bufferLen; 7 | private int line; 8 | private int column; 9 | private int index; 10 | protected int offset; 11 | protected int length; 12 | private TokenState currentTokenState; 13 | private TokenState lastTokenState; 14 | 15 | private String[] protoKeywords = { 16 | "sub-parse", 17 | "source", 18 | "is_vararg", 19 | "maxstacksize", 20 | "numparams", 21 | "linedefined", 22 | "lastlinedefined", 23 | "locvars", 24 | "upvaldesc", 25 | }; 26 | 27 | private String[] functionKeywords = { 28 | "function", "end" 29 | }; 30 | 31 | private String[] codeKeywords = { 32 | "code-start", "code-end", "line" 33 | }; 34 | 35 | private String[] valueKeyWords = { 36 | "true", "false", "nil", "null" 37 | }; 38 | 39 | private String[] opCodeKeyWords = { 40 | "unknown", 41 | "move", 42 | "loadk", 43 | "loadkx", 44 | "loadbool", 45 | "loadnil", 46 | "getupval", 47 | "gettabup", 48 | "gettable", 49 | "settabup", 50 | "setupval", 51 | "settable", 52 | "newtable", 53 | "self", 54 | "add", 55 | "sub", 56 | "mul", 57 | "mod", 58 | "pow", 59 | "div", 60 | "idiv", 61 | "band", 62 | "bor", 63 | "bxor", 64 | "shl", 65 | "shr", 66 | "unm", 67 | "bnot", 68 | "not", 69 | "len", 70 | "concat", 71 | "jmp", 72 | "eq", 73 | "lt", 74 | "le", 75 | "test", 76 | "testset", 77 | "call", 78 | "tailcall", 79 | "return", 80 | "forloop", 81 | "forprep", 82 | "tforcall", 83 | "tforloop", 84 | "setlist", 85 | "closure", 86 | "vararg", 87 | "extraarg", 88 | //下头三个是nirenr的Androlua+自定义指令,其中TFOREACH只是保留指令,还未实现 89 | "tbc", 90 | "newarray", 91 | "tforeach", 92 | 93 | "neq", 94 | "nlt", 95 | "nle", 96 | "func", 97 | "def", 98 | }; 99 | 100 | public Lexer(CharSequence src) { 101 | if (src == null) { 102 | throw new IllegalArgumentException("输入不能为空"); 103 | } 104 | this.source = src; 105 | init(); 106 | } 107 | 108 | private void init() { 109 | line = 0; 110 | column = 0; 111 | length = 0; 112 | index = 0; 113 | currentTokenState = new TokenState(Tokens.WHITESPACE, length, offset); 114 | this.bufferLen = source.length(); 115 | } 116 | 117 | public void reset() { 118 | init(); 119 | } 120 | 121 | public LexerSnapshot snapshot() { 122 | return new LexerSnapshot(); 123 | } 124 | 125 | public int getTokenLength() { 126 | return length; 127 | } 128 | 129 | public String getTokenText() { 130 | if (index + length > bufferLen) { 131 | return source.subSequence(index, bufferLen).toString(); 132 | } 133 | return source.subSequence(index, index + length).toString(); 134 | } 135 | 136 | public int getLine() { 137 | return line; 138 | } 139 | 140 | public int getColumn() { 141 | return column; 142 | } 143 | 144 | public int getIndex() { 145 | return index; 146 | } 147 | 148 | public Tokens getToken() { 149 | return currentTokenState.token; 150 | } 151 | 152 | private char peekCharWithLength(int i) { 153 | return source.charAt(offset + length + i - 1); 154 | } 155 | 156 | public void gotoNextToken(Tokens tk, boolean justSkipUselessToken) { 157 | while (true) { 158 | Tokens token = nextToken(); 159 | if (token == Lexer.Tokens.EOF || token == tk) { 160 | return; 161 | } 162 | if (justSkipUselessToken) { 163 | if (token == Tokens.WHITESPACE || token == Tokens.NEWLINE || token == Tokens.LINE_COMMENT || 164 | token == Tokens.OPERATOR || token == Tokens.SEMICOLON) { 165 | continue; 166 | } else { 167 | throw new RuntimeException("语法错误:未期待的令牌" + token); 168 | } 169 | } 170 | } 171 | } 172 | 173 | public Tokens skipUselessToken() { 174 | while (true) { 175 | Tokens token = nextToken(); 176 | if (token == Lexer.Tokens.EOF) { 177 | return token; 178 | } 179 | if (token == Tokens.WHITESPACE || token == Tokens.NEWLINE || token == Tokens.LINE_COMMENT || 180 | token == Tokens.OPERATOR || token == Tokens.SEMICOLON) { 181 | continue; 182 | } else { 183 | return token; 184 | } 185 | } 186 | } 187 | 188 | public boolean testNextToken(Tokens tk, boolean backIfNotMatch, boolean skipUselessToken) { 189 | LexerSnapshot snapshot = new LexerSnapshot(); 190 | while (true) { 191 | Tokens token = nextToken(); 192 | if (token == tk) { 193 | return true; 194 | } 195 | if (token == Lexer.Tokens.EOF) { 196 | return false; 197 | } 198 | if (skipUselessToken) { 199 | if (token == Tokens.WHITESPACE || token == Tokens.NEWLINE || token == Tokens.LINE_COMMENT || 200 | token == Tokens.OPERATOR || token == Tokens.SEMICOLON) { 201 | continue; 202 | } else { 203 | if (backIfNotMatch) { 204 | snapshot.restore(); 205 | } 206 | return false; 207 | } 208 | } 209 | } 210 | } 211 | 212 | public Tokens nextToken() { 213 | lastTokenState = currentTokenState; 214 | return (currentTokenState = calcLineAndColumn(nextTokenInternal())).token; 215 | } 216 | 217 | private char peekNextChar() { 218 | return source.charAt(offset); 219 | } 220 | 221 | private char peekCharWithLength() { 222 | return source.charAt(offset + length); 223 | } 224 | 225 | private char peekChar(int offset) { 226 | return source.charAt(offset); 227 | } 228 | 229 | private TokenState wrapState(Tokens token) { 230 | return new TokenState(token, length, offset); 231 | } 232 | 233 | private TokenState calcLineAndColumn(Tokens result) { 234 | column += lastTokenState.length; 235 | 236 | if (lastTokenState.token == Tokens.NEWLINE) { 237 | line++; 238 | column = 0; 239 | } 240 | 241 | return wrapState(result); 242 | } 243 | 244 | private Tokens nextTokenInternal() { 245 | 246 | index = index + length; 247 | offset = offset + length; 248 | if (offset >= bufferLen) { 249 | return Tokens.EOF; 250 | } 251 | 252 | char ch = peekNextChar(); 253 | length = 1; 254 | 255 | //分析简单char 256 | if (ch == '\n') { 257 | return Tokens.NEWLINE; 258 | } else if (ch == '\r') { 259 | line++; 260 | scanNewline(); 261 | return Tokens.NEWLINE; 262 | } else if (ch == '$') { 263 | while (offset + length < bufferLen && peekCharWithLength() != '\n') { 264 | length++; 265 | } 266 | return Tokens.LINE_COMMENT; 267 | } else if (ch == ';') { 268 | return Tokens.SEMICOLON; 269 | } 270 | 271 | //空格 272 | if (isWhitespace(ch)) { 273 | char chLocal; 274 | while (isWhitespace(chLocal = peekCharWithLength())) { 275 | if (chLocal == '\r' || chLocal == '\n' || offset + length < bufferLen) { 276 | break; 277 | } 278 | length++; 279 | } 280 | return Tokens.WHITESPACE; 281 | } 282 | 283 | //数字 284 | if (isDigit(ch)) { 285 | return scanNumber(); 286 | } 287 | 288 | // keyword 289 | if (isLetter(ch)) { 290 | return scanIdentifier(); 291 | } 292 | 293 | //为点 294 | if (ch == '.') { 295 | char nextChar = peekCharWithLength(1); 296 | 297 | if (nextChar == '.') { 298 | // .. 299 | return Tokens.OP_KEYWORD; 300 | } 301 | 302 | if (isLetter(nextChar)) { 303 | // 这里是移除点 304 | index++; 305 | /*length--;*/ 306 | Tokens result = scanIdentifier(); 307 | //还是得加回来的。 308 | index--; 309 | return result; 310 | } 311 | 312 | 313 | return Tokens.DOT; 314 | } 315 | 316 | //处理字符串 317 | if (ch == '"') { 318 | return scanString(); 319 | } 320 | 321 | //处理opcode 322 | //有的opcode使用多个符号,需要消费长度 323 | if (ch == '~') { 324 | // ~ ~= ~() 325 | ch = peekCharWithLength(1); 326 | if (ch == '=') { 327 | // ~= 328 | length++; 329 | } else if (ch == '(' && (((length++) > 0) && matchBracket('(', ')'))) { 330 | // ~() 331 | length++; 332 | } 333 | return Tokens.OP_KEYWORD; 334 | } else if (ch == '/') { 335 | if (matchBracket('/', '/')) { 336 | // '//' 337 | length++; 338 | } 339 | return Tokens.OP_KEYWORD; 340 | } else if (ch == '&') { 341 | return Tokens.OP_KEYWORD; 342 | } else if (ch == '#') { 343 | return Tokens.OP_KEYWORD; 344 | } else if (ch == '|') { 345 | return Tokens.OP_KEYWORD; 346 | } else if (ch == '+') { 347 | return Tokens.OP_KEYWORD; 348 | } else if (ch == '*') { 349 | return Tokens.OP_KEYWORD; 350 | } else if (ch == '^') { 351 | return Tokens.OP_KEYWORD; 352 | } else if (ch == '=' && matchBracket('=', '=')) { 353 | // == 354 | length++; 355 | return Tokens.OP_KEYWORD; 356 | } else if (ch == '{' && matchBracket('{', '}')) { 357 | // {} 358 | length++; 359 | return Tokens.OP_KEYWORD; 360 | } else if (ch == '[' && matchBracket('[', ']')) { 361 | // {} 362 | length++; 363 | return Tokens.OP_KEYWORD; 364 | } else if (ch == '!' && matchBracket('!', '=')) { 365 | // {} 366 | length++; 367 | return Tokens.OP_KEYWORD; 368 | } else if (ch == '[' && matchBracket('[', ']')) { 369 | // [] 370 | length++; 371 | return Tokens.OP_KEYWORD; 372 | } else if (ch == '-') { 373 | // - -() 374 | ch = peekCharWithLength(1); 375 | if (ch == '(' && (((length++) > 0) && matchBracket('(', ')'))) { 376 | // -() 377 | length++; 378 | } else if (ch == '>') { 379 | // -> 380 | length++; 381 | return Tokens.OPERATOR; 382 | } 383 | return Tokens.OP_KEYWORD; 384 | } else if (ch == '<') { 385 | // < <= << 386 | if (matchBracket('<', '=')) { 387 | // <= 388 | length++; 389 | } else if (matchBracket('<', '<')) { 390 | // << 391 | length++; 392 | } 393 | return Tokens.OP_KEYWORD; 394 | } else if (ch == '>') { 395 | // > >= >> 396 | 397 | if (matchBracket('>', '=')) { 398 | // >= 399 | length++; 400 | } else if (matchBracket('>', '>')) { 401 | // >> 402 | length++; 403 | } 404 | return Tokens.OP_KEYWORD; 405 | } 406 | 407 | return Tokens.UNKNOWN; 408 | } 409 | 410 | private Tokens scanNumber() { 411 | char ch; 412 | boolean hasDot = false; 413 | while (offset + length < bufferLen) { 414 | boolean isDigit = isDigit((ch = peekCharWithLength())); 415 | if (!isDigit && ch == '.') { 416 | if (hasDot) { 417 | throw new RuntimeException("错误的语法!在 (" + line + "," + (column + length) + ") 处 重复定义了."); 418 | } else { 419 | hasDot = true; 420 | } 421 | } else if (!isDigit) { 422 | break; 423 | } 424 | length++; 425 | } 426 | return hasDot ? Tokens.FLOAT_LITERAL : Tokens.INTEGER_LITERAL; 427 | } 428 | 429 | private boolean matchBracket(char left, char right) { 430 | char currentLeft = peekCharWithLength(0); 431 | char currentRight = peekCharWithLength(1); 432 | return currentLeft == left && currentRight == right; 433 | } 434 | 435 | protected final void throwIfNeeded() { 436 | if (offset + length == bufferLen) { 437 | throw new RuntimeException("太大的Token!考虑语法错误"); 438 | } 439 | } 440 | 441 | 442 | protected final boolean isNumber(String str) { 443 | boolean isNumber = true; 444 | int index = 0; 445 | while (index < str.length()) { 446 | if (!isDigit(str.charAt(index))) { 447 | isNumber = false; 448 | break; 449 | } 450 | index++; 451 | } 452 | return isNumber; 453 | } 454 | 455 | protected Tokens scanString() { 456 | throwIfNeeded(); 457 | 458 | char current = 0; 459 | 460 | //由于有转义符号的存在,不能直接判断是否为"\" 461 | while (true) { 462 | current = peekCharWithLength(); 463 | 464 | length++; 465 | 466 | if (current == '"' || current == '\n') { 467 | break; 468 | } 469 | 470 | if (current == '\\') { 471 | current = peekCharWithLength(); 472 | if (current == '\\' || current == 't' || current == 'f' || current == 'n' || current == 'r' || current == '0' || current == '\"' || current == 'b') { 473 | length++; 474 | } 475 | } 476 | 477 | 478 | if (offset + length >= bufferLen) { 479 | throw new RuntimeException("缺少正常的\""); 480 | } 481 | 482 | } 483 | 484 | 485 | return Tokens.STRING; 486 | } 487 | 488 | protected Tokens scanIdentifier() { 489 | throwIfNeeded(); 490 | 491 | //对于标识符来说,只要不遇到空格符就是合法的 492 | //其他校检我暂时懒得做了 493 | //呃不对,还有注释啥的。。 494 | char ch; 495 | while (!isWhitespace((ch = peekCharWithLength()))) { 496 | if (isSymbol(ch)) { 497 | break; 498 | } 499 | length++; 500 | } 501 | 502 | 503 | String tokenText = getTokenText(); 504 | 505 | for (String keyword : functionKeywords) { 506 | if (tokenText.startsWith(keyword)) { 507 | return Tokens.FUNCTION_KEYWORD; 508 | } 509 | } 510 | 511 | for (String keyword : protoKeywords) { 512 | if (tokenText.startsWith(keyword)) { 513 | return Tokens.PROTO_KEYWORD; 514 | } 515 | } 516 | 517 | for (String keyword : opCodeKeyWords) { 518 | if (tokenText.startsWith(keyword)) { 519 | return Tokens.OP_KEYWORD; 520 | } 521 | } 522 | 523 | // opxx 524 | if (tokenText.startsWith("op")) { 525 | String tokenTextSub = tokenText.substring(2, tokenText.length() - 1); 526 | boolean isNumber = isNumber(tokenTextSub); 527 | if (isNumber) { 528 | return Tokens.OP_KEYWORD; 529 | } 530 | } 531 | 532 | 533 | // goto_ 534 | if (tokenText.startsWith("goto_")) { 535 | String tokenTextSub = tokenText.substring(5, tokenText.length() - 1); 536 | boolean isNumber = isNumber(tokenTextSub); 537 | if (isNumber) { 538 | return Tokens.OP_KEYWORD; 539 | } 540 | } 541 | 542 | // rxx,uxx,kxx,pxx 543 | if (tokenText.length() > 1 && (tokenText.charAt(0) == 'r' || tokenText.charAt(0) == 'k' || 544 | tokenText.charAt(0) == 'u' || tokenText.charAt(0) == 'p')) { 545 | 546 | String tokenTextSub = tokenText.substring(1, tokenText.length() - 1); 547 | boolean isNumber = isNumber(tokenTextSub); 548 | if (isNumber) { 549 | return Tokens.OP_ARG; 550 | } 551 | } 552 | 553 | for (String keyword : valueKeyWords) { 554 | if (tokenText.startsWith(keyword)) { 555 | return Tokens.VALUE_KEYWORD; 556 | } 557 | } 558 | 559 | for (String keyword : codeKeywords) { 560 | if (tokenText.startsWith(keyword)) { 561 | return Tokens.CODE_KEYWORD; 562 | } 563 | } 564 | 565 | return Tokens.IDENTIFIER; 566 | } 567 | 568 | protected void scanNewline() { 569 | if (offset + length < bufferLen && peekChar(offset + length) == '\n') { 570 | length++; 571 | } 572 | } 573 | 574 | protected static boolean isLetter(char c) { 575 | return (c >= 'a' && c <= 'z') || c == '_' || (c >= 'A' && c <= 'Z'); 576 | } 577 | 578 | protected static boolean isDigit(char c) { 579 | return (c >= '0' && c <= '9'); 580 | } 581 | 582 | protected static boolean isSymbol(char c) { 583 | return (c == '$' || c == '>' || c == '<' || c == ';' || c == '.'); 584 | } 585 | 586 | protected static boolean isWhitespace(char c) { 587 | return (c == '\t' || c == ' ' || c == '\f' || c == '\n' || c == '\r'); 588 | } 589 | 590 | 591 | protected static class TokenState { 592 | Tokens token; 593 | int length; 594 | int offset; 595 | 596 | public TokenState(Tokens token, int length, int offset) { 597 | this.token = token; 598 | this.length = length; 599 | this.offset = offset; 600 | } 601 | } 602 | 603 | public class LexerSnapshot { 604 | private int oldIndex; 605 | private int oldOffset; 606 | private int oldLength; 607 | private int oldLine; 608 | private int oldColumn; 609 | private TokenState oldCurrentTokenState; 610 | private TokenState oldLastTokenState; 611 | 612 | public LexerSnapshot() { 613 | oldIndex = index; 614 | oldOffset = offset; 615 | oldLength = length; 616 | oldLine = line; 617 | oldColumn = column; 618 | oldCurrentTokenState = currentTokenState; 619 | oldLastTokenState = lastTokenState; 620 | } 621 | 622 | public void restore() { 623 | index = oldIndex; 624 | offset = oldOffset; 625 | length = oldLength; 626 | line = oldLine; 627 | column = oldColumn; 628 | currentTokenState = oldCurrentTokenState; 629 | lastTokenState = oldLastTokenState; 630 | } 631 | 632 | } 633 | 634 | public enum Tokens { 635 | WHITESPACE, NEWLINE, UNKNOWN, EOF, 636 | LINE_COMMENT, 637 | IDENTIFIER, 638 | INTEGER_LITERAL, FLOAT_LITERAL, 639 | STRING, 640 | DOT, OPERATOR, SEMICOLON, 641 | PROTO_KEYWORD, CODE_KEYWORD, FUNCTION_KEYWORD, 642 | OP_KEYWORD, OP_ARG, VALUE_KEYWORD 643 | } 644 | } 645 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International 2 | 3 | Creative Commons Corporation ("Creative Commons") is not a law firm and 4 | does not provide legal services or legal advice. Distribution of 5 | Creative Commons public licenses does not create a lawyer-client or 6 | other relationship. Creative Commons makes its licenses and related 7 | information available on an "as-is" basis. Creative Commons gives no 8 | warranties regarding its licenses, any material licensed under their 9 | terms and conditions, or any related information. Creative Commons 10 | disclaims all liability for damages resulting from their use to the 11 | fullest extent possible. 12 | 13 | Using Creative Commons Public Licenses 14 | 15 | Creative Commons public licenses provide a standard set of terms and 16 | conditions that creators and other rights holders may use to share 17 | original works of authorship and other material subject to copyright and 18 | certain other rights specified in the public license below. The 19 | following considerations are for informational purposes only, are not 20 | exhaustive, and do not form part of our licenses. 21 | 22 | Considerations for licensors: Our public licenses are intended for use 23 | by those authorized to give the public permission to use material in 24 | ways otherwise restricted by copyright and certain other rights. Our 25 | licenses are irrevocable. Licensors should read and understand the terms 26 | and conditions of the license they choose before applying it. Licensors 27 | should also secure all rights necessary before applying our licenses so 28 | that the public can reuse the material as expected. Licensors should 29 | clearly mark any material not subject to the license. This includes 30 | other CC-licensed material, or material used under an exception or 31 | limitation to copyright. More considerations for licensors : 32 | wiki.creativecommons.org/Considerations\_for\_licensors 33 | 34 | Considerations for the public: By using one of our public licenses, a 35 | licensor grants the public permission to use the licensed material under 36 | specified terms and conditions. If the licensor's permission is not 37 | necessary for any reason–for example, because of any applicable 38 | exception or limitation to copyright–then that use is not regulated by 39 | the license. Our licenses grant only permissions under copyright and 40 | certain other rights that a licensor has authority to grant. Use of the 41 | licensed material may still be restricted for other reasons, including 42 | because others have copyright or other rights in the material. A 43 | licensor may make special requests, such as asking that all changes be 44 | marked or described. Although not required by our licenses, you are 45 | encouraged to respect those requests where reasonable. More 46 | considerations for the public : 47 | wiki.creativecommons.org/Considerations\_for\_licensees 48 | 49 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International 50 | Public License 51 | 52 | By exercising the Licensed Rights (defined below), You accept and agree 53 | to be bound by the terms and conditions of this Creative Commons 54 | Attribution-NonCommercial-ShareAlike 4.0 International Public License 55 | ("Public License"). To the extent this Public License may be interpreted 56 | as a contract, You are granted the Licensed Rights in consideration of 57 | Your acceptance of these terms and conditions, and the Licensor grants 58 | You such rights in consideration of benefits the Licensor receives from 59 | making the Licensed Material available under these terms and conditions. 60 | 61 | Section 1 – Definitions. 62 | 63 | - a. Adapted Material means material subject to Copyright and Similar 64 | Rights that is derived from or based upon the Licensed Material and 65 | in which the Licensed Material is translated, altered, arranged, 66 | transformed, or otherwise modified in a manner requiring permission 67 | under the Copyright and Similar Rights held by the Licensor. For 68 | purposes of this Public License, where the Licensed Material is a 69 | musical work, performance, or sound recording, Adapted Material is 70 | always produced where the Licensed Material is synched in timed 71 | relation with a moving image. 72 | - b. Adapter's License means the license You apply to Your Copyright 73 | and Similar Rights in Your contributions to Adapted Material in 74 | accordance with the terms and conditions of this Public License. 75 | - c. BY-NC-SA Compatible License means a license listed at 76 | creativecommons.org/compatiblelicenses, approved by Creative Commons 77 | as essentially the equivalent of this Public License. 78 | - d. Copyright and Similar Rights means copyright and/or similar 79 | rights closely related to copyright including, without limitation, 80 | performance, broadcast, sound recording, and Sui Generis Database 81 | Rights, without regard to how the rights are labeled or categorized. 82 | For purposes of this Public License, the rights specified in Section 83 | 2(b)(1)-(2) are not Copyright and Similar Rights. 84 | - e. Effective Technological Measures means those measures that, in 85 | the absence of proper authority, may not be circumvented under laws 86 | fulfilling obligations under Article 11 of the WIPO Copyright Treaty 87 | adopted on December 20, 1996, and/or similar international 88 | agreements. 89 | - f. Exceptions and Limitations means fair use, fair dealing, and/or 90 | any other exception or limitation to Copyright and Similar Rights 91 | that applies to Your use of the Licensed Material. 92 | - g. License Elements means the license attributes listed in the name 93 | of a Creative Commons Public License. The License Elements of this 94 | Public License are Attribution, NonCommercial, and ShareAlike. 95 | - h. Licensed Material means the artistic or literary work, database, 96 | or other material to which the Licensor applied this Public License. 97 | - i. Licensed Rights means the rights granted to You subject to the 98 | terms and conditions of this Public License, which are limited to 99 | all Copyright and Similar Rights that apply to Your use of the 100 | Licensed Material and that the Licensor has authority to license. 101 | - j. Licensor means the individual(s) or entity(ies) granting rights 102 | under this Public License. 103 | - k. NonCommercial means not primarily intended for or directed 104 | towards commercial advantage or monetary compensation. For purposes 105 | of this Public License, the exchange of the Licensed Material for 106 | other material subject to Copyright and Similar Rights by digital 107 | file-sharing or similar means is NonCommercial provided there is no 108 | payment of monetary compensation in connection with the exchange. 109 | - l. Share means to provide material to the public by any means or 110 | process that requires permission under the Licensed Rights, such as 111 | reproduction, public display, public performance, distribution, 112 | dissemination, communication, or importation, and to make material 113 | available to the public including in ways that members of the public 114 | may access the material from a place and at a time individually 115 | chosen by them. 116 | - m. Sui Generis Database Rights means rights other than copyright 117 | resulting from Directive 96/9/EC of the European Parliament and of 118 | the Council of 11 March 1996 on the legal protection of databases, 119 | as amended and/or succeeded, as well as other essentially equivalent 120 | rights anywhere in the world. 121 | - n. You means the individual or entity exercising the Licensed Rights 122 | under this Public License. Your has a corresponding meaning. 123 | 124 | Section 2 – Scope. 125 | 126 | - a. License grant. 127 | - 1. Subject to the terms and conditions of this Public License, 128 | the Licensor hereby grants You a worldwide, royalty-free, 129 | non-sublicensable, non-exclusive, irrevocable license to 130 | exercise the Licensed Rights in the Licensed Material to: 131 | - A. reproduce and Share the Licensed Material, in whole or in 132 | part, for NonCommercial purposes only; and 133 | - B. produce, reproduce, and Share Adapted Material for 134 | NonCommercial purposes only. 135 | - 2. Exceptions and Limitations. For the avoidance of doubt, where 136 | Exceptions and Limitations apply to Your use, this Public 137 | License does not apply, and You do not need to comply with its 138 | terms and conditions. 139 | - 3. Term. The term of this Public License is specified in Section 140 | 6(a). 141 | - 4. Media and formats; technical modifications allowed. The 142 | Licensor authorizes You to exercise the Licensed Rights in all 143 | media and formats whether now known or hereafter created, and to 144 | make technical modifications necessary to do so. The Licensor 145 | waives and/or agrees not to assert any right or authority to 146 | forbid You from making technical modifications necessary to 147 | exercise the Licensed Rights, including technical modifications 148 | necessary to circumvent Effective Technological Measures. For 149 | purposes of this Public License, simply making modifications 150 | authorized by this Section 2(a)(4) never produces Adapted 151 | Material. 152 | - 5. Downstream recipients. 153 | - A. Offer from the Licensor – Licensed Material. Every 154 | recipient of the Licensed Material automatically receives an 155 | offer from the Licensor to exercise the Licensed Rights 156 | under the terms and conditions of this Public License. 157 | - B. Additional offer from the Licensor – Adapted Material. 158 | Every recipient of Adapted Material from You automatically 159 | receives an offer from the Licensor to exercise the Licensed 160 | Rights in the Adapted Material under the conditions of the 161 | Adapter's License You apply. 162 | - C. No downstream restrictions. You may not offer or impose 163 | any additional or different terms or conditions on, or apply 164 | any Effective Technological Measures to, the Licensed 165 | Material if doing so restricts exercise of the Licensed 166 | Rights by any recipient of the Licensed Material. 167 | - 6. No endorsement. Nothing in this Public License constitutes or 168 | may be construed as permission to assert or imply that You are, 169 | or that Your use of the Licensed Material is, connected with, or 170 | sponsored, endorsed, or granted official status by, the Licensor 171 | or others designated to receive attribution as provided in 172 | Section 3(a)(1)(A)(i). 173 | - b. Other rights. 174 | - 1. Moral rights, such as the right of integrity, are not 175 | licensed under this Public License, nor are publicity, privacy, 176 | and/or other similar personality rights; however, to the extent 177 | possible, the Licensor waives and/or agrees not to assert any 178 | such rights held by the Licensor to the limited extent necessary 179 | to allow You to exercise the Licensed Rights, but not otherwise. 180 | - 2. Patent and trademark rights are not licensed under this 181 | Public License. 182 | - 3. To the extent possible, the Licensor waives any right to 183 | collect royalties from You for the exercise of the Licensed 184 | Rights, whether directly or through a collecting society under 185 | any voluntary or waivable statutory or compulsory licensing 186 | scheme. In all other cases the Licensor expressly reserves any 187 | right to collect such royalties, including when the Licensed 188 | Material is used other than for NonCommercial purposes. 189 | 190 | Section 3 – License Conditions. 191 | 192 | Your exercise of the Licensed Rights is expressly made subject to the 193 | following conditions. 194 | 195 | - a. Attribution. 196 | - 1. If You Share the Licensed Material (including in modified 197 | form), You must: 198 | - A. retain the following if it is supplied by the Licensor 199 | with the Licensed Material: 200 | - i. identification of the creator(s) of the Licensed 201 | Material and any others designated to receive 202 | attribution, in any reasonable manner requested by the 203 | Licensor (including by pseudonym if designated); 204 | - ii. a copyright notice; 205 | - iii. a notice that refers to this Public License; 206 | - iv. a notice that refers to the disclaimer of 207 | warranties; 208 | - v. a URI or hyperlink to the Licensed Material to the 209 | extent reasonably practicable; 210 | 211 | - B. indicate if You modified the Licensed Material and retain 212 | an indication of any previous modifications; and 213 | - C. indicate the Licensed Material is licensed under this 214 | Public License, and include the text of, or the URI or 215 | hyperlink to, this Public License. 216 | - 2. You may satisfy the conditions in Section 3(a)(1) in any 217 | reasonable manner based on the medium, means, and context in 218 | which You Share the Licensed Material. For example, it may be 219 | reasonable to satisfy the conditions by providing a URI or 220 | hyperlink to a resource that includes the required information. 221 | - 3. If requested by the Licensor, You must remove any of the 222 | information required by Section 3(a)(1)(A) to the extent 223 | reasonably practicable. 224 | - b. ShareAlike.In addition to the conditions in Section 3(a), if You 225 | Share Adapted Material You produce, the following conditions also 226 | apply. 227 | - 1. The Adapter's License You apply must be a Creative Commons 228 | license with the same License Elements, this version or later, 229 | or a BY-NC-SA Compatible License. 230 | - 2. You must include the text of, or the URI or hyperlink to, the 231 | Adapter's License You apply. You may satisfy this condition in 232 | any reasonable manner based on the medium, means, and context in 233 | which You Share Adapted Material. 234 | - 3. You may not offer or impose any additional or different terms 235 | or conditions on, or apply any Effective Technological Measures 236 | to, Adapted Material that restrict exercise of the rights 237 | granted under the Adapter's License You apply. 238 | 239 | Section 4 – Sui Generis Database Rights. 240 | 241 | Where the Licensed Rights include Sui Generis Database Rights that apply 242 | to Your use of the Licensed Material: 243 | 244 | - a. for the avoidance of doubt, Section 2(a)(1) grants You the right 245 | to extract, reuse, reproduce, and Share all or a substantial portion 246 | of the contents of the database for NonCommercial purposes only; 247 | - b. if You include all or a substantial portion of the database 248 | contents in a database in which You have Sui Generis Database 249 | Rights, then the database in which You have Sui Generis Database 250 | Rights (but not its individual contents) is Adapted Material, 251 | including for purposes of Section 3(b); and 252 | - c. You must comply with the conditions in Section 3(a) if You Share 253 | all or a substantial portion of the contents of the database. 254 | For the avoidance of doubt, this Section 4 supplements and does not 255 | replace Your obligations under this Public License where the 256 | Licensed Rights include other Copyright and Similar Rights. 257 | 258 | Section 5 – Disclaimer of Warranties and Limitation of Liability. 259 | 260 | - a. Unless otherwise separately undertaken by the Licensor, to the 261 | extent possible, the Licensor offers the Licensed Material as-is and 262 | as-available, and makes no representations or warranties of any kind 263 | concerning the Licensed Material, whether express, implied, 264 | statutory, or other. This includes, without limitation, warranties 265 | of title, merchantability, fitness for a particular purpose, 266 | non-infringement, absence of latent or other defects, accuracy, or 267 | the presence or absence of errors, whether or not known or 268 | discoverable. Where disclaimers of warranties are not allowed in 269 | full or in part, this disclaimer may not apply to You. 270 | - b. To the extent possible, in no event will the Licensor be liable 271 | to You on any legal theory (including, without limitation, 272 | negligence) or otherwise for any direct, special, indirect, 273 | incidental, consequential, punitive, exemplary, or other losses, 274 | costs, expenses, or damages arising out of this Public License or 275 | use of the Licensed Material, even if the Licensor has been advised 276 | of the possibility of such losses, costs, expenses, or damages. 277 | Where a limitation of liability is not allowed in full or in part, 278 | this limitation may not apply to You. 279 | - c. The disclaimer of warranties and limitation of liability provided 280 | above shall be interpreted in a manner that, to the extent possible, 281 | most closely approximates an absolute disclaimer and waiver of all 282 | liability. 283 | 284 | Section 6 – Term and Termination. 285 | 286 | - a. This Public License applies for the term of the Copyright and 287 | Similar Rights licensed here. However, if You fail to comply with 288 | this Public License, then Your rights under this Public License 289 | terminate automatically. 290 | - b. Where Your right to use the Licensed Material has terminated 291 | under Section 6(a), it reinstates: 292 | 293 | - 1. automatically as of the date the violation is cured, provided 294 | it is cured within 30 days of Your discovery of the violation; 295 | or 296 | - 2. upon express reinstatement by the Licensor. 297 | 298 | For the avoidance of doubt, this Section 6(b) does not affect any 299 | right the Licensor may have to seek remedies for Your violations of 300 | this Public License. 301 | 302 | - c. For the avoidance of doubt, the Licensor may also offer the 303 | Licensed Material under separate terms or conditions or stop 304 | distributing the Licensed Material at any time; however, doing so 305 | will not terminate this Public License. 306 | - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 307 | License. 308 | 309 | Section 7 – Other Terms and Conditions. 310 | 311 | - a. The Licensor shall not be bound by any additional or different 312 | terms or conditions communicated by You unless expressly agreed. 313 | - b. Any arrangements, understandings, or agreements regarding the 314 | Licensed Material not stated herein are separate from and 315 | independent of the terms and conditions of this Public License. 316 | 317 | Section 8 – Interpretation. 318 | 319 | - a. For the avoidance of doubt, this Public License does not, and 320 | shall not be interpreted to, reduce, limit, restrict, or impose 321 | conditions on any use of the Licensed Material that could lawfully 322 | be made without permission under this Public License. 323 | - b. To the extent possible, if any provision of this Public License 324 | is deemed unenforceable, it shall be automatically reformed to the 325 | minimum extent necessary to make it enforceable. If the provision 326 | cannot be reformed, it shall be severed from this Public License 327 | without affecting the enforceability of the remaining terms and 328 | conditions. 329 | - c. No term or condition of this Public License will be waived and no 330 | failure to comply consented to unless expressly agreed to by the 331 | Licensor. 332 | - d. Nothing in this Public License constitutes or may be interpreted 333 | as a limitation upon, or waiver of, any privileges and immunities 334 | that apply to the Licensor or You, including from the legal 335 | processes of any jurisdiction or authority. 336 | 337 | Creative Commons is not a party to its public licenses. Notwithstanding, 338 | Creative Commons may elect to apply one of its public licenses to 339 | material it publishes and in those instances will be considered the 340 | "Licensor." The text of the Creative Commons public licenses is 341 | dedicated to the public domain under the CC0 Public Domain Dedication. 342 | Except for the limited purpose of indicating that material is shared 343 | under a Creative Commons public license or as otherwise permitted by the 344 | Creative Commons policies published at creativecommons.org/policies, 345 | Creative Commons does not authorize the use of the trademark "Creative 346 | Commons" or any other trademark or logo of Creative Commons without its 347 | prior written consent including, without limitation, in connection with 348 | any unauthorized modifications to any of its public licenses or any 349 | other arrangements, understandings, or agreements concerning use of 350 | licensed material. For the avoidance of doubt, this paragraph does not 351 | form part of the public licenses. 352 | 353 | Creative Commons may be contacted at creativecommons.org. 354 | -------------------------------------------------------------------------------- /com/nwdxlgzs/xasm/Disassembler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Xasm汇编文件结构: 3 | * 1:.function到.end之间为一个函数原型 4 | * 2:.function后跟索引路径,根为main,索引路径用/分割,如main/0/1/2 5 | * 3:.sub-parse 是否这个汇编文件也解析了目标函数子函数 6 | * 4:.source 对应Proto的source,nil表示没有 7 | * 5:.is_vararg/.maxstacksize/.numparams/.linedefined/.lastlinedefined 对应Proto的is_vararg/maxstacksize/numparams/linedefined/lastlinedefined 8 | * 6:sizep/sizek/sizecode/sizeupvalues/sizelineinfo/sizelocvars等不使用,根据解析内容自动回补 9 | * 7:.locvars -> 对应Proto的locvars,第一个string为name(可以是nil),第二个int为startpc,第三个int为endpc 10 | * 8:.upvaldesc 对应Proto的upvalues,第一个string为name(可以是nil),第一个int为idx,第一个bool为instack 11 | * 9:.code-start到.code-end为一个块,块内只允许指令数据或者.line 或者.goto_XX存在 12 | * 10:.line 对应Proto的lineinfo,int为行号(特别的,0不会显示,上一次的line和本次一致也会不显示) 13 | * 11:.goto_XX是辅助表示跳转指令的跳转目的地 14 | * 12:每个指令表示结构并不完全一样,请看case分支处注释。 15 | * 13:字符串转义规则:\t\n\b\f\"\r\\\0,\xXX表示16进制字符 16 | */ 17 | package com.nwdxlgzs.xasm; 18 | 19 | import static com.nwdxlgzs.xasm.TValue.*; 20 | import static com.nwdxlgzs.xasm.defines.*; 21 | 22 | public class Disassembler { 23 | private final Proto proto; 24 | private boolean checkIsSub = false; 25 | 26 | public Disassembler(Proto proto) { 27 | this.proto = proto; 28 | } 29 | 30 | public void setCheckIsSub(boolean ck) { 31 | checkIsSub = ck; 32 | } 33 | 34 | public boolean getCheckIsSub() { 35 | return checkIsSub; 36 | } 37 | 38 | private int getSubIndex(Proto f, Proto target, int[] map, int deep, int[][] ret) { 39 | if (target == null || target == proto) return -1; 40 | if (f == null) f = proto; 41 | if (map == null || map.length <= deep) { 42 | map = realloc(map, deep + 1); 43 | ret[0] = map; 44 | } 45 | for (int i = 0; i < f.sizep(); i++) { 46 | map[deep] = i; 47 | if (f.p[i] == target) return i; 48 | int sub = getSubIndex(f.p[i], target, map, deep + 1, ret); 49 | if (sub != -1) return sub; 50 | } 51 | return -1; 52 | } 53 | 54 | 55 | //f:哪个Proto(父子Proto指定层级) 56 | //needNote:是否需要辅助性注释 57 | //likeActCode:是否需要指令码转成生动的行为符号(如:OP_ADD用+代替) 58 | //needSubXasm:是否要解析子函数汇编 59 | public String getXasm(Proto f, boolean needNote, boolean likeActCode, boolean needSubXasm) { 60 | if (f == null) f = proto; 61 | StringBuilder sb = new StringBuilder(); 62 | if (f != proto) { 63 | int[][] pIndex = new int[1][]; 64 | int find = getSubIndex(proto, f, null, 0, pIndex); 65 | if (find == -1) throw new IllegalArgumentException("没有找到目标函数原型"); 66 | for (int i = 0; i < pIndex[0].length; i++) { 67 | sb.append("/"); 68 | sb.append(pIndex[0][i]); 69 | } 70 | } 71 | return getXasm(f, sb.toString(), needNote, likeActCode, needSubXasm); 72 | } 73 | 74 | public String getXasm(Proto f, String subPath, boolean needNote, boolean likeActCode, boolean needSubXasm) { 75 | int i; 76 | if (f == null) f = proto; 77 | if (checkIsSub) { 78 | Proto p = proto.findSub(subPath == null ? "" : subPath); 79 | if (p != f) { 80 | throw new IllegalArgumentException("安全检查未通过,当前索引和传入的函数原型并非一个。"); 81 | } 82 | } 83 | bindInst.bind(f);//识别会跳跃到的位置等信息,方便统一打标签等 84 | StringBuilder sb = new StringBuilder(); 85 | sb.append(".function main"); 86 | sb.append(subPath == null ? "" : subPath); 87 | if (needNote) { 88 | if (f != proto) { 89 | sb.append(" $ 当前根索引函数原型路径"); 90 | } else { 91 | sb.append(" $ 当前函数原型是根"); 92 | } 93 | } 94 | sb.append("\n"); 95 | sb.append(".sub-parse ");//这个是给人看的,解析工具其实可以不认的,只是告诉人这个函数会解析子函数 96 | sb.append(needSubXasm); 97 | if (needNote) { 98 | if (needSubXasm) { 99 | sb.append(" $ 本Xasm也会解析子函数"); 100 | } else { 101 | sb.append(" $ 本Xasm只解析本函数,子函数将不进行解析"); 102 | } 103 | } 104 | sb.append("\n"); 105 | sb.append(".source "); 106 | if (f.source == null || f.source.equals(NIL)) { 107 | sb.append("null"); 108 | } else { 109 | sb.append(f.source.toWarpString()); 110 | } 111 | if (needNote) { 112 | if (f.source == null || f.source.equals(NIL)) { 113 | sb.append(" $ 当前函数原型没有指定源文件"); 114 | } else { 115 | byte[] buf = (byte[]) f.source.value_; 116 | if (buf.length > 0) { 117 | if (buf[0] == '@') { 118 | sb.append(" $ 当前函数原型的源文件路径"); 119 | } else { 120 | sb.append(" $ 当前函数原型的源内容"); 121 | } 122 | } else { 123 | sb.append(" $ 当前函数原型的源文件未填写"); 124 | } 125 | } 126 | } 127 | sb.append("\n"); 128 | sb.append(".is_vararg ").append(f.is_vararg); 129 | if (needNote) { 130 | if (f.is_vararg == 0) { 131 | sb.append(" $ 没使用变参"); 132 | } else if (f.is_vararg == 1) { 133 | sb.append(" $ 使用了变参作为最后一个参数"); 134 | } else if (f.is_vararg == 2) { 135 | sb.append(" $ 使用了变参作为最后一个参数(根一定是)"); 136 | } else { 137 | sb.append(" $ 是否支持变参:0表示没使用,1表示使用了变参作为最后一个参数,2表示根"); 138 | } 139 | } 140 | sb.append("\n"); 141 | sb.append(".maxstacksize ").append(f.maxstacksize); 142 | if (needNote) { 143 | sb.append(" $ 最大栈大小,合法值为0~250(255是理论的,但是虚拟机支持到250)"); 144 | } 145 | sb.append("\n"); 146 | sb.append(".numparams ").append(f.numparams); 147 | if (needNote) { 148 | sb.append(" $ 固定的形参个数"); 149 | } 150 | sb.append("\n"); 151 | sb.append(".linedefined ").append(f.linedefined); 152 | if (needNote) { 153 | if (f != proto) { 154 | sb.append(" $ 起始定义的行号"); 155 | } else { 156 | sb.append(" $ 起始定义的行号,但是根一般是0"); 157 | } 158 | } 159 | sb.append("\n"); 160 | sb.append(".lastlinedefined ").append(f.lastlinedefined); 161 | if (needNote) { 162 | if (f != proto) { 163 | sb.append(" $ 结束定义的行号"); 164 | } else { 165 | sb.append(" $ 结束定义的行号,但是根一般是0"); 166 | } 167 | } 168 | sb.append("\n"); 169 | int sizelocvars = f.sizelocvars(); 170 | if (sizelocvars > 0) 171 | sb.append("\n");//成组出现,多加入一次换行 172 | for (i = 0; i < sizelocvars; i++) { 173 | if (needNote && i == 0) { 174 | sb.append("$ 局部变量名 起始位置(指令) -> 回收位置(指令)").append("\n"); 175 | } 176 | LocVar lv = f.locvars[i]; 177 | sb.append(".locvars ") 178 | .append(lv.varname.toVarString()).append(" ") 179 | .append(lv.startpc).append(" -> ").append(lv.endpc); 180 | sb.append("\n"); 181 | } 182 | sb.append("\n");//成组出现,多加入一次换行 183 | int sizeupvalues = f.sizeupvalues(); 184 | for (i = 0; i < sizeupvalues; i++) { 185 | if (needNote && i == 0) { 186 | sb.append("$ 上值变量名 索引编号 是否在栈中").append("\n"); 187 | } 188 | Upvaldesc uv = f.upvalues[i]; 189 | sb.append(".upvaldesc ") 190 | .append(uv.name.toVarString()).append(" ") 191 | .append(uv.idx).append(" ").append(uv.instack); 192 | sb.append("\n"); 193 | } 194 | sb.append("\n");//成组出现,多加入一次换行 195 | if (needNote) { 196 | sb.append("$ op操作码 各种操作数 rXX表示XX寄存器,uXX表示XX上值,pXX表示XX子函数,kXX表示第XX常量(只有找不到该常量才会出现kXX),goto_XX表示跳跃的XX标签,直接是数字表示数字,一般按A,B,C,Bx,sBx,Ax顺序表示").append("\n"); 197 | sb.append("$ .goto_XX是跳跃标签,.line XX是行号标签(特别的,0不会显示,上一次的line和本次一致也会不显示)").append("\n"); 198 | } 199 | sb.append(".code-start"); 200 | sb.append("\n"); 201 | int sizecode = f.sizecode(); 202 | int sizelineinfo = f.sizelineinfo(); 203 | int lastline = 0; 204 | // int sizek = f.sizek(); 205 | i = -1;//先++到0 206 | while (true) { 207 | i++; 208 | if (i >= sizecode) { 209 | break; 210 | } 211 | if (sizelineinfo > 0 && i < sizelineinfo) { 212 | int line = f.lineinfo[i]; 213 | if (line != 0 && line != lastline) { 214 | sb.append(".line ").append(line).append("\n"); 215 | } 216 | lastline = line; 217 | } 218 | Instruction instruction = f.code[i]; 219 | OPCode opcode = instruction.getOpCode(); 220 | if (instruction.isCanJump2There) { 221 | sb.append(".goto_").append(i).append("\n"); 222 | } 223 | if (instruction.isStartRealFake) { 224 | sb.append("$ =================开始假块=================\n"); 225 | } 226 | if (instruction.isRealFake) { 227 | sb.append("$ 这是下方指令绝对不可能被执行,否则会遇到完全未知的错误,请考虑附近指令是否为假块。\n"); 228 | } 229 | if (likeActCode) { 230 | switch (opcode) { 231 | case OP_ADD: { 232 | sb.append("+ "); 233 | break; 234 | } 235 | case OP_SUB: { 236 | sb.append("- "); 237 | break; 238 | } 239 | case OP_MUL: { 240 | sb.append("* "); 241 | break; 242 | } 243 | case OP_MOD: { 244 | sb.append("% "); 245 | break; 246 | } 247 | case OP_POW: { 248 | sb.append("^ "); 249 | break; 250 | } 251 | case OP_DIV: { 252 | sb.append("/ "); 253 | break; 254 | } 255 | case OP_IDIV: { 256 | sb.append("// "); 257 | break; 258 | } 259 | case OP_BAND: { 260 | sb.append("& "); 261 | break; 262 | } 263 | case OP_BOR: { 264 | sb.append("| "); 265 | break; 266 | } 267 | case OP_BXOR: { 268 | sb.append("~ "); 269 | break; 270 | } 271 | case OP_SHL: { 272 | sb.append("<< "); 273 | break; 274 | } 275 | case OP_SHR: { 276 | sb.append(">> "); 277 | break; 278 | } 279 | case OP_UNM: { 280 | sb.append("-() "); 281 | break; 282 | } 283 | case OP_BNOT: { 284 | sb.append("~() "); 285 | break; 286 | } 287 | case OP_LEN: { 288 | sb.append("# "); 289 | break; 290 | } 291 | case OP_CONCAT: { 292 | sb.append(".. "); 293 | break; 294 | } 295 | case OP_NEWTABLE: { 296 | sb.append("{} "); 297 | break; 298 | } 299 | case OP_NEWARRAY: { 300 | sb.append("[] "); 301 | break; 302 | } 303 | case OP_CLOSURE: { 304 | sb.append("func "); 305 | break; 306 | } 307 | case OP_EQ: { 308 | if (instruction.A() == 0) { 309 | sb.append("~= "); 310 | } else { 311 | sb.append("== "); 312 | } 313 | break; 314 | } 315 | case OP_LT: { 316 | if (instruction.A() != 0) { 317 | sb.append("< "); 318 | } else { 319 | sb.append("> "); 320 | } 321 | break; 322 | } 323 | case OP_LE: { 324 | if (instruction.A() != 0) { 325 | sb.append("<= "); 326 | } else { 327 | sb.append("=> "); 328 | } 329 | break; 330 | } 331 | default: { 332 | sb.append(opcode.getName()).append(" "); 333 | break; 334 | } 335 | } 336 | } else { 337 | sb.append(opcode.getName()).append(" "); 338 | } 339 | switch (opcode) { 340 | case OP_MOVE: {//rA rB 341 | sb.append("r").append(instruction.A()).append(" ") 342 | .append("r").append(instruction.B()); 343 | if (needNote) { 344 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值赋值给寄存器(r").append(instruction.A()).append(")"); 345 | } 346 | break; 347 | } 348 | case OP_LOADK: {//rA 349 | sb.append("r").append(instruction.A()).append(" ") 350 | .append(safeToVarString(f, instruction.Bx())); 351 | if (needNote) { 352 | sb.append(" $ 加载常量(").append(safeToVarString(f, instruction.Bx())).append(")到寄存器(r").append(instruction.A()).append(")"); 353 | } 354 | break; 355 | } 356 | case OP_LOADKX: {//rA 357 | sb.append("r").append(instruction.A()).append(" "); 358 | i++; 359 | Instruction instruction2 = f.code[i]; 360 | sb.append(safeToVarString(f, instruction2.Ax())); 361 | if (needNote) { 362 | sb.append(" $ 加载常量(").append(safeToVarString(f, instruction.Ax())).append(")到寄存器(r").append(instruction.A()).append(")"); 363 | } 364 | break; 365 | } 366 | case OP_LOADBOOL: {//rA 或者rA 或者rA goto_XX 367 | sb.append("r").append(instruction.A()).append(" ") 368 | .append(instruction.B() != 0).append(" "); 369 | if (instruction.C() != 0) { 370 | sb.append("goto_").append(i + 1 + 1); 371 | } 372 | if (needNote) { 373 | sb.append(" $ 加载布尔值(").append(instruction.B() != 0).append(")到寄存器(r").append(instruction.A()).append(")"); 374 | if (instruction.C() != 0) { 375 | sb.append(",并跳过下一条指令"); 376 | } 377 | } 378 | break; 379 | } 380 | case OP_LOADNIL: {//rA r(A+B)或者rA 381 | sb.append("r").append(instruction.A()).append(" ") 382 | .append("r").append(instruction.B() + instruction.A()); 383 | if (needNote) { 384 | sb.append(" $ 将寄存器(r").append(instruction.A()).append(")到寄存器(r").append(instruction.B() + instruction.A()).append(")闭区间的值设置为nil"); 385 | } 386 | break; 387 | } 388 | case OP_GETUPVAL: {//rA uB 389 | sb.append("r").append(instruction.A()).append(" ") 390 | .append("u").append(instruction.B()); 391 | if (needNote) { 392 | sb.append(" $ 将上值(u").append(instruction.B()).append(")的值赋值给寄存器(r").append(instruction.A()).append(")"); 393 | } 394 | break; 395 | } 396 | case OP_GETTABUP: {//rA uB rC或者rA uB 397 | sb.append("r").append(instruction.A()).append(" ") 398 | .append("u").append(instruction.B()).append(" "); 399 | if (ISK(instruction.C())) { 400 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 401 | if (needNote) { 402 | sb.append(" $ 将上值(u").append(instruction.B()).append(")的值的键为常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值赋值给寄存器(r").append(instruction.A()).append(")"); 403 | } 404 | } else { 405 | sb.append("r").append(instruction.C()); 406 | if (needNote) { 407 | sb.append(" $ 将上值(u").append(instruction.B()).append(")的值的键为寄存器(r").append(instruction.C()).append(")的值赋值给寄存器(r").append(instruction.A()).append(")"); 408 | } 409 | } 410 | break; 411 | } 412 | case OP_GETTABLE: {//rA rB rC或者rA rB 413 | sb.append("r").append(instruction.A()).append(" ") 414 | .append("r").append(instruction.B()).append(" "); 415 | if (ISK(instruction.C())) { 416 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 417 | if (needNote) { 418 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值的键为常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值赋值给寄存器(r").append(instruction.A()).append(")"); 419 | } 420 | } else { 421 | sb.append("r").append(instruction.C()); 422 | if (needNote) { 423 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值的键为寄存器(r").append(instruction.C()).append(")的值赋值给寄存器(r").append(instruction.A()).append(")"); 424 | } 425 | } 426 | break; 427 | } 428 | case OP_SETTABUP: {//uA 或者uA rB 或者uA rC或者uA rB rC 429 | sb.append("u").append(instruction.A()).append(" "); 430 | if (ISK(instruction.B())) { 431 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 432 | if (ISK(instruction.C())) { 433 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 434 | if (needNote) { 435 | sb.append(" $ 将上值(u").append(instruction.A()).append(")的值的键为常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值设置为常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")"); 436 | } 437 | } else { 438 | sb.append("r").append(instruction.C()); 439 | if (needNote) { 440 | sb.append(" $ 将上值(u").append(instruction.A()).append(")的值的键为常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值设置为寄存器(r").append(instruction.C()).append(")的值"); 441 | } 442 | } 443 | } else { 444 | sb.append("r").append(instruction.B()).append(" "); 445 | if (ISK(instruction.C())) { 446 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 447 | if (needNote) { 448 | sb.append(" $ 将上值(u").append(instruction.A()).append(")的值的键为寄存器(r").append(instruction.B()).append(")的值设置为常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")"); 449 | } 450 | } else { 451 | sb.append("r").append(instruction.C()); 452 | if (needNote) { 453 | sb.append(" $ 将上值(u").append(instruction.A()).append(")的值的键为寄存器(r").append(instruction.B()).append(")的值设置为寄存器(r").append(instruction.C()).append(")的值"); 454 | } 455 | } 456 | } 457 | break; 458 | } 459 | case OP_SETUPVAL: {//uB rA 460 | sb.append("u").append(instruction.B()).append(" ") 461 | .append("r").append(instruction.A()); 462 | if (needNote) { 463 | sb.append(" $ 将寄存器(r").append(instruction.A()).append(")的值赋值给上值(u").append(instruction.B()).append(")"); 464 | } 465 | break; 466 | } 467 | case OP_SETTABLE: {//rA 或者rA rB 或者rA rC或者rA rB rC 468 | sb.append("r").append(instruction.A()).append(" "); 469 | if (ISK(instruction.B())) { 470 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 471 | if (ISK(instruction.C())) { 472 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 473 | if (needNote) { 474 | sb.append(" $ 将寄存器(r").append(instruction.A()).append(")的值的键为常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值设置为常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")"); 475 | } 476 | } else { 477 | sb.append("r").append(instruction.C()); 478 | if (needNote) { 479 | sb.append(" $ 将寄存器(r").append(instruction.A()).append(")的值的键为常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值设置为寄存器(r").append(instruction.C()).append(")的值"); 480 | } 481 | } 482 | } else { 483 | sb.append("r").append(instruction.B()).append(" "); 484 | if (ISK(instruction.C())) { 485 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 486 | if (needNote) { 487 | sb.append(" $ 将寄存器(r").append(instruction.A()).append(")的值的键为寄存器(r").append(instruction.B()).append(")的值设置为常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")"); 488 | } 489 | } else { 490 | sb.append("r").append(instruction.C()); 491 | if (needNote) { 492 | sb.append(" $ 将寄存器(r").append(instruction.A()).append(")的值的键为寄存器(r").append(instruction.B()).append(")的值设置为寄存器(r").append(instruction.C()).append(")的值"); 493 | } 494 | } 495 | } 496 | break; 497 | } 498 | case OP_NEWTABLE: {//rA 499 | sb.append("r").append(instruction.A()).append(" ") 500 | .append(instruction.B()).append(" ") 501 | .append(instruction.C()); 502 | if (needNote) { 503 | sb.append(" $ 创建一个新的表,将其赋值给寄存器(r").append(instruction.A()).append("),并将其数组部分的大小设置为(").append(instruction.B()).append("),哈希部分的大小设置为(").append(instruction.C()).append(")"); 504 | } 505 | break; 506 | } 507 | case OP_SELF: {//rA rB 或者rA rB rC 508 | sb.append("r").append(instruction.A()).append(" ") 509 | .append("r").append(instruction.B()).append(" "); 510 | if (ISK(instruction.C())) { 511 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 512 | if (needNote) { 513 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值的键为常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值赋值给寄存器(r").append(instruction.A()).append("),并将寄存器(r").append(instruction.B()).append(")的值赋值给寄存器(r").append(instruction.A() + 1).append(")"); 514 | } 515 | } else { 516 | sb.append("r").append(instruction.C()); 517 | if (needNote) { 518 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值的键为寄存器(r").append(instruction.C()).append(")的值赋值给寄存器(r").append(instruction.A()).append("),并将寄存器(r").append(instruction.B()).append(")的值赋值给寄存器(r").append(instruction.A() + 1).append(")"); 519 | } 520 | } 521 | break; 522 | } 523 | case OP_ADD: {//rA 或者rA rB 或者rA rC或者rA rB rC 524 | sb.append("r").append(instruction.A()).append(" "); 525 | if (ISK(instruction.B())) { 526 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 527 | if (ISK(instruction.C())) { 528 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 529 | if (needNote) { 530 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")相加,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 531 | } 532 | } else { 533 | sb.append("r").append(instruction.C()); 534 | if (needNote) { 535 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")与寄存器(r").append(instruction.C()).append(")的值相加,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 536 | } 537 | } 538 | } else { 539 | sb.append("r").append(instruction.B()).append(" "); 540 | if (ISK(instruction.C())) { 541 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 542 | if (needNote) { 543 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")相加,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 544 | } 545 | } else { 546 | sb.append("r").append(instruction.C()); 547 | if (needNote) { 548 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与寄存器(r").append(instruction.C()).append(")的值相加,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 549 | } 550 | } 551 | } 552 | break; 553 | } 554 | case OP_SUB: {//rA 或者rA rB 或者rA rC或者rA rB rC 555 | sb.append("r").append(instruction.A()).append(" "); 556 | if (ISK(instruction.B())) { 557 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 558 | if (ISK(instruction.C())) { 559 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 560 | if (needNote) { 561 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")相减,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 562 | } 563 | } else { 564 | sb.append("r").append(instruction.C()); 565 | if (needNote) { 566 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")与寄存器(r").append(instruction.C()).append(")的值相减,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 567 | } 568 | } 569 | } else { 570 | sb.append("r").append(instruction.B()).append(" "); 571 | if (ISK(instruction.C())) { 572 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 573 | if (needNote) { 574 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")相减,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 575 | } 576 | } else { 577 | sb.append("r").append(instruction.C()); 578 | if (needNote) { 579 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与寄存器(r").append(instruction.C()).append(")的值相减,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 580 | } 581 | } 582 | } 583 | break; 584 | } 585 | case OP_MUL: {//rA 或者rA rB 或者rA rC或者rA rB rC 586 | sb.append("r").append(instruction.A()).append(" "); 587 | if (ISK(instruction.B())) { 588 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 589 | if (ISK(instruction.C())) { 590 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 591 | if (needNote) { 592 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")相乘,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 593 | } 594 | } else { 595 | sb.append("r").append(instruction.C()); 596 | if (needNote) { 597 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")与寄存器(r").append(instruction.C()).append(")的值相乘,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 598 | } 599 | } 600 | } else { 601 | sb.append("r").append(instruction.B()).append(" "); 602 | if (ISK(instruction.C())) { 603 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 604 | if (needNote) { 605 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")相乘,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 606 | } 607 | } else { 608 | sb.append("r").append(instruction.C()); 609 | if (needNote) { 610 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与寄存器(r").append(instruction.C()).append(")的值相乘,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 611 | } 612 | } 613 | } 614 | break; 615 | } 616 | case OP_MOD: {//rA 或者rA rB 或者rA rC或者rA rB rC 617 | sb.append("r").append(instruction.A()).append(" "); 618 | if (ISK(instruction.B())) { 619 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 620 | if (ISK(instruction.C())) { 621 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 622 | if (needNote) { 623 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")求余,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 624 | } 625 | } else { 626 | sb.append("r").append(instruction.C()); 627 | if (needNote) { 628 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")与寄存器(r").append(instruction.C()).append(")的值求余,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 629 | } 630 | } 631 | } else { 632 | sb.append("r").append(instruction.B()).append(" "); 633 | if (ISK(instruction.C())) { 634 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 635 | if (needNote) { 636 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")求余,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 637 | } 638 | } else { 639 | sb.append("r").append(instruction.C()); 640 | if (needNote) { 641 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与寄存器(r").append(instruction.C()).append(")的值求余,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 642 | } 643 | } 644 | } 645 | break; 646 | } 647 | case OP_POW: {//rA 或者rA rB 或者rA rC或者rA rB rC 648 | sb.append("r").append(instruction.A()).append(" "); 649 | if (ISK(instruction.B())) { 650 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 651 | if (ISK(instruction.C())) { 652 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 653 | if (needNote) { 654 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值的常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")次方,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 655 | } 656 | } else { 657 | sb.append("r").append(instruction.C()); 658 | if (needNote) { 659 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值的寄存器(r").append(instruction.C()).append(")的值次方,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 660 | } 661 | } 662 | } else { 663 | sb.append("r").append(instruction.B()).append(" "); 664 | if (ISK(instruction.C())) { 665 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 666 | if (needNote) { 667 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值的常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")次方,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 668 | } 669 | } else { 670 | sb.append("r").append(instruction.C()); 671 | if (needNote) { 672 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值的寄存器(r").append(instruction.C()).append(")的值次方,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 673 | } 674 | } 675 | } 676 | break; 677 | } 678 | case OP_DIV: {//rA 或者rA rB 或者rA rC或者rA rB rC 679 | sb.append("r").append(instruction.A()).append(" "); 680 | if (ISK(instruction.B())) { 681 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 682 | if (ISK(instruction.C())) { 683 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 684 | if (needNote) { 685 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值除以常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 686 | } 687 | } else { 688 | sb.append("r").append(instruction.C()); 689 | if (needNote) { 690 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值除以寄存器(r").append(instruction.C()).append(")的值,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 691 | } 692 | } 693 | } else { 694 | sb.append("r").append(instruction.B()).append(" "); 695 | if (ISK(instruction.C())) { 696 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 697 | if (needNote) { 698 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值除以常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 699 | } 700 | } else { 701 | sb.append("r").append(instruction.C()); 702 | if (needNote) { 703 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值除以寄存器(r").append(instruction.C()).append(")的值,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 704 | } 705 | } 706 | } 707 | break; 708 | } 709 | case OP_IDIV: {//rA 或者rA rB 或者rA rC或者rA rB rC 710 | sb.append("r").append(instruction.A()).append(" "); 711 | if (ISK(instruction.B())) { 712 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 713 | if (ISK(instruction.C())) { 714 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 715 | if (needNote) { 716 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值整除以常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 717 | } 718 | } else { 719 | sb.append("r").append(instruction.C()); 720 | if (needNote) { 721 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值整除以寄存器(r").append(instruction.C()).append(")的值,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 722 | } 723 | } 724 | } else { 725 | sb.append("r").append(instruction.B()).append(" "); 726 | if (ISK(instruction.C())) { 727 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 728 | if (needNote) { 729 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值整除以常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 730 | } 731 | } else { 732 | sb.append("r").append(instruction.C()); 733 | if (needNote) { 734 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值整除以寄存器(r").append(instruction.C()).append(")的值,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 735 | } 736 | } 737 | } 738 | break; 739 | } 740 | case OP_BAND: {//rA 或者rA rB 或者rA rC或者rA rB rC 741 | sb.append("r").append(instruction.A()).append(" "); 742 | if (ISK(instruction.B())) { 743 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 744 | if (ISK(instruction.C())) { 745 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 746 | if (needNote) { 747 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值进行按位与运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 748 | } 749 | } else { 750 | sb.append("r").append(instruction.C()); 751 | if (needNote) { 752 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值与寄存器(r").append(instruction.C()).append(")的值进行按位与运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 753 | } 754 | } 755 | } else { 756 | sb.append("r").append(instruction.B()).append(" "); 757 | if (ISK(instruction.C())) { 758 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 759 | if (needNote) { 760 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值进行按位与运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 761 | } 762 | } else { 763 | sb.append("r").append(instruction.C()); 764 | if (needNote) { 765 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与寄存器(r").append(instruction.C()).append(")的值进行按位与运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 766 | } 767 | } 768 | } 769 | break; 770 | } 771 | case OP_BOR: {//rA 或者rA rB 或者rA rC或者rA rB rC 772 | sb.append("r").append(instruction.A()).append(" "); 773 | if (ISK(instruction.B())) { 774 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 775 | if (ISK(instruction.C())) { 776 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 777 | if (needNote) { 778 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值进行按位或运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 779 | } 780 | } else { 781 | sb.append("r").append(instruction.C()); 782 | if (needNote) { 783 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值与寄存器(r").append(instruction.C()).append(")的值进行按位或运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 784 | } 785 | } 786 | } else { 787 | sb.append("r").append(instruction.B()).append(" "); 788 | if (ISK(instruction.C())) { 789 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 790 | if (needNote) { 791 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值进行按位或运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 792 | } 793 | } else { 794 | sb.append("r").append(instruction.C()); 795 | if (needNote) { 796 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与寄存器(r").append(instruction.C()).append(")的值进行按位或运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 797 | } 798 | } 799 | } 800 | break; 801 | } 802 | case OP_BXOR: {//rA 或者rA rB 或者rA rC或者rA rB rC 803 | sb.append("r").append(instruction.A()).append(" "); 804 | if (ISK(instruction.B())) { 805 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 806 | if (ISK(instruction.C())) { 807 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 808 | if (needNote) { 809 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值进行按位异或运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 810 | } 811 | } else { 812 | sb.append("r").append(instruction.C()); 813 | if (needNote) { 814 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值与寄存器(r").append(instruction.C()).append(")的值进行按位异或运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 815 | } 816 | } 817 | } else { 818 | sb.append("r").append(instruction.B()).append(" "); 819 | if (ISK(instruction.C())) { 820 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 821 | if (needNote) { 822 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")的值进行按位异或运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 823 | } 824 | } else { 825 | sb.append("r").append(instruction.C()); 826 | if (needNote) { 827 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值与寄存器(r").append(instruction.C()).append(")的值进行按位异或运算,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 828 | } 829 | } 830 | } 831 | break; 832 | } 833 | case OP_SHL: {//rA 或者rA rB 或者rA rC或者rA rB rC 834 | sb.append("r").append(instruction.A()).append(" "); 835 | if (ISK(instruction.B())) { 836 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 837 | if (ISK(instruction.C())) { 838 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 839 | if (needNote) { 840 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值左移常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")位,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 841 | } 842 | } else { 843 | sb.append("r").append(instruction.C()); 844 | if (needNote) { 845 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值左移寄存器(r").append(instruction.C()).append(")的值位,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 846 | } 847 | } 848 | } else { 849 | sb.append("r").append(instruction.B()).append(" "); 850 | if (ISK(instruction.C())) { 851 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 852 | if (needNote) { 853 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值左移常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")位,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 854 | } 855 | } else { 856 | sb.append("r").append(instruction.C()); 857 | if (needNote) { 858 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值左移寄存器(r").append(instruction.C()).append(")的值位,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 859 | } 860 | } 861 | } 862 | break; 863 | } 864 | case OP_SHR: {//rA 或者rA rB 或者rA rC或者rA rB rC 865 | sb.append("r").append(instruction.A()).append(" "); 866 | if (ISK(instruction.B())) { 867 | sb.append(safeToVarString(f, INDEXK(instruction.B()))).append(" "); 868 | if (ISK(instruction.C())) { 869 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 870 | if (needNote) { 871 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值右移常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")位,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 872 | } 873 | } else { 874 | sb.append("r").append(instruction.C()); 875 | if (needNote) { 876 | sb.append(" $ 将常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")的值右移寄存器(r").append(instruction.C()).append(")的值位,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 877 | } 878 | } 879 | } else { 880 | sb.append("r").append(instruction.B()).append(" "); 881 | if (ISK(instruction.C())) { 882 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 883 | if (needNote) { 884 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值右移常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append(")位,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 885 | } 886 | } else { 887 | sb.append("r").append(instruction.C()); 888 | if (needNote) { 889 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值右移寄存器(r").append(instruction.C()).append(")的值位,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 890 | } 891 | } 892 | } 893 | break; 894 | } 895 | case OP_UNM: {//rA rB 896 | sb.append("r").append(instruction.A()).append(" r").append(instruction.B()); 897 | if (needNote) { 898 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值取反,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 899 | } 900 | break; 901 | } 902 | case OP_BNOT: {//rA rB 903 | sb.append("r").append(instruction.A()).append(" r").append(instruction.B()); 904 | if (needNote) { 905 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的值按位取反,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 906 | } 907 | break; 908 | } 909 | case OP_NOT: {//rA rB 910 | sb.append("r").append(instruction.A()).append(" r").append(instruction.B()); 911 | if (needNote) { 912 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的布尔值取反,将结果赋值给寄存器(r").append(instruction.A()).append(")"); 913 | } 914 | break; 915 | } 916 | case OP_LEN: {//rA rB 917 | sb.append("r").append(instruction.A()).append(" r").append(instruction.B()); 918 | if (needNote) { 919 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")的长度赋值给寄存器(r").append(instruction.A()).append(")"); 920 | } 921 | break; 922 | } 923 | case OP_CONCAT: {//rA rB rC 924 | sb.append("r").append(instruction.A()).append(" r").append(instruction.B()).append(" r").append(instruction.C()); 925 | if (needNote) { 926 | sb.append(" $ 将寄存器(r").append(instruction.B()).append(")到寄存器(r").append(instruction.C()).append(")闭区间的值连接拼接起来,将结果字符串赋值给寄存器(r").append(instruction.A()).append(")"); 927 | } 928 | break; 929 | } 930 | case OP_JMP: {//或者 或者goto_XX或者 goto_XX 931 | if (instruction.A() == 0) { 932 | sb.append("goto_").append(i + 1 + instruction.sBx()); 933 | if (needNote) { 934 | sb.append(" $ 无条件跳转"); 935 | } 936 | } else { 937 | sb.append(instruction.A()).append(" ").append("goto_").append(i + 1 + instruction.sBx()); 938 | if (needNote) { 939 | sb.append(" $ 关闭寄存器(r").append(instruction.A() - 1).append(")以及更高层的值,然后跳转"); 940 | } 941 | } 942 | break; 943 | } 944 | case OP_EQ: {// 或者 rB 或者 rC或者 rB rC 945 | sb.append(instruction.A() != 0).append(" "); 946 | if (instruction.A() != 0) { 947 | if (ISK(instruction.B())) { 948 | sb.append(safeToVarString(f, INDEXK(instruction.B()))); 949 | if (ISK(instruction.C())) { 950 | sb.append(" ").append(safeToVarString(f, INDEXK(instruction.C()))); 951 | if (needNote) { 952 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")等于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 953 | } 954 | } else { 955 | sb.append(" r").append(instruction.C()); 956 | if (needNote) { 957 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")等于寄存器(r").append(instruction.C()).append("),则跳转,否则,跳过下一条指令"); 958 | } 959 | } 960 | } else { 961 | sb.append("r").append(instruction.B()).append(" "); 962 | if (ISK(instruction.C())) { 963 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 964 | if (needNote) { 965 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值等于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 966 | } 967 | } else { 968 | sb.append("r").append(instruction.C()); 969 | if (needNote) { 970 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值等于寄存器(r").append(instruction.C()).append(")的值,跳转,否则,跳过下一条指令"); 971 | } 972 | } 973 | } 974 | } else { 975 | if (ISK(instruction.B())) { 976 | sb.append(safeToVarString(f, INDEXK(instruction.B()))); 977 | if (ISK(instruction.C())) { 978 | sb.append(" ").append(safeToVarString(f, INDEXK(instruction.C()))); 979 | if (needNote) { 980 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")不等于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 981 | } 982 | } else { 983 | sb.append(" r").append(instruction.C()); 984 | if (needNote) { 985 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")不等于寄存器(r").append(instruction.C()).append("),则跳转,否则,跳过下一条指令"); 986 | } 987 | } 988 | } else { 989 | sb.append("r").append(instruction.B()).append(" "); 990 | if (ISK(instruction.C())) { 991 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 992 | if (needNote) { 993 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值不等于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 994 | } 995 | } else { 996 | sb.append("r").append(instruction.C()); 997 | if (needNote) { 998 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值不等于寄存器(r").append(instruction.C()).append(")的值,跳转,否则,跳过下一条指令"); 999 | } 1000 | } 1001 | } 1002 | } 1003 | break; 1004 | } 1005 | case OP_LT: {// 或者 rB 或者 rC或者 rB rC 1006 | sb.append(instruction.A() != 0).append(" "); 1007 | if (instruction.A() != 0) { 1008 | if (ISK(instruction.B())) { 1009 | sb.append(safeToVarString(f, INDEXK(instruction.B()))); 1010 | if (ISK(instruction.C())) { 1011 | sb.append(" ").append(safeToVarString(f, INDEXK(instruction.C()))); 1012 | if (needNote) { 1013 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")小于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 1014 | } 1015 | } else { 1016 | sb.append(" r").append(instruction.C()); 1017 | if (needNote) { 1018 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")小于寄存器(r").append(instruction.C()).append("),则跳转,否则,跳过下一条指令"); 1019 | } 1020 | } 1021 | } else { 1022 | sb.append("r").append(instruction.B()).append(" "); 1023 | if (ISK(instruction.C())) { 1024 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 1025 | if (needNote) { 1026 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值小于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 1027 | } 1028 | } else { 1029 | sb.append("r").append(instruction.C()); 1030 | if (needNote) { 1031 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值小于寄存器(r").append(instruction.C()).append(")的值,跳转,否则,跳过下一条指令"); 1032 | } 1033 | } 1034 | } 1035 | } else { 1036 | if (ISK(instruction.B())) { 1037 | sb.append(safeToVarString(f, INDEXK(instruction.B()))); 1038 | if (ISK(instruction.C())) { 1039 | sb.append(" ").append(safeToVarString(f, INDEXK(instruction.C()))); 1040 | if (needNote) { 1041 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")不小于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 1042 | } 1043 | } else { 1044 | sb.append(" r").append(instruction.C()); 1045 | if (needNote) { 1046 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")不小于寄存器(r").append(instruction.C()).append("),则跳转,否则,跳过下一条指令"); 1047 | } 1048 | } 1049 | } else { 1050 | sb.append("r").append(instruction.B()).append(" "); 1051 | if (ISK(instruction.C())) { 1052 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 1053 | if (needNote) { 1054 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值不小于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 1055 | } 1056 | } else { 1057 | sb.append("r").append(instruction.C()); 1058 | if (needNote) { 1059 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值不小于寄存器(r").append(instruction.C()).append(")的值,跳转,否则,跳过下一条指令"); 1060 | } 1061 | } 1062 | } 1063 | } 1064 | break; 1065 | } 1066 | case OP_LE: {// 或者 rB 或者 rC或者 rB rC 1067 | sb.append(instruction.A() != 0).append(" "); 1068 | if (instruction.A() != 0) { 1069 | if (ISK(instruction.B())) { 1070 | sb.append(safeToVarString(f, INDEXK(instruction.B()))); 1071 | if (ISK(instruction.C())) { 1072 | sb.append(" ").append(safeToVarString(f, INDEXK(instruction.C()))); 1073 | if (needNote) { 1074 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")小于等于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 1075 | } 1076 | } else { 1077 | sb.append(" r").append(instruction.C()); 1078 | if (needNote) { 1079 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")小于等于寄存器(r").append(instruction.C()).append("),则跳转,否则,跳过下一条指令"); 1080 | } 1081 | } 1082 | } else { 1083 | sb.append("r").append(instruction.B()).append(" "); 1084 | if (ISK(instruction.C())) { 1085 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 1086 | if (needNote) { 1087 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值小于等于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 1088 | } 1089 | } else { 1090 | sb.append("r").append(instruction.C()); 1091 | if (needNote) { 1092 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值小于等于寄存器(r").append(instruction.C()).append(")的值,跳转,否则,跳过下一条指令"); 1093 | } 1094 | } 1095 | } 1096 | } else { 1097 | if (ISK(instruction.B())) { 1098 | sb.append(safeToVarString(f, INDEXK(instruction.B()))); 1099 | if (ISK(instruction.C())) { 1100 | sb.append(" ").append(safeToVarString(f, INDEXK(instruction.C()))); 1101 | if (needNote) { 1102 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")不小于等于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 1103 | } 1104 | } else { 1105 | sb.append(" r").append(instruction.C()); 1106 | if (needNote) { 1107 | sb.append(" $ 如果常量(").append(safeToVarString(f, INDEXK(instruction.B()))).append(")不小于等于寄存器(r").append(instruction.C()).append("),则跳转,否则,跳过下一条指令"); 1108 | } 1109 | } 1110 | } else { 1111 | sb.append("r").append(instruction.B()).append(" "); 1112 | if (ISK(instruction.C())) { 1113 | sb.append(safeToVarString(f, INDEXK(instruction.C()))); 1114 | if (needNote) { 1115 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值不小于等于常量(").append(safeToVarString(f, INDEXK(instruction.C()))).append("),则跳转,否则,跳过下一条指令"); 1116 | } 1117 | } else { 1118 | sb.append("r").append(instruction.C()); 1119 | if (needNote) { 1120 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的值不小于等于寄存器(r").append(instruction.C()).append(")的值,跳转,否则,跳过下一条指令"); 1121 | } 1122 | } 1123 | } 1124 | } 1125 | break; 1126 | } 1127 | case OP_TEST: {//rA 1128 | sb.append("r").append(instruction.A()).append(" ").append(instruction.C() != 0); 1129 | if (needNote) { 1130 | sb.append(" $ 如果寄存器(r").append(instruction.A()).append(")的转布尔值后的值为").append(instruction.C() != 0).append(",则跳转,否则,跳过下一条指令"); 1131 | } 1132 | break; 1133 | } 1134 | case OP_TESTSET: {//rA rB 1135 | sb.append("r").append(instruction.A()).append(" r").append(instruction.B()).append(" ").append(instruction.C() != 0); 1136 | if (needNote) { 1137 | sb.append(" $ 如果寄存器(r").append(instruction.B()).append(")的转布尔值后的值为").append(instruction.C() != 0).append(",则把寄存器(r").append(instruction.B()).append(")的值赋值给寄存器(r").append(instruction.A()).append("),并跳转,否则,跳过下一条指令"); 1138 | } 1139 | break; 1140 | } 1141 | case OP_CALL: {//rA 1142 | sb.append("r").append(instruction.A()).append(" ").append(instruction.B()).append(" ").append(instruction.C()); 1143 | if (needNote) { 1144 | sb.append(" $ 调用函数,参数个数为").append(instruction.B()); 1145 | if (instruction.C() == 0) { 1146 | sb.append(",返回值数量不确定"); 1147 | } else if (instruction.C() == 1) { 1148 | sb.append(",无返回值"); 1149 | } else if (instruction.C() > 1) { 1150 | sb.append(",返回值数量为").append(instruction.C() - 1); 1151 | } 1152 | } 1153 | break; 1154 | } 1155 | case OP_TAILCALL: {//rA 1156 | sb.append("r").append(instruction.A()).append(" ").append(instruction.B()).append(" ").append(instruction.C()); 1157 | if (needNote) { 1158 | sb.append(" $ 尾调用函数,参数个数为").append(instruction.B()).append(",返回值数量不确定,通常这个指令后面会跟一个返回指令"); 1159 | } 1160 | break; 1161 | } 1162 | case OP_RETURN: {//rA 1163 | sb.append("r").append(instruction.A()).append(" ").append(instruction.B()); 1164 | if (needNote) { 1165 | sb.append(" $ 返回"); 1166 | if (instruction.B() == 0) { 1167 | sb.append(",返回值数量已经部分在栈顶,把剩余的返回值数量压入栈顶"); 1168 | } else if (instruction.B() == 1) { 1169 | sb.append(",无返回值"); 1170 | } else if (instruction.B() > 1) { 1171 | sb.append(",返回值数量为").append(instruction.B() - 1); 1172 | } 1173 | } 1174 | break; 1175 | } 1176 | case OP_FORLOOP: {//rA 或者rA goto_XX 1177 | sb.append("r").append(instruction.A()).append(" ").append("goto_").append(i + 1 + instruction.sBx()); 1178 | if (needNote) { 1179 | sb.append(" $ 循环指令,增长相应步长后跳转"); 1180 | } 1181 | break; 1182 | } 1183 | case OP_FORPREP: {//rA 或者rA goto_XX 1184 | sb.append("r").append(instruction.A()).append(" ").append("goto_").append(i + 1 + instruction.sBx()); 1185 | if (needNote) { 1186 | sb.append(" $ 循环指令,准备循环,把循环变量减去步长,然后跳转"); 1187 | } 1188 | break; 1189 | } 1190 | case OP_TFORCALL: {//rA 1191 | sb.append("r").append(instruction.A()).append(" ").append(instruction.C()); 1192 | if (needNote) { 1193 | sb.append(" $ 调用迭代函数,参数个数为").append(instruction.C()); 1194 | } 1195 | break; 1196 | } 1197 | case OP_TFORLOOP: {//rA 或者rA goto_XX 1198 | sb.append("r").append(instruction.A()).append(" ").append("goto_").append(i + 1 + instruction.sBx()); 1199 | if (needNote) { 1200 | sb.append(" $ 循环指令,如果寄存器(r").append(instruction.A() + 1).append(")非nil,则跳转"); 1201 | } 1202 | break; 1203 | } 1204 | case OP_SETLIST: {//rA 1205 | sb.append("r").append(instruction.A()).append(" ").append(instruction.B()); 1206 | if (instruction.C() == 0) { 1207 | i++; 1208 | Instruction instruction2 = f.code[i]; 1209 | sb.append(" ").append(instruction2.Ax()); 1210 | if (needNote) { 1211 | sb.append(" $ 设置表,批次数量为").append(instruction2.Ax()); 1212 | } 1213 | } else { 1214 | sb.append(" ").append(instruction.C()); 1215 | if (needNote) { 1216 | sb.append(" $ 设置表,批次数量为").append(instruction.C()); 1217 | } 1218 | } 1219 | break; 1220 | } 1221 | case OP_CLOSURE: {//rA pBx 1222 | sb.append("r").append(instruction.A()).append(" ").append("p").append(instruction.Bx()); 1223 | if (needNote) { 1224 | sb.append(" $ 创建闭包,子原型索引为").append(instruction.Bx()); 1225 | } 1226 | break; 1227 | } 1228 | case OP_VARARG: {//rA 1229 | sb.append("r").append(instruction.A()).append(" ").append(instruction.B()); 1230 | if (needNote) { 1231 | sb.append(" $ 变长参数"); 1232 | } 1233 | break; 1234 | } 1235 | case OP_EXTRAARG: {//Ax 1236 | sb.append(instruction.Ax()); 1237 | if (needNote) { 1238 | sb.append(" $ 附加参数,他应该不会翻译出来,用到它的指令应该已经自动解析了才对。"); 1239 | } 1240 | break; 1241 | } 1242 | case OP_TBC: {//rA 1243 | sb.append("r").append(instruction.A()); 1244 | if (needNote) { 1245 | sb.append(" $ ToBeClosed,Alua用于简单支持lua54特性的指令"); 1246 | } 1247 | break; 1248 | } 1249 | case OP_NEWARRAY: {//rA 1250 | sb.append("r").append(instruction.A()).append(" ").append(instruction.B()); 1251 | if (needNote) { 1252 | sb.append(" $ 创建数组,数组长度为").append(instruction.B()); 1253 | } 1254 | break; 1255 | } 1256 | case OP_TFOREACH: {//rA 1257 | sb.append("r").append(instruction.A()); 1258 | if (needNote) { 1259 | sb.append(" $ 迭代器循环指令,目前Alua仅解释器支持运行,暂不支持编译出这个指令,你看到它多半有问题"); 1260 | } 1261 | break; 1262 | } 1263 | default: { 1264 | sb.append(instruction.value()); 1265 | break; 1266 | } 1267 | } 1268 | sb.append("\n"); 1269 | if (instruction.isEndRealFake) { 1270 | sb.append("$ =================结束假块=================\n"); 1271 | } 1272 | } 1273 | sb.append(".code-end"); 1274 | sb.append("\n"); 1275 | sb.append(".end"); 1276 | sb.append("\n"); 1277 | sb.append("\n"); 1278 | if (needSubXasm) { 1279 | int sizep = f.sizep(); 1280 | for (i = 0; i < sizep; i++) { 1281 | if (subPath == null) { 1282 | sb.append(getXasm(f.p[i], String.valueOf(i), needNote, likeActCode, needSubXasm)); 1283 | } else { 1284 | sb.append(getXasm(f.p[i], subPath + "/" + String.valueOf(i), needNote, likeActCode, needSubXasm)); 1285 | } 1286 | } 1287 | } 1288 | return sb.toString(); 1289 | } 1290 | } 1291 | 1292 | --------------------------------------------------------------------------------