package lua; /** * Constants for lua limits and opcodes * * @author jim_roseborough * */ public class Lua { // from llimits.h /** maximum stack for a Lua function */ public static final int MAXSTACK = 250; /** minimum size for the string table (must be power of 2) */ public static final int MINSTRTABSIZE = 32; /** minimum size for string buffer */ public static final int LUA_MINBUFFER = 32; // from lopcodes.h /*=========================================================================== We assume that instructions are unsigned numbers. All instructions have an opcode in the first 6 bits. Instructions can have the following fields: `A' : 8 bits `B' : 9 bits `C' : 9 bits `Bx' : 18 bits (`B' and `C' together) `sBx' : signed Bx A signed argument is represented in excess K; that is, the number value is the unsigned value minus K. K is exactly the maximum value for that argument (so that -max is represented by 0, and +max is represented by 2*max), which is half the maximum for the corresponding unsigned argument. ===========================================================================*/ /* basic instruction format */ public static final int iABC = 0; public static final int iABx = 1; public static final int iAsBx = 2; /* ** size and position of opcode arguments. */ public static final int SIZE_C = 9; public static final int SIZE_B = 9; public static final int SIZE_Bx = (SIZE_C + SIZE_B); public static final int SIZE_A = 8; public static final int SIZE_OP = 6; public static final int POS_OP = 0; public static final int POS_A = (POS_OP + SIZE_OP); public static final int POS_C = (POS_A + SIZE_A); public static final int POS_B = (POS_C + SIZE_C); public static final int POS_Bx = POS_C; public static final int MAX_OP = ((1<>1); /* `sBx' is signed */ public static final int MASK_OP = ((1<> POS_OP) & MAX_OP; } public static int SET_OPCODE(int i,int o) { return (i & (MASK_NOT_OP)) | ((o & MAX_OP) << POS_OP); } public static int GETARG_A(int i) { return (i >> POS_A) & MAXARG_A; } public static int SETARG_A(int i,int u) { return (i & (MASK_NOT_A)) | ((u & MAXARG_A) << POS_A); } public static int GETARG_B(int i) { return (i >> POS_B) & MAXARG_B; } public static int SETARG_B(int i,int u) { return (i & (MASK_NOT_B)) | ((u & MAXARG_B) << POS_B); } public static int GETARG_C(int i) { return (i >> POS_C) & MAXARG_C; } public static int SETARG_C(int i,int u) { return (i & (MASK_NOT_C)) | ((u & MAXARG_C) << POS_C); } public static int GETARG_Bx(int i) { return (i >> POS_Bx) & MAXARG_Bx; } public static int SETARG_Bx(int i,int u) { return (i & (MASK_NOT_Bx)) | ((u & MAXARG_Bx) << POS_Bx); } public static int GETARG_sBx(int i) { return ((i >> POS_Bx) & MAXARG_Bx) - MAXARG_sBx; } public static int SETARG_sBx(int i,int u) { return (i & (MASK_NOT_Bx)) | ((u + MAXARG_sBx) << POS_Bx); } public static int CREATE_ABC(int o, int a, int b, int c) { return (o< C) then pc++ */ public static final int OP_TESTSET = 27; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ public static final int OP_CALL = 28; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ public static final int OP_TAILCALL = 29; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ public static final int OP_RETURN = 30; /* A B return R(A), ... ,R(A+B-2) (see note) */ public static final int OP_FORLOOP = 31; /* A sBx R(A)+=R(A+2); if R(A) =) R(A)*/ public static final int OP_CLOSURE = 36; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ public static final int OP_VARARG = 37; /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ public static final int NUM_OPCODES = OP_VARARG + 1; /*=========================================================================== Notes: (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, and can be 0: OP_CALL then sets `top' to last_result+1, so next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. (*) In OP_VARARG, if (B == 0) then use actual number of varargs and set top (like in OP_CALL with C == 0). (*) In OP_RETURN, if (B == 0) then return up to `top' (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next `instruction' is real C (*) For comparisons, A specifies what condition the test should accept (true or false). (*) All `skips' (pc++) assume that next instruction is a jump ===========================================================================*/ /* ** masks for instruction properties. The format is: ** bits 0-1: op mode ** bits 2-3: C arg mode ** bits 4-5: B arg mode ** bit 6: instruction set register A ** bit 7: operator is a test */ public static final int OpArgN = 0; /* argument is not used */ public static final int OpArgU = 1; /* argument is used */ public static final int OpArgR = 2; /* argument is a register or a jump offset */ public static final int OpArgK = 3; /* argument is a constant or register/constant */ public static final int[] luaP_opmodes = { /* T A B C mode opcode */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_MOVE */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_LOADK */ (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_LOADBOOL */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LOADNIL */ (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_GETUPVAL */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_GETGLOBAL */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgK<<2) | (iABC), /* OP_GETTABLE */ (0<<7) | (0<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_SETGLOBAL */ (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_SETUPVAL */ (0<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SETTABLE */ (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_NEWTABLE */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgK<<2) | (iABC), /* OP_SELF */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_ADD */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SUB */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MUL */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_DIV */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MOD */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_POW */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_UNM */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_NOT */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LEN */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgR<<2) | (iABC), /* OP_CONCAT */ (0<<7) | (0<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_JMP */ (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_EQ */ (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_LT */ (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_LE */ (1<<7) | (1<<6) | (OpArgR<<4) | (OpArgU<<2) | (iABC), /* OP_TEST */ (1<<7) | (1<<6) | (OpArgR<<4) | (OpArgU<<2) | (iABC), /* OP_TESTSET */ (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_CALL */ (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_TAILCALL */ (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_RETURN */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_FORLOOP */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_FORPREP */ (1<<7) | (0<<6) | (OpArgN<<4) | (OpArgU<<2) | (iABC), /* OP_TFORLOOP */ (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_SETLIST */ (0<<7) | (0<<6) | (OpArgN<<4) | (OpArgN<<2) | (iABC), /* OP_CLOSE */ (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABx), /* OP_CLOSURE */ (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_VARARG */ }; public static int getOpMode(int m) { return luaP_opmodes[m] & 3; } public static int getBMode(int m) { return (luaP_opmodes[m] >> 4) & 3; } public static int getCMode(int m) { return (luaP_opmodes[m] >> 2) & 3; } public static boolean testAMode(int m) { return 0 != (luaP_opmodes[m] & (1 << 6)); } public static boolean testTMode(int m) { return 0 != (luaP_opmodes[m] & (1 << 7)); } /** opcode names */ public static final String[] luaP_opnames = { "MOVE", "LOADK", "LOADBOOL", "LOADNIL", "GETUPVAL", "GETGLOBAL", "GETTABLE", "SETGLOBAL", "SETUPVAL", "SETTABLE", "NEWTABLE", "SELF", "ADD", "SUB", "MUL", "DIV", "MOD", "POW", "UNM", "NOT", "LEN", "CONCAT", "JMP", "EQ", "LT", "LE", "TEST", "TESTSET", "CALL", "TAILCALL", "RETURN", "FORLOOP", "FORPREP", "TFORLOOP", "SETLIST", "CLOSE", "CLOSURE", "VARARG", null, }; /** number of list items to accumulate before a SETLIST instruction */ public static final int LFIELDS_PER_FLUSH = 50; }