diff src/lua/lopcodes.h @ 11:27763b933818

raise lua sources up one level
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 11:07:39 -0600
parents src/lua/src/lopcodes.h@f9f4f1b99eed
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/lua/lopcodes.h	Sat Mar 03 11:07:39 2012 -0600
     1.3 @@ -0,0 +1,268 @@
     1.4 +/*
     1.5 +** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $
     1.6 +** Opcodes for Lua virtual machine
     1.7 +** See Copyright Notice in lua.h
     1.8 +*/
     1.9 +
    1.10 +#ifndef lopcodes_h
    1.11 +#define lopcodes_h
    1.12 +
    1.13 +#include "llimits.h"
    1.14 +
    1.15 +
    1.16 +/*===========================================================================
    1.17 +  We assume that instructions are unsigned numbers.
    1.18 +  All instructions have an opcode in the first 6 bits.
    1.19 +  Instructions can have the following fields:
    1.20 +	`A' : 8 bits
    1.21 +	`B' : 9 bits
    1.22 +	`C' : 9 bits
    1.23 +	`Bx' : 18 bits (`B' and `C' together)
    1.24 +	`sBx' : signed Bx
    1.25 +
    1.26 +  A signed argument is represented in excess K; that is, the number
    1.27 +  value is the unsigned value minus K. K is exactly the maximum value
    1.28 +  for that argument (so that -max is represented by 0, and +max is
    1.29 +  represented by 2*max), which is half the maximum for the corresponding
    1.30 +  unsigned argument.
    1.31 +===========================================================================*/
    1.32 +
    1.33 +
    1.34 +enum OpMode {iABC, iABx, iAsBx};  /* basic instruction format */
    1.35 +
    1.36 +
    1.37 +/*
    1.38 +** size and position of opcode arguments.
    1.39 +*/
    1.40 +#define SIZE_C		9
    1.41 +#define SIZE_B		9
    1.42 +#define SIZE_Bx		(SIZE_C + SIZE_B)
    1.43 +#define SIZE_A		8
    1.44 +
    1.45 +#define SIZE_OP		6
    1.46 +
    1.47 +#define POS_OP		0
    1.48 +#define POS_A		(POS_OP + SIZE_OP)
    1.49 +#define POS_C		(POS_A + SIZE_A)
    1.50 +#define POS_B		(POS_C + SIZE_C)
    1.51 +#define POS_Bx		POS_C
    1.52 +
    1.53 +
    1.54 +/*
    1.55 +** limits for opcode arguments.
    1.56 +** we use (signed) int to manipulate most arguments,
    1.57 +** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
    1.58 +*/
    1.59 +#if SIZE_Bx < LUAI_BITSINT-1
    1.60 +#define MAXARG_Bx        ((1<<SIZE_Bx)-1)
    1.61 +#define MAXARG_sBx        (MAXARG_Bx>>1)         /* `sBx' is signed */
    1.62 +#else
    1.63 +#define MAXARG_Bx        MAX_INT
    1.64 +#define MAXARG_sBx        MAX_INT
    1.65 +#endif
    1.66 +
    1.67 +
    1.68 +#define MAXARG_A        ((1<<SIZE_A)-1)
    1.69 +#define MAXARG_B        ((1<<SIZE_B)-1)
    1.70 +#define MAXARG_C        ((1<<SIZE_C)-1)
    1.71 +
    1.72 +
    1.73 +/* creates a mask with `n' 1 bits at position `p' */
    1.74 +#define MASK1(n,p)	((~((~(Instruction)0)<<n))<<p)
    1.75 +
    1.76 +/* creates a mask with `n' 0 bits at position `p' */
    1.77 +#define MASK0(n,p)	(~MASK1(n,p))
    1.78 +
    1.79 +/*
    1.80 +** the following macros help to manipulate instructions
    1.81 +*/
    1.82 +
    1.83 +#define GET_OPCODE(i)	(cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
    1.84 +#define SET_OPCODE(i,o)	((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
    1.85 +		((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
    1.86 +
    1.87 +#define GETARG_A(i)	(cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
    1.88 +#define SETARG_A(i,u)	((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
    1.89 +		((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
    1.90 +
    1.91 +#define GETARG_B(i)	(cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
    1.92 +#define SETARG_B(i,b)	((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
    1.93 +		((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
    1.94 +
    1.95 +#define GETARG_C(i)	(cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
    1.96 +#define SETARG_C(i,b)	((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
    1.97 +		((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
    1.98 +
    1.99 +#define GETARG_Bx(i)	(cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
   1.100 +#define SETARG_Bx(i,b)	((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
   1.101 +		((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
   1.102 +
   1.103 +#define GETARG_sBx(i)	(GETARG_Bx(i)-MAXARG_sBx)
   1.104 +#define SETARG_sBx(i,b)	SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
   1.105 +
   1.106 +
   1.107 +#define CREATE_ABC(o,a,b,c)	((cast(Instruction, o)<<POS_OP) \
   1.108 +			| (cast(Instruction, a)<<POS_A) \
   1.109 +			| (cast(Instruction, b)<<POS_B) \
   1.110 +			| (cast(Instruction, c)<<POS_C))
   1.111 +
   1.112 +#define CREATE_ABx(o,a,bc)	((cast(Instruction, o)<<POS_OP) \
   1.113 +			| (cast(Instruction, a)<<POS_A) \
   1.114 +			| (cast(Instruction, bc)<<POS_Bx))
   1.115 +
   1.116 +
   1.117 +/*
   1.118 +** Macros to operate RK indices
   1.119 +*/
   1.120 +
   1.121 +/* this bit 1 means constant (0 means register) */
   1.122 +#define BITRK		(1 << (SIZE_B - 1))
   1.123 +
   1.124 +/* test whether value is a constant */
   1.125 +#define ISK(x)		((x) & BITRK)
   1.126 +
   1.127 +/* gets the index of the constant */
   1.128 +#define INDEXK(r)	((int)(r) & ~BITRK)
   1.129 +
   1.130 +#define MAXINDEXRK	(BITRK - 1)
   1.131 +
   1.132 +/* code a constant index as a RK value */
   1.133 +#define RKASK(x)	((x) | BITRK)
   1.134 +
   1.135 +
   1.136 +/*
   1.137 +** invalid register that fits in 8 bits
   1.138 +*/
   1.139 +#define NO_REG		MAXARG_A
   1.140 +
   1.141 +
   1.142 +/*
   1.143 +** R(x) - register
   1.144 +** Kst(x) - constant (in constant table)
   1.145 +** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
   1.146 +*/
   1.147 +
   1.148 +
   1.149 +/*
   1.150 +** grep "ORDER OP" if you change these enums
   1.151 +*/
   1.152 +
   1.153 +typedef enum {
   1.154 +/*----------------------------------------------------------------------
   1.155 +name		args	description
   1.156 +------------------------------------------------------------------------*/
   1.157 +OP_MOVE,/*	A B	R(A) := R(B)					*/
   1.158 +OP_LOADK,/*	A Bx	R(A) := Kst(Bx)					*/
   1.159 +OP_LOADBOOL,/*	A B C	R(A) := (Bool)B; if (C) pc++			*/
   1.160 +OP_LOADNIL,/*	A B	R(A) := ... := R(B) := nil			*/
   1.161 +OP_GETUPVAL,/*	A B	R(A) := UpValue[B]				*/
   1.162 +
   1.163 +OP_GETGLOBAL,/*	A Bx	R(A) := Gbl[Kst(Bx)]				*/
   1.164 +OP_GETTABLE,/*	A B C	R(A) := R(B)[RK(C)]				*/
   1.165 +
   1.166 +OP_SETGLOBAL,/*	A Bx	Gbl[Kst(Bx)] := R(A)				*/
   1.167 +OP_SETUPVAL,/*	A B	UpValue[B] := R(A)				*/
   1.168 +OP_SETTABLE,/*	A B C	R(A)[RK(B)] := RK(C)				*/
   1.169 +
   1.170 +OP_NEWTABLE,/*	A B C	R(A) := {} (size = B,C)				*/
   1.171 +
   1.172 +OP_SELF,/*	A B C	R(A+1) := R(B); R(A) := R(B)[RK(C)]		*/
   1.173 +
   1.174 +OP_ADD,/*	A B C	R(A) := RK(B) + RK(C)				*/
   1.175 +OP_SUB,/*	A B C	R(A) := RK(B) - RK(C)				*/
   1.176 +OP_MUL,/*	A B C	R(A) := RK(B) * RK(C)				*/
   1.177 +OP_DIV,/*	A B C	R(A) := RK(B) / RK(C)				*/
   1.178 +OP_MOD,/*	A B C	R(A) := RK(B) % RK(C)				*/
   1.179 +OP_POW,/*	A B C	R(A) := RK(B) ^ RK(C)				*/
   1.180 +OP_UNM,/*	A B	R(A) := -R(B)					*/
   1.181 +OP_NOT,/*	A B	R(A) := not R(B)				*/
   1.182 +OP_LEN,/*	A B	R(A) := length of R(B)				*/
   1.183 +
   1.184 +OP_CONCAT,/*	A B C	R(A) := R(B).. ... ..R(C)			*/
   1.185 +
   1.186 +OP_JMP,/*	sBx	pc+=sBx					*/
   1.187 +
   1.188 +OP_EQ,/*	A B C	if ((RK(B) == RK(C)) ~= A) then pc++		*/
   1.189 +OP_LT,/*	A B C	if ((RK(B) <  RK(C)) ~= A) then pc++  		*/
   1.190 +OP_LE,/*	A B C	if ((RK(B) <= RK(C)) ~= A) then pc++  		*/
   1.191 +
   1.192 +OP_TEST,/*	A C	if not (R(A) <=> C) then pc++			*/ 
   1.193 +OP_TESTSET,/*	A B C	if (R(B) <=> C) then R(A) := R(B) else pc++	*/ 
   1.194 +
   1.195 +OP_CALL,/*	A B C	R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
   1.196 +OP_TAILCALL,/*	A B C	return R(A)(R(A+1), ... ,R(A+B-1))		*/
   1.197 +OP_RETURN,/*	A B	return R(A), ... ,R(A+B-2)	(see note)	*/
   1.198 +
   1.199 +OP_FORLOOP,/*	A sBx	R(A)+=R(A+2);
   1.200 +			if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
   1.201 +OP_FORPREP,/*	A sBx	R(A)-=R(A+2); pc+=sBx				*/
   1.202 +
   1.203 +OP_TFORLOOP,/*	A C	R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); 
   1.204 +                        if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++	*/ 
   1.205 +OP_SETLIST,/*	A B C	R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B	*/
   1.206 +
   1.207 +OP_CLOSE,/*	A 	close all variables in the stack up to (>=) R(A)*/
   1.208 +OP_CLOSURE,/*	A Bx	R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))	*/
   1.209 +
   1.210 +OP_VARARG/*	A B	R(A), R(A+1), ..., R(A+B-1) = vararg		*/
   1.211 +} OpCode;
   1.212 +
   1.213 +
   1.214 +#define NUM_OPCODES	(cast(int, OP_VARARG) + 1)
   1.215 +
   1.216 +
   1.217 +
   1.218 +/*===========================================================================
   1.219 +  Notes:
   1.220 +  (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
   1.221 +      and can be 0: OP_CALL then sets `top' to last_result+1, so
   1.222 +      next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
   1.223 +
   1.224 +  (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
   1.225 +      set top (like in OP_CALL with C == 0).
   1.226 +
   1.227 +  (*) In OP_RETURN, if (B == 0) then return up to `top'
   1.228 +
   1.229 +  (*) In OP_SETLIST, if (B == 0) then B = `top';
   1.230 +      if (C == 0) then next `instruction' is real C
   1.231 +
   1.232 +  (*) For comparisons, A specifies what condition the test should accept
   1.233 +      (true or false).
   1.234 +
   1.235 +  (*) All `skips' (pc++) assume that next instruction is a jump
   1.236 +===========================================================================*/
   1.237 +
   1.238 +
   1.239 +/*
   1.240 +** masks for instruction properties. The format is:
   1.241 +** bits 0-1: op mode
   1.242 +** bits 2-3: C arg mode
   1.243 +** bits 4-5: B arg mode
   1.244 +** bit 6: instruction set register A
   1.245 +** bit 7: operator is a test
   1.246 +*/  
   1.247 +
   1.248 +enum OpArgMask {
   1.249 +  OpArgN,  /* argument is not used */
   1.250 +  OpArgU,  /* argument is used */
   1.251 +  OpArgR,  /* argument is a register or a jump offset */
   1.252 +  OpArgK   /* argument is a constant or register/constant */
   1.253 +};
   1.254 +
   1.255 +LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
   1.256 +
   1.257 +#define getOpMode(m)	(cast(enum OpMode, luaP_opmodes[m] & 3))
   1.258 +#define getBMode(m)	(cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
   1.259 +#define getCMode(m)	(cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
   1.260 +#define testAMode(m)	(luaP_opmodes[m] & (1 << 6))
   1.261 +#define testTMode(m)	(luaP_opmodes[m] & (1 << 7))
   1.262 +
   1.263 +
   1.264 +LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1];  /* opcode names */
   1.265 +
   1.266 +
   1.267 +/* number of list items to accumulate before a SETLIST instruction */
   1.268 +#define LFIELDS_PER_FLUSH	50
   1.269 +
   1.270 +
   1.271 +#endif