?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2. ** $Id: lopcodes.h $
  3. ** Opcodes for Lua virtual machine
  4. ** See Copyright Notice in lua.h
  5. */
  6.  
  7. #ifndef lopcodes_h
  8. #define lopcodes_h
  9.  
  10. #include "llimits.h"
  11.  
  12.  
  13. /*===========================================================================
  14.   We assume that instructions are unsigned 32-bit integers.
  15.   All instructions have an opcode in the first 7 bits.
  16.   Instructions can have the following formats:
  17.  
  18.         3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
  19.         1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  20. iABC          C(8)     |      B(8)     |k|     A(8)      |   Op(7)     |
  21. iABx                Bx(17)               |     A(8)      |   Op(7)     |
  22. iAsBx              sBx (signed)(17)      |     A(8)      |   Op(7)     |
  23. iAx                           Ax(25)                     |   Op(7)     |
  24. isJ                           sJ(25)                     |   Op(7)     |
  25.  
  26.   A signed argument is represented in excess K: the represented value is
  27.   the written unsigned value minus K, where K is half the maximum for the
  28.   corresponding unsigned argument.
  29. ===========================================================================*/
  30.  
  31.  
  32. enum OpMode {iABC, iABx, iAsBx, iAx, isJ};  /* basic instruction formats */
  33.  
  34.  
  35. /*
  36. ** size and position of opcode arguments.
  37. */
  38. #define SIZE_C          8
  39. #define SIZE_B          8
  40. #define SIZE_Bx         (SIZE_C + SIZE_B + 1)
  41. #define SIZE_A          8
  42. #define SIZE_Ax         (SIZE_Bx + SIZE_A)
  43. #define SIZE_sJ         (SIZE_Bx + SIZE_A)
  44.  
  45. #define SIZE_OP         7
  46.  
  47. #define POS_OP          0
  48.  
  49. #define POS_A           (POS_OP + SIZE_OP)
  50. #define POS_k           (POS_A + SIZE_A)
  51. #define POS_B           (POS_k + 1)
  52. #define POS_C           (POS_B + SIZE_B)
  53.  
  54. #define POS_Bx          POS_k
  55.  
  56. #define POS_Ax          POS_A
  57.  
  58. #define POS_sJ          POS_A
  59.  
  60.  
  61. /*
  62. ** limits for opcode arguments.
  63. ** we use (signed) 'int' to manipulate most arguments,
  64. ** so they must fit in ints.
  65. */
  66.  
  67. /* Check whether type 'int' has at least 'b' bits ('b' < 32) */
  68. #define L_INTHASBITS(b)         ((UINT_MAX >> ((b) - 1)) >= 1)
  69.  
  70.  
  71. #if L_INTHASBITS(SIZE_Bx)
  72. #define MAXARG_Bx       ((1<<SIZE_Bx)-1)
  73. #else
  74. #define MAXARG_Bx       MAX_INT
  75. #endif
  76.  
  77. #define OFFSET_sBx      (MAXARG_Bx>>1)         /* 'sBx' is signed */
  78.  
  79.  
  80. #if L_INTHASBITS(SIZE_Ax)
  81. #define MAXARG_Ax       ((1<<SIZE_Ax)-1)
  82. #else
  83. #define MAXARG_Ax       MAX_INT
  84. #endif
  85.  
  86. #if L_INTHASBITS(SIZE_sJ)
  87. #define MAXARG_sJ       ((1 << SIZE_sJ) - 1)
  88. #else
  89. #define MAXARG_sJ       MAX_INT
  90. #endif
  91.  
  92. #define OFFSET_sJ       (MAXARG_sJ >> 1)
  93.  
  94.  
  95. #define MAXARG_A        ((1<<SIZE_A)-1)
  96. #define MAXARG_B        ((1<<SIZE_B)-1)
  97. #define MAXARG_C        ((1<<SIZE_C)-1)
  98. #define OFFSET_sC       (MAXARG_C >> 1)
  99.  
  100. #define int2sC(i)       ((i) + OFFSET_sC)
  101. #define sC2int(i)       ((i) - OFFSET_sC)
  102.  
  103.  
  104. /* creates a mask with 'n' 1 bits at position 'p' */
  105. #define MASK1(n,p)      ((~((~(Instruction)0)<<(n)))<<(p))
  106.  
  107. /* creates a mask with 'n' 0 bits at position 'p' */
  108. #define MASK0(n,p)      (~MASK1(n,p))
  109.  
  110. /*
  111. ** the following macros help to manipulate instructions
  112. */
  113.  
  114. #define GET_OPCODE(i)   (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
  115. #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
  116.                 ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
  117.  
  118. #define checkopm(i,m)   (getOpMode(GET_OPCODE(i)) == m)
  119.  
  120.  
  121. #define getarg(i,pos,size)      (cast_int(((i)>>(pos)) & MASK1(size,0)))
  122. #define setarg(i,v,pos,size)    ((i) = (((i)&MASK0(size,pos)) | \
  123.                 ((cast(Instruction, v)<<pos)&MASK1(size,pos))))
  124.  
  125. #define GETARG_A(i)     getarg(i, POS_A, SIZE_A)
  126. #define SETARG_A(i,v)   setarg(i, v, POS_A, SIZE_A)
  127.  
  128. #define GETARG_B(i)     check_exp(checkopm(i, iABC), getarg(i, POS_B, SIZE_B))
  129. #define GETARG_sB(i)    sC2int(GETARG_B(i))
  130. #define SETARG_B(i,v)   setarg(i, v, POS_B, SIZE_B)
  131.  
  132. #define GETARG_C(i)     check_exp(checkopm(i, iABC), getarg(i, POS_C, SIZE_C))
  133. #define GETARG_sC(i)    sC2int(GETARG_C(i))
  134. #define SETARG_C(i,v)   setarg(i, v, POS_C, SIZE_C)
  135.  
  136. #define TESTARG_k(i)    check_exp(checkopm(i, iABC), (cast_int(((i) & (1u << POS_k)))))
  137. #define GETARG_k(i)     check_exp(checkopm(i, iABC), getarg(i, POS_k, 1))
  138. #define SETARG_k(i,v)   setarg(i, v, POS_k, 1)
  139.  
  140. #define GETARG_Bx(i)    check_exp(checkopm(i, iABx), getarg(i, POS_Bx, SIZE_Bx))
  141. #define SETARG_Bx(i,v)  setarg(i, v, POS_Bx, SIZE_Bx)
  142.  
  143. #define GETARG_Ax(i)    check_exp(checkopm(i, iAx), getarg(i, POS_Ax, SIZE_Ax))
  144. #define SETARG_Ax(i,v)  setarg(i, v, POS_Ax, SIZE_Ax)
  145.  
  146. #define GETARG_sBx(i)  \
  147.         check_exp(checkopm(i, iAsBx), getarg(i, POS_Bx, SIZE_Bx) - OFFSET_sBx)
  148. #define SETARG_sBx(i,b) SETARG_Bx((i),cast_uint((b)+OFFSET_sBx))
  149.  
  150. #define GETARG_sJ(i)  \
  151.         check_exp(checkopm(i, isJ), getarg(i, POS_sJ, SIZE_sJ) - OFFSET_sJ)
  152. #define SETARG_sJ(i,j) \
  153.         setarg(i, cast_uint((j)+OFFSET_sJ), POS_sJ, SIZE_sJ)
  154.  
  155.  
  156. #define CREATE_ABCk(o,a,b,c,k)  ((cast(Instruction, o)<<POS_OP) \
  157.                         | (cast(Instruction, a)<<POS_A) \
  158.                         | (cast(Instruction, b)<<POS_B) \
  159.                         | (cast(Instruction, c)<<POS_C) \
  160.                         | (cast(Instruction, k)<<POS_k))
  161.  
  162. #define CREATE_ABx(o,a,bc)      ((cast(Instruction, o)<<POS_OP) \
  163.                         | (cast(Instruction, a)<<POS_A) \
  164.                         | (cast(Instruction, bc)<<POS_Bx))
  165.  
  166. #define CREATE_Ax(o,a)          ((cast(Instruction, o)<<POS_OP) \
  167.                         | (cast(Instruction, a)<<POS_Ax))
  168.  
  169. #define CREATE_sJ(o,j,k)        ((cast(Instruction, o) << POS_OP) \
  170.                         | (cast(Instruction, j) << POS_sJ) \
  171.                         | (cast(Instruction, k) << POS_k))
  172.  
  173.  
  174. #if !defined(MAXINDEXRK)  /* (for debugging only) */
  175. #define MAXINDEXRK      MAXARG_B
  176. #endif
  177.  
  178.  
  179. /*
  180. ** invalid register that fits in 8 bits
  181. */
  182. #define NO_REG          MAXARG_A
  183.  
  184.  
  185. /*
  186. ** R[x] - register
  187. ** K[x] - constant (in constant table)
  188. ** RK(x) == if k(i) then K[x] else R[x]
  189. */
  190.  
  191.  
  192. /*
  193. ** Grep "ORDER OP" if you change these enums. Opcodes marked with a (*)
  194. ** has extra descriptions in the notes after the enumeration.
  195. */
  196.  
  197. typedef enum {
  198. /*----------------------------------------------------------------------
  199.   name          args    description
  200. ------------------------------------------------------------------------*/
  201. OP_MOVE,/*      A B     R[A] := R[B]                                    */
  202. OP_LOADI,/*     A sBx   R[A] := sBx                                     */
  203. OP_LOADF,/*     A sBx   R[A] := (lua_Number)sBx                         */
  204. OP_LOADK,/*     A Bx    R[A] := K[Bx]                                   */
  205. OP_LOADKX,/*    A       R[A] := K[extra arg]                            */
  206. OP_LOADFALSE,/* A       R[A] := false                                   */
  207. OP_LFALSESKIP,/*A       R[A] := false; pc++     (*)                     */
  208. OP_LOADTRUE,/*  A       R[A] := true                                    */
  209. OP_LOADNIL,/*   A B     R[A], R[A+1], ..., R[A+B] := nil                */
  210. OP_GETUPVAL,/*  A B     R[A] := UpValue[B]                              */
  211. OP_SETUPVAL,/*  A B     UpValue[B] := R[A]                              */
  212.  
  213. OP_GETTABUP,/*  A B C   R[A] := UpValue[B][K[C]:string]                 */
  214. OP_GETTABLE,/*  A B C   R[A] := R[B][R[C]]                              */
  215. OP_GETI,/*      A B C   R[A] := R[B][C]                                 */
  216. OP_GETFIELD,/*  A B C   R[A] := R[B][K[C]:string]                       */
  217.  
  218. OP_SETTABUP,/*  A B C   UpValue[A][K[B]:string] := RK(C)                */
  219. OP_SETTABLE,/*  A B C   R[A][R[B]] := RK(C)                             */
  220. OP_SETI,/*      A B C   R[A][B] := RK(C)                                */
  221. OP_SETFIELD,/*  A B C   R[A][K[B]:string] := RK(C)                      */
  222.  
  223. OP_NEWTABLE,/*  A B C k R[A] := {}                                      */
  224.  
  225. OP_SELF,/*      A B C   R[A+1] := R[B]; R[A] := R[B][RK(C):string]      */
  226.  
  227. OP_ADDI,/*      A B sC  R[A] := R[B] + sC                               */
  228.  
  229. OP_ADDK,/*      A B C   R[A] := R[B] + K[C]:number                      */
  230. OP_SUBK,/*      A B C   R[A] := R[B] - K[C]:number                      */
  231. OP_MULK,/*      A B C   R[A] := R[B] * K[C]:number                      */
  232. OP_MODK,/*      A B C   R[A] := R[B] % K[C]:number                      */
  233. OP_POWK,/*      A B C   R[A] := R[B] ^ K[C]:number                      */
  234. OP_DIVK,/*      A B C   R[A] := R[B] / K[C]:number                      */
  235. OP_IDIVK,/*     A B C   R[A] := R[B] // K[C]:number                     */
  236.  
  237. OP_BANDK,/*     A B C   R[A] := R[B] & K[C]:integer                     */
  238. OP_BORK,/*      A B C   R[A] := R[B] | K[C]:integer                     */
  239. OP_BXORK,/*     A B C   R[A] := R[B] ~ K[C]:integer                     */
  240.  
  241. OP_SHRI,/*      A B sC  R[A] := R[B] >> sC                              */
  242. OP_SHLI,/*      A B sC  R[A] := sC << R[B]                              */
  243.  
  244. OP_ADD,/*       A B C   R[A] := R[B] + R[C]                             */
  245. OP_SUB,/*       A B C   R[A] := R[B] - R[C]                             */
  246. OP_MUL,/*       A B C   R[A] := R[B] * R[C]                             */
  247. OP_MOD,/*       A B C   R[A] := R[B] % R[C]                             */
  248. OP_POW,/*       A B C   R[A] := R[B] ^ R[C]                             */
  249. OP_DIV,/*       A B C   R[A] := R[B] / R[C]                             */
  250. OP_IDIV,/*      A B C   R[A] := R[B] // R[C]                            */
  251.  
  252. OP_BAND,/*      A B C   R[A] := R[B] & R[C]                             */
  253. OP_BOR,/*       A B C   R[A] := R[B] | R[C]                             */
  254. OP_BXOR,/*      A B C   R[A] := R[B] ~ R[C]                             */
  255. OP_SHL,/*       A B C   R[A] := R[B] << R[C]                            */
  256. OP_SHR,/*       A B C   R[A] := R[B] >> R[C]                            */
  257.  
  258. OP_MMBIN,/*     A B C   call C metamethod over R[A] and R[B]    (*)     */
  259. OP_MMBINI,/*    A sB C k        call C metamethod over R[A] and sB      */
  260. OP_MMBINK,/*    A B C k         call C metamethod over R[A] and K[B]    */
  261.  
  262. OP_UNM,/*       A B     R[A] := -R[B]                                   */
  263. OP_BNOT,/*      A B     R[A] := ~R[B]                                   */
  264. OP_NOT,/*       A B     R[A] := not R[B]                                */
  265. OP_LEN,/*       A B     R[A] := #R[B] (length operator)                 */
  266.  
  267. OP_CONCAT,/*    A B     R[A] := R[A].. ... ..R[A + B - 1]               */
  268.  
  269. OP_CLOSE,/*     A       close all upvalues >= R[A]                      */
  270. OP_TBC,/*       A       mark variable A "to be closed"                  */
  271. OP_JMP,/*       sJ      pc += sJ                                        */
  272. OP_EQ,/*        A B k   if ((R[A] == R[B]) ~= k) then pc++              */
  273. OP_LT,/*        A B k   if ((R[A] <  R[B]) ~= k) then pc++              */
  274. OP_LE,/*        A B k   if ((R[A] <= R[B]) ~= k) then pc++              */
  275.  
  276. OP_EQK,/*       A B k   if ((R[A] == K[B]) ~= k) then pc++              */
  277. OP_EQI,/*       A sB k  if ((R[A] == sB) ~= k) then pc++                */
  278. OP_LTI,/*       A sB k  if ((R[A] < sB) ~= k) then pc++                 */
  279. OP_LEI,/*       A sB k  if ((R[A] <= sB) ~= k) then pc++                */
  280. OP_GTI,/*       A sB k  if ((R[A] > sB) ~= k) then pc++                 */
  281. OP_GEI,/*       A sB k  if ((R[A] >= sB) ~= k) then pc++                */
  282.  
  283. OP_TEST,/*      A k     if (not R[A] == k) then pc++                    */
  284. OP_TESTSET,/*   A B k   if (not R[B] == k) then pc++ else R[A] := R[B] (*) */
  285.  
  286. OP_CALL,/*      A B C   R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */
  287. OP_TAILCALL,/*  A B C k return R[A](R[A+1], ... ,R[A+B-1])              */
  288.  
  289. OP_RETURN,/*    A B C k return R[A], ... ,R[A+B-2]      (see note)      */
  290. OP_RETURN0,/*           return                                          */
  291. OP_RETURN1,/*   A       return R[A]                                     */
  292.  
  293. OP_FORLOOP,/*   A Bx    update counters; if loop continues then pc-=Bx; */
  294. OP_FORPREP,/*   A Bx    <check values and prepare counters>;
  295.                         if not to run then pc+=Bx+1;                    */
  296.  
  297. OP_TFORPREP,/*  A Bx    create upvalue for R[A + 3]; pc+=Bx             */
  298. OP_TFORCALL,/*  A C     R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]);  */
  299. OP_TFORLOOP,/*  A Bx    if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */
  300.  
  301. OP_SETLIST,/*   A B C k R[A][C+i] := R[A+i], 1 <= i <= B                */
  302.  
  303. OP_CLOSURE,/*   A Bx    R[A] := closure(KPROTO[Bx])                     */
  304.  
  305. OP_VARARG,/*    A C     R[A], R[A+1], ..., R[A+C-2] = vararg            */
  306.  
  307. OP_VARARGPREP,/*A       (adjust vararg parameters)                      */
  308.  
  309. OP_EXTRAARG/*   Ax      extra (larger) argument for previous opcode     */
  310. } OpCode;
  311.  
  312.  
  313. #define NUM_OPCODES     ((int)(OP_EXTRAARG) + 1)
  314.  
  315.  
  316.  
  317. /*===========================================================================
  318.   Notes:
  319.  
  320.   (*) Opcode OP_LFALSESKIP is used to convert a condition to a boolean
  321.   value, in a code equivalent to (not cond ? false : true).  (It
  322.   produces false and skips the next instruction producing true.)
  323.  
  324.   (*) Opcodes OP_MMBIN and variants follow each arithmetic and
  325.   bitwise opcode. If the operation succeeds, it skips this next
  326.   opcode. Otherwise, this opcode calls the corresponding metamethod.
  327.  
  328.   (*) Opcode OP_TESTSET is used in short-circuit expressions that need
  329.   both to jump and to produce a value, such as (a = b or c).
  330.  
  331.   (*) In OP_CALL, if (B == 0) then B = top - A. If (C == 0), then
  332.   'top' is set to last_result+1, so next open instruction (OP_CALL,
  333.   OP_RETURN*, OP_SETLIST) may use 'top'.
  334.  
  335.   (*) In OP_VARARG, if (C == 0) then use actual number of varargs and
  336.   set top (like in OP_CALL with C == 0).
  337.  
  338.   (*) In OP_RETURN, if (B == 0) then return up to 'top'.
  339.  
  340.   (*) In OP_LOADKX and OP_NEWTABLE, the next instruction is always
  341.   OP_EXTRAARG.
  342.  
  343.   (*) In OP_SETLIST, if (B == 0) then real B = 'top'; if k, then
  344.   real C = EXTRAARG _ C (the bits of EXTRAARG concatenated with the
  345.   bits of C).
  346.  
  347.   (*) In OP_NEWTABLE, B is log2 of the hash size (which is always a
  348.   power of 2) plus 1, or zero for size zero. If not k, the array size
  349.   is C. Otherwise, the array size is EXTRAARG _ C.
  350.  
  351.   (*) For comparisons, k specifies what condition the test should accept
  352.   (true or false).
  353.  
  354.   (*) In OP_MMBINI/OP_MMBINK, k means the arguments were flipped
  355.    (the constant is the first operand).
  356.  
  357.   (*) All 'skips' (pc++) assume that next instruction is a jump.
  358.  
  359.   (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the
  360.   function builds upvalues, which may need to be closed. C > 0 means
  361.   the function is vararg, so that its 'func' must be corrected before
  362.   returning; in this case, (C - 1) is its number of fixed parameters.
  363.  
  364.   (*) In comparisons with an immediate operand, C signals whether the
  365.   original operand was a float. (It must be corrected in case of
  366.   metamethods.)
  367.  
  368. ===========================================================================*/
  369.  
  370.  
  371. /*
  372. ** masks for instruction properties. The format is:
  373. ** bits 0-2: op mode
  374. ** bit 3: instruction set register A
  375. ** bit 4: operator is a test (next instruction must be a jump)
  376. ** bit 5: instruction uses 'L->top' set by previous instruction (when B == 0)
  377. ** bit 6: instruction sets 'L->top' for next instruction (when C == 0)
  378. ** bit 7: instruction is an MM instruction (call a metamethod)
  379. */
  380.  
  381. LUAI_DDEC(const lu_byte luaP_opmodes[NUM_OPCODES];)
  382.  
  383. #define getOpMode(m)    (cast(enum OpMode, luaP_opmodes[m] & 7))
  384. #define testAMode(m)    (luaP_opmodes[m] & (1 << 3))
  385. #define testTMode(m)    (luaP_opmodes[m] & (1 << 4))
  386. #define testITMode(m)   (luaP_opmodes[m] & (1 << 5))
  387. #define testOTMode(m)   (luaP_opmodes[m] & (1 << 6))
  388. #define testMMMode(m)   (luaP_opmodes[m] & (1 << 7))
  389.  
  390. /* "out top" (set top for next instruction) */
  391. #define isOT(i)  \
  392.         ((testOTMode(GET_OPCODE(i)) && GETARG_C(i) == 0) || \
  393.           GET_OPCODE(i) == OP_TAILCALL)
  394.  
  395. /* "in top" (uses top from previous instruction) */
  396. #define isIT(i)         (testITMode(GET_OPCODE(i)) && GETARG_B(i) == 0)
  397.  
  398. #define opmode(mm,ot,it,t,a,m)  \
  399.     (((mm) << 7) | ((ot) << 6) | ((it) << 5) | ((t) << 4) | ((a) << 3) | (m))
  400.  
  401.  
  402. /* number of list items to accumulate before a SETLIST instruction */
  403. #define LFIELDS_PER_FLUSH       50
  404.  
  405. #endif
  406.