summaryrefslogtreecommitdiff
path: root/src/luac/opcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/luac/opcode.c')
-rw-r--r--src/luac/opcode.c85
1 files changed, 50 insertions, 35 deletions
diff --git a/src/luac/opcode.c b/src/luac/opcode.c
index c97e46a5..c2d4ae7d 100644
--- a/src/luac/opcode.c
+++ b/src/luac/opcode.c
@@ -1,83 +1,98 @@
/*
-** $Id: opcode.c,v 1.4 1998/07/12 00:17:37 lhf Exp $
+** $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 OpcodeInfo(TProtoFunc* tf, Byte* p, Opcode* I, char* xFILE, int xLINE)
+int luaU_opcodeinfo(TProtoFunc* tf, Byte* p, Opcode* I, char* xFILE, int xLINE)
{
Opcode OP;
Byte* code=tf->code;
int op=*p;
- if (p==code)
+ int size=1;
+ if (p==code) /* first byte is STACK */
{
- OP.name="STACK";
- OP.size=1;
- OP.op=STACK;
- OP.class=STACK;
+ OP=Fake[-STACK];
OP.arg=op;
}
- else if (p==code+1)
+ else if (p==code+1) /* second byte is ARGS or VARARGS */
{
- OP.size=1;
- if (op>=ZEROVARARG)
+ if (op<ZEROVARARG)
{
- OP.name="VARARGS";
- OP.op=VARARGS;
- OP.class=VARARGS;
- OP.arg=op-ZEROVARARG;
+ OP=Fake[-ARGS];
+ OP.arg=op;
}
else
{
- OP.name="ARGS";
- OP.op=ARGS;
- OP.class=ARGS;
- OP.arg=op;
+ OP=Fake[-VARARGS];
+ OP.arg=op-ZEROVARARG;
}
}
- else if (op==NOP)
+ else if (op==NOP) /* NOP is fake */
{
- OP.name="NOP";
- OP.size=1;
- OP.op=NOP;
- OP.class=NOP;
+ OP=Fake[0];
}
else if (op>=NOPCODES) /* cannot happen */
{
- luaL_verror("internal error at %s:%d: bad opcode %d at %d in tf=%p",
- xFILE, xLINE,op,(int)(p-code),tf);
+ luaL_verror("[%s:%d] bad opcode %d at pc=%d" IN,
+ xFILE,xLINE,op,(int)(p-code),INLOC);
return 0;
}
- else
+ else /* ordinary opcode */
{
OP=Info[op];
- if (op==SETLIST || op==CLOSURE || op==CALLFUNC)
+ switch (OP.args)
{
- OP.arg=p[1];
- OP.arg2=p[2];
+ 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;
}
- else if (OP.size==2) OP.arg=p[1];
- else if (OP.size>=3) OP.arg=(p[1]<<8)+p[2];
- if (op==SETLISTW || op==CLOSUREW) OP.arg2=p[3];
}
*I=OP;
- return OP.size;
+ return size;
}
-int CodeSize(TProtoFunc* tf)
+int luaU_codesize(TProtoFunc* tf)
{
Byte* code=tf->code;
Byte* p=code;
- while (1)
+ for (;;)
{
Opcode OP;
p+=INFO(tf,p,&OP);