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