Imported from ../lua-3.2.tar.gz.
[lua.git] / src / luac / opcode.c
blobc2d4ae7dfc136e4245fc61fdf1d7d2a85d2d41b5
1 /*
2 ** $Id: opcode.c,v 1.9 1999/05/25 19:58:55 lhf Exp $
3 ** opcode information
4 ** See Copyright Notice in lua.h
5 */
7 #include "luac.h"
9 enum { /* for Opcode.args */
10 ARGS_NONE,
11 ARGS_B,
12 ARGS_W,
13 ARGS_BB,
14 ARGS_WB
17 static Opcode Info[]= /* ORDER lopcodes.h */
19 #include "opcode.h"
22 static Opcode Fake[]= /* ORDER luac.h */
24 { "NOP", NOP, NOP, ARGS_NONE, -1, -1 },
25 { "STACK", STACK, STACK, ARGS_B, -1, -1 },
26 { "ARGS", ARGS, ARGS, ARGS_B, -1, -1 },
27 { "VARARGS", VARARGS, VARARGS, ARGS_B, -1, -1 },
30 #define NOPCODES (sizeof(Info)/sizeof(Info[0]))
32 int luaU_opcodeinfo(TProtoFunc* tf, Byte* p, Opcode* I, char* xFILE, int xLINE)
34 Opcode OP;
35 Byte* code=tf->code;
36 int op=*p;
37 int size=1;
38 if (p==code) /* first byte is STACK */
40 OP=Fake[-STACK];
41 OP.arg=op;
43 else if (p==code+1) /* second byte is ARGS or VARARGS */
45 if (op<ZEROVARARG)
47 OP=Fake[-ARGS];
48 OP.arg=op;
50 else
52 OP=Fake[-VARARGS];
53 OP.arg=op-ZEROVARARG;
56 else if (op==NOP) /* NOP is fake */
58 OP=Fake[0];
60 else if (op>=NOPCODES) /* cannot happen */
62 luaL_verror("[%s:%d] bad opcode %d at pc=%d" IN,
63 xFILE,xLINE,op,(int)(p-code),INLOC);
64 return 0;
66 else /* ordinary opcode */
68 OP=Info[op];
69 switch (OP.args)
71 case ARGS_NONE: size=1;
72 break;
73 case ARGS_B: size=2; OP.arg=p[1];
74 break;
75 case ARGS_W: size=3; OP.arg=(p[1]<<8)+p[2];
76 break;
77 case ARGS_BB: size=3; OP.arg=p[1]; OP.arg2=p[2];
78 break;
79 case ARGS_WB: size=4; OP.arg=(p[1]<<8)+p[2]; OP.arg2=p[3];
80 break;
81 default: /* cannot happen */
82 luaL_verror("[%s:%d] bad args %d for %s at pc=%d" IN,
83 __FILE__,__LINE__,OP.args,OP.name,(int)(p-code),INLOC);
84 break;
87 *I=OP;
88 return size;
91 int luaU_codesize(TProtoFunc* tf)
93 Byte* code=tf->code;
94 Byte* p=code;
95 for (;;)
97 Opcode OP;
98 p+=INFO(tf,p,&OP);
99 if (OP.op==ENDCODE) break;
101 return p-code;