lua/lopcodes.h

Go to the documentation of this file.
00001 /*
00002 ** $Id: lopcodes.h,v 1.2 2004/03/23 05:09:14 jbj Exp $
00003 ** Opcodes for Lua virtual machine
00004 ** See Copyright Notice in lua.h
00005 */
00006 
00007 #ifndef lopcodes_h
00008 #define lopcodes_h
00009 
00010 #include "llimits.h"
00011 
00012 
00013 /*===========================================================================
00014   We assume that instructions are unsigned numbers.
00015   All instructions have an opcode in the first 6 bits.
00016   Instructions can have the following fields:
00017         `A' : 8 bits
00018         `B' : 9 bits
00019         `C' : 9 bits
00020         `Bx' : 18 bits (`B' and `C' together)
00021         `sBx' : signed Bx
00022 
00023   A signed argument is represented in excess K; that is, the number
00024   value is the unsigned value minus K. K is exactly the maximum value
00025   for that argument (so that -max is represented by 0, and +max is
00026   represented by 2*max), which is half the maximum for the corresponding
00027   unsigned argument.
00028 ===========================================================================*/
00029 
00030 
00031 enum OpMode {iABC, iABx, iAsBx};  /* basic instruction format */
00032 
00033 
00034 /*
00035 ** size and position of opcode arguments.
00036 */
00037 #define SIZE_C          9
00038 #define SIZE_B          9
00039 #define SIZE_Bx         (SIZE_C + SIZE_B)
00040 #define SIZE_A          8
00041 
00042 #define SIZE_OP         6
00043 
00044 #define POS_C           SIZE_OP
00045 #define POS_B           (POS_C + SIZE_C)
00046 #define POS_Bx          POS_C
00047 #define POS_A           (POS_B + SIZE_B)
00048 
00049 
00050 /*
00051 ** limits for opcode arguments.
00052 ** we use (signed) int to manipulate most arguments,
00053 ** so they must fit in BITS_INT-1 bits (-1 for sign)
00054 */
00055 #if SIZE_Bx < BITS_INT-1
00056 #define MAXARG_Bx        ((1<<SIZE_Bx)-1)
00057 #define MAXARG_sBx        (MAXARG_Bx>>1)         /* `sBx' is signed */
00058 #else
00059 #define MAXARG_Bx        MAX_INT
00060 #define MAXARG_sBx        MAX_INT
00061 #endif
00062 
00063 
00064 #define MAXARG_A        ((1<<SIZE_A)-1)
00065 #define MAXARG_B        ((1<<SIZE_B)-1)
00066 #define MAXARG_C        ((1<<SIZE_C)-1)
00067 
00068 
00069 /* creates a mask with `n' 1 bits at position `p' */
00070 #define MASK1(n,p)      ((~((~(Instruction)0)<<n))<<p)
00071 
00072 /* creates a mask with `n' 0 bits at position `p' */
00073 #define MASK0(n,p)      (~MASK1(n,p))
00074 
00075 /*
00076 ** the following macros help to manipulate instructions
00077 */
00078 
00079 #define GET_OPCODE(i)   (cast(OpCode, (i)&MASK1(SIZE_OP,0)))
00080 #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | cast(Instruction, o)))
00081 
00082 #define GETARG_A(i)     (cast(int, (i)>>POS_A))
00083 #define SETARG_A(i,u)   ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
00084                 ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
00085 
00086 #define GETARG_B(i)     (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
00087 #define SETARG_B(i,b)   ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
00088                 ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
00089 
00090 #define GETARG_C(i)     (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
00091 #define SETARG_C(i,b)   ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
00092                 ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
00093 
00094 #define GETARG_Bx(i)    (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
00095 #define SETARG_Bx(i,b)  ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
00096                 ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
00097 
00098 #define GETARG_sBx(i)   (GETARG_Bx(i)-MAXARG_sBx)
00099 #define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
00100 
00101 
00102 #define CREATE_ABC(o,a,b,c)     (cast(Instruction, o) \
00103                         | (cast(Instruction, a)<<POS_A) \
00104                         | (cast(Instruction, b)<<POS_B) \
00105                         | (cast(Instruction, c)<<POS_C))
00106 
00107 #define CREATE_ABx(o,a,bc)      (cast(Instruction, o) \
00108                         | (cast(Instruction, a)<<POS_A) \
00109                         | (cast(Instruction, bc)<<POS_Bx))
00110 
00111 
00112 
00113 
00114 /*
00115 ** invalid register that fits in 8 bits
00116 */
00117 #define NO_REG          MAXARG_A
00118 
00119 
00120 /*
00121 ** R(x) - register
00122 ** Kst(x) - constant (in constant table)
00123 ** RK(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK)
00124 */
00125 
00126 
00127 /*
00128 ** grep "ORDER OP" if you change these enums
00129 */
00130 
00131 typedef enum {
00132 /*----------------------------------------------------------------------
00133 name            args    description
00134 ------------------------------------------------------------------------*/
00135 OP_MOVE,/*      A B     R(A) := R(B)                                    */
00136 OP_LOADK,/*     A Bx    R(A) := Kst(Bx)                                 */
00137 OP_LOADBOOL,/*  A B C   R(A) := (Bool)B; if (C) PC++                    */
00138 OP_LOADNIL,/*   A B     R(A) := ... := R(B) := nil                      */
00139 OP_GETUPVAL,/*  A B     R(A) := UpValue[B]                              */
00140 
00141 OP_GETGLOBAL,/* A Bx    R(A) := Gbl[Kst(Bx)]                            */
00142 OP_GETTABLE,/*  A B C   R(A) := R(B)[RK(C)]                             */
00143 
00144 OP_SETGLOBAL,/* A Bx    Gbl[Kst(Bx)] := R(A)                            */
00145 OP_SETUPVAL,/*  A B     UpValue[B] := R(A)                              */
00146 OP_SETTABLE,/*  A B C   R(A)[RK(B)] := RK(C)                            */
00147 
00148 OP_NEWTABLE,/*  A B C   R(A) := {} (size = B,C)                         */
00149 
00150 OP_SELF,/*      A B C   R(A+1) := R(B); R(A) := R(B)[RK(C)]             */
00151 
00152 OP_ADD,/*       A B C   R(A) := RK(B) + RK(C)                           */
00153 OP_SUB,/*       A B C   R(A) := RK(B) - RK(C)                           */
00154 OP_MUL,/*       A B C   R(A) := RK(B) * RK(C)                           */
00155 OP_DIV,/*       A B C   R(A) := RK(B) / RK(C)                           */
00156 OP_POW,/*       A B C   R(A) := RK(B) ^ RK(C)                           */
00157 OP_UNM,/*       A B     R(A) := -R(B)                                   */
00158 OP_NOT,/*       A B     R(A) := not R(B)                                */
00159 
00160 OP_CONCAT,/*    A B C   R(A) := R(B).. ... ..R(C)                       */
00161 
00162 OP_JMP,/*       sBx     PC += sBx                                       */
00163 
00164 OP_EQ,/*        A B C   if ((RK(B) == RK(C)) ~= A) then pc++            */
00165 OP_LT,/*        A B C   if ((RK(B) <  RK(C)) ~= A) then pc++            */
00166 OP_LE,/*        A B C   if ((RK(B) <= RK(C)) ~= A) then pc++            */
00167 
00168 OP_TEST,/*      A B C   if (R(B) <=> C) then R(A) := R(B) else pc++     */ 
00169 
00170 OP_CALL,/*      A B C   R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
00171 OP_TAILCALL,/*  A B C   return R(A)(R(A+1), ... ,R(A+B-1))              */
00172 OP_RETURN,/*    A B     return R(A), ... ,R(A+B-2)      (see note)      */
00173 
00174 OP_FORLOOP,/*   A sBx   R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBx  */
00175 
00176 OP_TFORLOOP,/*  A C     R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); 
00177                         if R(A+2) ~= nil then pc++                      */
00178 OP_TFORPREP,/*  A sBx   if type(R(A)) == table then R(A+1):=R(A), R(A):=next;
00179                         PC += sBx                                       */
00180 
00181 OP_SETLIST,/*   A Bx    R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */
00182 OP_SETLISTO,/*  A Bx                                                    */
00183 
00184 OP_CLOSE,/*     A       close all variables in the stack up to (>=) R(A)*/
00185 OP_CLOSURE/*    A Bx    R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))  */
00186 } OpCode;
00187 
00188 
00189 #define NUM_OPCODES     (cast(int, OP_CLOSURE+1))
00190 
00191 
00192 
00193 /*===========================================================================
00194   Notes:
00195   (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
00196       and can be 0: OP_CALL then sets `top' to last_result+1, so
00197       next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
00198 
00199   (2) In OP_RETURN, if (B == 0) then return up to `top'
00200 
00201   (3) For comparisons, B specifies what conditions the test should accept.
00202 
00203   (4) All `skips' (pc++) assume that next instruction is a jump
00204 ===========================================================================*/
00205 
00206 
00207 /*
00208 ** masks for instruction properties
00209 */  
00210 enum OpModeMask {
00211   OpModeBreg = 2,       /* B is a register */
00212   OpModeBrk,            /* B is a register/constant */
00213   OpModeCrk,           /* C is a register/constant */
00214   OpModesetA,           /* instruction set register A */
00215   OpModeK,              /* Bx is a constant */
00216   OpModeT               /* operator is a test */
00217   
00218 };
00219 
00220 
00221 /*@unchecked@*/
00222 extern const lu_byte luaP_opmodes[NUM_OPCODES];
00223 
00224 #define getOpMode(m)            (cast(enum OpMode, luaP_opmodes[m] & 3))
00225 #define testOpMode(m, b)        (luaP_opmodes[m] & (1 << (b)))
00226 
00227 
00228 #ifdef LUA_OPNAMES
00229 extern const char *const luaP_opnames[];  /* opcode names */
00230 #endif
00231 
00232 
00233 
00234 /* number of list items to accumulate before a SETLIST instruction */
00235 /* (must be a power of 2) */
00236 #define LFIELDS_PER_FLUSH       32
00237 
00238 
00239 #endif

Generated on Fri Oct 12 08:44:54 2007 for rpm by  doxygen 1.5.2