123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- --- a/src/lvm.c
- +++ b/src/lvm.c
- @@ -31,6 +31,9 @@
- /* limit for table tag-method chains (to avoid loops) */
- #define MAXTAGLOOP 100
-
- +#ifdef __GNUC__
- +#define COMPUTED_GOTO 1
- +#endif
-
- /*
- * If 'obj' is a string, it is tried to be interpreted as a number.
- @@ -568,12 +571,63 @@ static inline int arith_mode( const TVal
- ARITH_OP1_END
- #endif
-
- +#ifdef COMPUTED_GOTO
- +#define OPCODE_TARGET(op) DO_OP_##op:
- +#define CALL_OPCODE(op) goto *opcodes[op];
- +#define OPCODE_PTR(op) [OP_##op] = &&DO_OP_##op
- +#else
- +#define OPCODE_TARGET(op) case OP_##op:
- +#define CALL_OPCODE(op) switch (op)
- +#endif
- +
-
- void luaV_execute (lua_State *L, int nexeccalls) {
- LClosure *cl;
- StkId base;
- TValue *k;
- const Instruction *pc;
- +#ifdef COMPUTED_GOTO
- + static const void *opcodes[] = {
- + OPCODE_PTR(MOVE),
- + OPCODE_PTR(LOADK),
- + OPCODE_PTR(LOADBOOL),
- + OPCODE_PTR(LOADNIL),
- + OPCODE_PTR(GETUPVAL),
- + OPCODE_PTR(GETGLOBAL),
- + OPCODE_PTR(GETTABLE),
- + OPCODE_PTR(SETGLOBAL),
- + OPCODE_PTR(SETUPVAL),
- + OPCODE_PTR(SETTABLE),
- + OPCODE_PTR(NEWTABLE),
- + OPCODE_PTR(SELF),
- + OPCODE_PTR(ADD),
- + OPCODE_PTR(SUB),
- + OPCODE_PTR(MUL),
- + OPCODE_PTR(DIV),
- + OPCODE_PTR(MOD),
- + OPCODE_PTR(POW),
- + OPCODE_PTR(UNM),
- + OPCODE_PTR(NOT),
- + OPCODE_PTR(LEN),
- + OPCODE_PTR(CONCAT),
- + OPCODE_PTR(JMP),
- + OPCODE_PTR(EQ),
- + OPCODE_PTR(LT),
- + OPCODE_PTR(LE),
- + OPCODE_PTR(TEST),
- + OPCODE_PTR(TESTSET),
- + OPCODE_PTR(CALL),
- + OPCODE_PTR(TAILCALL),
- + OPCODE_PTR(RETURN),
- + OPCODE_PTR(FORLOOP),
- + OPCODE_PTR(FORPREP),
- + OPCODE_PTR(TFORLOOP),
- + OPCODE_PTR(SETLIST),
- + OPCODE_PTR(CLOSE),
- + OPCODE_PTR(CLOSURE),
- + OPCODE_PTR(VARARG)
- + };
- +#endif
- reentry: /* entry point */
- lua_assert(isLua(L->ci));
- pc = L->savedpc;
- @@ -598,33 +652,33 @@ void luaV_execute (lua_State *L, int nex
- lua_assert(base == L->base && L->base == L->ci->base);
- lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
- lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
- - switch (GET_OPCODE(i)) {
- - case OP_MOVE: {
- + CALL_OPCODE(GET_OPCODE(i)) {
- + OPCODE_TARGET(MOVE) {
- setobjs2s(L, ra, RB(i));
- continue;
- }
- - case OP_LOADK: {
- + OPCODE_TARGET(LOADK) {
- setobj2s(L, ra, KBx(i));
- continue;
- }
- - case OP_LOADBOOL: {
- + OPCODE_TARGET(LOADBOOL) {
- setbvalue(ra, GETARG_B(i));
- if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
- continue;
- }
- - case OP_LOADNIL: {
- + OPCODE_TARGET(LOADNIL) {
- TValue *rb = RB(i);
- do {
- setnilvalue(rb--);
- } while (rb >= ra);
- continue;
- }
- - case OP_GETUPVAL: {
- + OPCODE_TARGET(GETUPVAL) {
- int b = GETARG_B(i);
- setobj2s(L, ra, cl->upvals[b]->v);
- continue;
- }
- - case OP_GETGLOBAL: {
- + OPCODE_TARGET(GETGLOBAL) {
- TValue g;
- TValue *rb = KBx(i);
- sethvalue(L, &g, cl->env);
- @@ -632,88 +686,88 @@ void luaV_execute (lua_State *L, int nex
- Protect(luaV_gettable(L, &g, rb, ra));
- continue;
- }
- - case OP_GETTABLE: {
- + OPCODE_TARGET(GETTABLE) {
- Protect(luaV_gettable(L, RB(i), RKC(i), ra));
- continue;
- }
- - case OP_SETGLOBAL: {
- + OPCODE_TARGET(SETGLOBAL) {
- TValue g;
- sethvalue(L, &g, cl->env);
- lua_assert(ttisstring(KBx(i)));
- Protect(luaV_settable(L, &g, KBx(i), ra));
- continue;
- }
- - case OP_SETUPVAL: {
- + OPCODE_TARGET(SETUPVAL) {
- UpVal *uv = cl->upvals[GETARG_B(i)];
- setobj(L, uv->v, ra);
- luaC_barrier(L, uv, ra);
- continue;
- }
- - case OP_SETTABLE: {
- + OPCODE_TARGET(SETTABLE) {
- Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
- continue;
- }
- - case OP_NEWTABLE: {
- + OPCODE_TARGET(NEWTABLE) {
- int b = GETARG_B(i);
- int c = GETARG_C(i);
- sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
- Protect(luaC_checkGC(L));
- continue;
- }
- - case OP_SELF: {
- + OPCODE_TARGET(SELF) {
- StkId rb = RB(i);
- setobjs2s(L, ra+1, rb);
- Protect(luaV_gettable(L, rb, RKC(i), ra));
- continue;
- }
- - case OP_ADD: {
- + OPCODE_TARGET(ADD) {
- TValue *rb = RKB(i), *rc= RKC(i);
- arith_op_continue( luai_numadd, try_addint, luai_vectadd );
- Protect(Arith(L, ra, rb, rc, TM_ADD)); \
- continue;
- }
- - case OP_SUB: {
- + OPCODE_TARGET(SUB) {
- TValue *rb = RKB(i), *rc= RKC(i);
- arith_op_continue( luai_numsub, try_subint, luai_vectsub );
- Protect(Arith(L, ra, rb, rc, TM_SUB));
- continue;
- }
- - case OP_MUL: {
- + OPCODE_TARGET(MUL) {
- TValue *rb = RKB(i), *rc= RKC(i);
- arith_op_continue(luai_nummul, try_mulint, luai_vectmul);
- Protect(Arith(L, ra, rb, rc, TM_MUL));
- continue;
- }
- - case OP_DIV: {
- + OPCODE_TARGET(DIV) {
- TValue *rb = RKB(i), *rc= RKC(i);
- arith_op_continue(luai_numdiv, try_divint, luai_vectdiv);
- Protect(Arith(L, ra, rb, rc, TM_DIV));
- continue;
- }
- - case OP_MOD: {
- + OPCODE_TARGET(MOD) {
- TValue *rb = RKB(i), *rc= RKC(i);
- arith_op_continue_scalar(luai_nummod, try_modint); /* scalars only */
- Protect(Arith(L, ra, rb, rc, TM_MOD));
- continue;
- }
- - case OP_POW: {
- + OPCODE_TARGET(POW) {
- TValue *rb = RKB(i), *rc= RKC(i);
- arith_op_continue(luai_numpow, try_powint, luai_vectpow);
- Protect(Arith(L, ra, rb, rc, TM_POW));
- continue;
- }
- - case OP_UNM: {
- + OPCODE_TARGET(UNM) {
- TValue *rb = RB(i);
- arith_op1_continue(luai_numunm, try_unmint, luai_vectunm);
- Protect(Arith(L, ra, rb, rb, TM_UNM));
- continue;
- }
- - case OP_NOT: {
- + OPCODE_TARGET(NOT) {
- int res = l_isfalse(RB(i)); /* next assignment may change this value */
- setbvalue(ra, res);
- continue;
- }
- - case OP_LEN: {
- + OPCODE_TARGET(LEN) {
- const TValue *rb = RB(i);
- switch (ttype(rb)) {
- case LUA_TTABLE: {
- @@ -733,18 +787,18 @@ void luaV_execute (lua_State *L, int nex
- }
- continue;
- }
- - case OP_CONCAT: {
- + OPCODE_TARGET(CONCAT) {
- int b = GETARG_B(i);
- int c = GETARG_C(i);
- Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
- setobjs2s(L, RA(i), base+b);
- continue;
- }
- - case OP_JMP: {
- + OPCODE_TARGET(JMP) {
- dojump(L, pc, GETARG_sBx(i));
- continue;
- }
- - case OP_EQ: {
- + OPCODE_TARGET(EQ) {
- TValue *rb = RKB(i);
- TValue *rc = RKC(i);
- Protect(
- @@ -754,7 +808,7 @@ void luaV_execute (lua_State *L, int nex
- pc++;
- continue;
- }
- - case OP_LT: {
- + OPCODE_TARGET(LT) {
- Protect(
- if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
- dojump(L, pc, GETARG_sBx(*pc));
- @@ -762,7 +816,7 @@ void luaV_execute (lua_State *L, int nex
- pc++;
- continue;
- }
- - case OP_LE: {
- + OPCODE_TARGET(LE) {
- Protect(
- if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
- dojump(L, pc, GETARG_sBx(*pc));
- @@ -770,13 +824,13 @@ void luaV_execute (lua_State *L, int nex
- pc++;
- continue;
- }
- - case OP_TEST: {
- + OPCODE_TARGET(TEST) {
- if (l_isfalse(ra) != GETARG_C(i))
- dojump(L, pc, GETARG_sBx(*pc));
- pc++;
- continue;
- }
- - case OP_TESTSET: {
- + OPCODE_TARGET(TESTSET) {
- TValue *rb = RB(i);
- if (l_isfalse(rb) != GETARG_C(i)) {
- setobjs2s(L, ra, rb);
- @@ -785,7 +839,7 @@ void luaV_execute (lua_State *L, int nex
- pc++;
- continue;
- }
- - case OP_CALL: {
- + OPCODE_TARGET(CALL) {
- int b = GETARG_B(i);
- int nresults = GETARG_C(i) - 1;
- if (b != 0) L->top = ra+b; /* else previous instruction set top */
- @@ -806,7 +860,7 @@ void luaV_execute (lua_State *L, int nex
- }
- }
- }
- - case OP_TAILCALL: {
- + OPCODE_TARGET(TAILCALL) {
- int b = GETARG_B(i);
- if (b != 0) L->top = ra+b; /* else previous instruction set top */
- L->savedpc = pc;
- @@ -838,7 +892,7 @@ void luaV_execute (lua_State *L, int nex
- }
- }
- }
- - case OP_RETURN: {
- + OPCODE_TARGET(RETURN) {
- int b = GETARG_B(i);
- if (b != 0) L->top = ra+b-1;
- if (L->openupval) luaF_close(L, base);
- @@ -853,7 +907,7 @@ void luaV_execute (lua_State *L, int nex
- goto reentry;
- }
- }
- - case OP_FORLOOP: {
- + OPCODE_TARGET(FORLOOP) {
- /* If start,step and limit are all integers, we don't need to check
- * against overflow in the looping.
- */
- @@ -881,7 +935,7 @@ void luaV_execute (lua_State *L, int nex
- }
- continue;
- }
- - case OP_FORPREP: {
- + OPCODE_TARGET(FORPREP) {
- const TValue *init = ra;
- const TValue *plimit = ra+1;
- const TValue *pstep = ra+2;
- @@ -904,7 +958,7 @@ void luaV_execute (lua_State *L, int nex
- dojump(L, pc, GETARG_sBx(i));
- continue;
- }
- - case OP_TFORLOOP: {
- + OPCODE_TARGET(TFORLOOP) {
- StkId cb = ra + 3; /* call base */
- setobjs2s(L, cb+2, ra+2);
- setobjs2s(L, cb+1, ra+1);
- @@ -920,7 +974,7 @@ void luaV_execute (lua_State *L, int nex
- pc++;
- continue;
- }
- - case OP_SETLIST: {
- + OPCODE_TARGET(SETLIST) {
- int n = GETARG_B(i);
- int c = GETARG_C(i);
- int last;
- @@ -942,11 +996,11 @@ void luaV_execute (lua_State *L, int nex
- }
- continue;
- }
- - case OP_CLOSE: {
- + OPCODE_TARGET(CLOSE) {
- luaF_close(L, ra);
- continue;
- }
- - case OP_CLOSURE: {
- + OPCODE_TARGET(CLOSURE) {
- Proto *p;
- Closure *ncl;
- int nup, j;
- @@ -966,7 +1020,7 @@ void luaV_execute (lua_State *L, int nex
- Protect(luaC_checkGC(L));
- continue;
- }
- - case OP_VARARG: {
- + OPCODE_TARGET(VARARG) {
- int b = GETARG_B(i) - 1;
- int j;
- CallInfo *ci = L->ci;
|