diff options
Diffstat (limited to 'src/luac/opcode.c')
-rw-r--r-- | src/luac/opcode.c | 85 |
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); |