diff --git a/lopcodes.h b/lopcodes.h index ccab6341..7ba79e25 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.2 1997/09/19 18:40:32 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -8,6 +8,13 @@ #define lopcodes_h +/* +** NOTICE: variants of the same opcode (like PUSH0, PUSHBYTE, PUSHWORD) must +** be consecutive: First, those with built-in parameters, then with byte +** parameter and last with word parameter. +*/ + + typedef enum { /* name parm before after side effect -----------------------------------------------------------------------------*/ @@ -15,15 +22,19 @@ ENDCODE, PUSHNIL,/* - nil */ PUSHNILS,/* b - nil_1...nil_b */ + PUSH0,/* - 0.0 */ PUSH1,/* - 1.0 */ PUSH2,/* - 2.0 */ PUSHBYTE,/* b - (float)b */ PUSHWORD,/* w - (float)w */ + PUSHCONSTANTB,/*b - CNST[b] */ PUSHCONSTANT,/* w - CNST[w] */ + PUSHUPVALUE0, PUSHUPVALUE,/* b - Closure[b] */ + PUSHLOCAL0,/* - LOC[0] */ PUSHLOCAL1,/* - LOC[1] */ PUSHLOCAL2,/* - LOC[2] */ @@ -35,10 +46,15 @@ PUSHLOCAL7,/* - LOC[7] */ PUSHLOCAL8,/* - LOC[8] */ PUSHLOCAL9,/* - LOC[9] */ PUSHLOCAL,/* b - LOC[b] */ -PUSHGLOBALB,/* b - VAR[CNST[b]] */ -PUSHGLOBAL,/* w - VAR[CNST[w]] */ + +GETGLOBALB,/* b - VAR[CNST[b]] */ +GETGLOBAL,/* w - VAR[CNST[w]] */ + GETTABLE,/* i t t[i] */ + +PUSHSELFB,/* b t t t[CNST[b]] */ PUSHSELF,/* w t t t[CNST[w]] */ + CREATEARRAY,/* w - newarray(size = w) */ SETLOCAL0,/* x - LOC[0]=x */ @@ -52,10 +68,13 @@ SETLOCAL7,/* x - LOC[7]=x */ SETLOCAL8,/* x - LOC[8]=x */ SETLOCAL9,/* x - LOC[9]=x */ SETLOCAL,/* b x - LOC[b]=x */ + SETGLOBALB,/* b x - VAR[CNST[b]]=x */ SETGLOBAL,/* w x - VAR[CNST[w]]=x */ + SETTABLE0,/* v i t - t[i]=v */ SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */ + SETLIST0,/* b v_b...v_1 t - t[i]=v_i */ SETLIST,/* b c v_b...v_1 t - t[i+c*FPF]=v_i */ SETMAP,/* b v_b k_b ...v_1 k_1 t t t[k_i]=v_i */ @@ -82,10 +101,14 @@ UPJMP,/* w - - PC-=w */ IFFJMP,/* w x - (x==nil)? PC+=w */ IFFUPJMP,/* w x - (x==nil)? PC-=w */ -CLOSURE,/* f v_1...v_n c(f) */ +CLOSUREB,/* b v_1...v_n c(CNST[b]) */ +CLOSURE,/* w v_1...v_n c(CNST[w]) */ + CALLFUNC,/* b c v_b...v_1 f r_c...r_1 f(v1,...,v_b) */ RETCODE,/* b - - */ SETLINE,/* w - - LINE=w */ +POP1,/* - - TOP-=1 */ +POP2,/* - - TOP-=2 */ POPS,/* b - - TOP-=b */ ARGS,/* b - - TOP=BASE+b */ VARARGS/* b v_x...v_1 {v_1...v_x;n=x} TOP=BASE+b+1 */ diff --git a/lua.stx b/lua.stx index 51159737..c7d90e20 100644 --- a/lua.stx +++ b/lua.stx @@ -1,6 +1,6 @@ %{ /* -** $Id: lua.stx,v 1.2 1997/09/19 18:40:32 roberto Exp roberto $ +** $Id: lua.stx,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $ ** Syntax analizer and code generator ** See Copyright Notice in lua.h */ @@ -94,6 +94,22 @@ static void code_byte (Byte c) } +static void code_word_at (int pc, int n) +{ + Word w = n; + if (w != n) + luaY_error("block too big"); + currState->f->code[pc] = n&0xFF; + currState->f->code[pc+1] = n>>8; +} + +static void code_word (int n) +{ + code_byte(n&0xFF); + code_byte(n>>8); +} + + static void deltastack (int delta) { currState->stacksize += delta; @@ -112,9 +128,25 @@ static void code_opcode (OpCode op, int delta) } -static void code_push (OpCode op) +static void code_opborw(OpCode opbyte, int arg, int delta) { - code_opcode(op, 1); + if (arg <= 255) { + code_opcode(opbyte, delta); + code_byte(arg); + } + else { + code_opcode(opbyte+1, delta); + code_word(arg); + } +} + + +static void code_oparg (OpCode firstop, OpCode opbyte, int arg, int delta) +{ + if (firstop+arg < opbyte) + code_opcode(firstop+arg, delta); + else + code_opborw(opbyte, arg, delta); } @@ -133,31 +165,9 @@ static void code_pop (OpCode op) #define code_unop(op) code_neutralop(op) -static void code_word_at (int pc, int n) -{ - Word w = n; - if (w != n) - luaY_error("block too big"); - currState->f->code[pc] = n&0xFF; - currState->f->code[pc+1] = n>>8; -} - -static void code_word (int n) -{ - code_byte(n&0xFF); - code_byte(n>>8); -} - static void code_constant (int c) { - if (c <= 255) { - code_push(PUSHCONSTANTB); - code_byte(c); - } - else { - code_push(PUSHCONSTANT); - code_word(c); - } + code_opborw(PUSHCONSTANTB, c, 1); } @@ -216,18 +226,8 @@ static int real_constant (real r) static void code_number (real f) { Word i; - if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) { - /* f has an (short) integer value */ - if (i <= 2) code_push(PUSH0 + i); - else if (i <= 255) { - code_push(PUSHBYTE); - code_byte(i); - } - else { - code_push(PUSHWORD); - code_word(i); - } - } + if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) + code_oparg(PUSH0, PUSHBYTE, i, 1); /* f has an (short) integer value */ else code_constant(real_constant(f)); } @@ -344,12 +344,7 @@ static void pushupvalue (TaggedString *n) if (aux_localname(n, currState) >= 0) luaY_syntaxerror("cannot access an upvalue in current scope", n->str); i = indexupvalue(n); - if (i == 0) - code_push(PUSHUPVALUE0); - else { - code_push(PUSHUPVALUE); - code_byte(i); - } + code_oparg(PUSHUPVALUE0, PUSHUPVALUE, i, 1); } @@ -366,18 +361,10 @@ void luaY_codedebugline (int line) static void adjuststack (int n) { - if (n > 0) { - code_opcode(POPS, -n); - code_byte(n); - } - else if (n < 0) { - if (n == -1) - code_push(PUSHNIL); - else { - code_opcode(PUSHNILS, -n); - code_byte(-n); - } - } + if (n > 0) + code_oparg(POP1-1, POPS, n, -n); /* POP1-1 = POP0 */ + else if (n < 0) + code_oparg(PUSHNIL-1, PUSHNILS, -n, -n); /* PUSHNIL1-1 = PUSHNIL0 */ } @@ -426,29 +413,12 @@ static void code_args (int dots) static void lua_pushvar (vardesc number) { - if (number > 0) { /* global var */ - number--; - if (number <= 255) { - code_push(PUSHGLOBALB); - code_byte(number); - } - else { - code_push(PUSHGLOBAL); - code_word(number); - } - } - else if (number < 0) { /* local var */ - number = (-number) - 1; - if (number < 10) - code_push(PUSHLOCAL0 + number); - else { - code_push(PUSHLOCAL); - code_byte(number); - } - } - else { + if (number > 0) /* global var */ + code_opborw(GETGLOBALB, number-1, 1); + else if (number < 0) /* local var */ + code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1); + else code_pop(GETTABLE); - } } @@ -456,26 +426,10 @@ static void storevar (vardesc number) { if (number == 0) /* indexed var */ code_opcode(SETTABLE0, -3); - else if (number > 0) { /* global var */ - number--; - if (number <= 255) { - code_pop(SETGLOBALB); - code_byte(number); - } - else { - code_pop(SETGLOBAL); - code_word(number); - } - } - else { /* number < 0 - local var */ - number = (-number) - 1; - if (number < 10) - code_pop(SETLOCAL0 + number); - else { - code_pop(SETLOCAL); - code_byte(number); - } - } + else if (number > 0) /* global var */ + code_opborw(SETGLOBALB, number-1, -1); + else /* number < 0 - local var */ + code_oparg(SETLOCAL0, SETLOCAL, (-number)-1, -1); } @@ -535,8 +489,7 @@ static void func_onstack (TProtoFunc *f) currState->f->consts[c].value.tf = (currState+1)->f; for (i=0; iupvalues[i]); - code_constant(c); - code_opcode(CLOSURE, -nupvalues); + code_opborw(CLOSUREB, c, 1-nupvalues); } @@ -771,7 +724,7 @@ expr : '(' expr ')' { $$ = $2; } | varexp { $$ = 0;} | NUMBER { code_number($1); $$ = 0; } | STRING { code_string($1); $$ = 0; } - | NIL {code_push(PUSHNIL); $$ = 0; } + | NIL {code_opcode(PUSHNIL, 1); $$ = 0; } | functioncall { $$ = $1; } | expr1 AND PrepJumpPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; } | expr1 OR PrepJumpPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; } @@ -779,14 +732,9 @@ expr : '(' expr ')' { $$ = $2; } ; table : - { - code_push(CREATEARRAY); - $$ = currState->pc; code_word(0); - } - '{' fieldlist '}' - { - code_word_at($1, $3); - } + { code_opcode(CREATEARRAY, 1); $$ = currState->pc; code_word(0); } + '{' fieldlist '}' + { code_word_at($1, $3); } ; functioncall : funcvalue funcParams @@ -801,8 +749,7 @@ functioncall : funcvalue funcParams funcvalue : varexp { $$ = 0; } | varexp ':' NAME { - code_push(PUSHSELF); - code_word(string_constant($3, currState)); + code_opborw(PUSHSELFB, string_constant($3, currState), 1); $$ = 1; } ; @@ -909,15 +856,8 @@ varlist1 : var ; var : singlevar { $$ = $1; } - | varexp '[' expr1 ']' - { - $$ = 0; /* indexed variable */ - } - | varexp '.' NAME - { - code_string($3); - $$ = 0; /* indexed variable */ - } + | varexp '[' expr1 ']' { $$ = 0; } /* indexed variable */ + | varexp '.' NAME { code_string($3); $$ = 0; }/* ind. var. */ ; singlevar : NAME { $$ = singlevar($1, currState); } diff --git a/lvm.c b/lvm.c index 50213247..90237f14 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.2 1997/09/19 18:40:32 roberto Exp roberto $ +** $Id: lvm.c,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -28,7 +28,7 @@ /* Extra stack to run a function: LUA_T_LINE(1), TM calls(2), ... */ -#define EXTRA_STACK 4 +#define EXTRA_STACK 5 @@ -276,14 +276,14 @@ static void adjust_varargs (StkId first_extra_arg) */ StkId luaV_execute (Closure *cl, StkId base) { - TProtoFunc *func = cl->consts[0].value.tf; - Byte *pc = func->code; + Byte *pc = cl->consts[0].value.tf->code; + TObject *consts = cl->consts[0].value.tf->consts; if (lua_callhook) luaD_callHook(base, LUA_T_MARK, 0); luaD_checkstack((*pc++)+EXTRA_STACK); while (1) { - OpCode opcode; - switch (opcode = (OpCode)*pc++) { + int aux; + switch ((OpCode)(aux = *pc++)) { case PUSHNIL: ttype(luaD_stack.top++) = LUA_T_NIL; @@ -296,89 +296,95 @@ StkId luaV_execute (Closure *cl, StkId base) break; } - case PUSH0: case PUSH1: case PUSH2: - ttype(luaD_stack.top) = LUA_T_NUMBER; - nvalue(luaD_stack.top) = opcode-PUSH0; - luaD_stack.top++; - break; - case PUSHBYTE: - ttype(luaD_stack.top) = LUA_T_NUMBER; - nvalue(luaD_stack.top) = *pc++; - luaD_stack.top++; - break; + aux = *pc++; goto pushnumber; case PUSHWORD: + aux = get_word(pc); goto pushnumber; + + case PUSH0: case PUSH1: case PUSH2: + aux -= PUSH0; + pushnumber: ttype(luaD_stack.top) = LUA_T_NUMBER; - nvalue(luaD_stack.top) = get_word(pc); + nvalue(luaD_stack.top) = aux; luaD_stack.top++; break; + case PUSHLOCAL: + aux = *pc++; goto pushlocal; + case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: case PUSHLOCAL9: - *luaD_stack.top++ = - *((luaD_stack.stack+base) + (int)(opcode-PUSHLOCAL0)); + aux -= PUSHLOCAL0; + pushlocal: + *luaD_stack.top++ = *((luaD_stack.stack+base) + aux); break; - case PUSHLOCAL: - *luaD_stack.top++ = *((luaD_stack.stack+base) + (*pc++)); - break; + case GETGLOBAL: + aux = get_word(pc); goto getglobal; - case PUSHGLOBALB: - luaV_getglobal(luaG_findsymbol(tsvalue(&func->consts[*pc++]))); - break; - - case PUSHGLOBAL: - luaV_getglobal(luaG_findsymbol(tsvalue(&func->consts[get_word(pc)]))); + case GETGLOBALB: + aux = *pc++; + getglobal: + luaV_getglobal(luaG_findsymbol(tsvalue(&consts[aux]))); break; case GETTABLE: luaV_gettable(); break; - case PUSHSELF: { + case PUSHSELF: + aux = get_word(pc); goto pushself; + + case PUSHSELFB: + aux = *pc++; + pushself: { TObject receiver = *(luaD_stack.top-1); - *luaD_stack.top++ = func->consts[get_word(pc)]; + *luaD_stack.top++ = consts[aux]; luaV_gettable(); *luaD_stack.top++ = receiver; break; } - case PUSHCONSTANTB: - *luaD_stack.top++ = func->consts[*pc++]; - break; - case PUSHCONSTANT: - *luaD_stack.top++ = func->consts[get_word(pc)]; - break; + aux = get_word(pc); goto pushconstant; - case PUSHUPVALUE0: - *luaD_stack.top++ = cl->consts[1]; + case PUSHCONSTANTB: + aux = *pc++; + pushconstant: + *luaD_stack.top++ = consts[aux]; break; case PUSHUPVALUE: - *luaD_stack.top++ = cl->consts[(*pc++)+1]; + aux = *pc++; goto pushupvalue; + + case PUSHUPVALUE0: + aux = 0; + pushupvalue: + *luaD_stack.top++ = cl->consts[aux+1]; break; + case SETLOCAL: + aux = *pc++; goto setlocal; + case SETLOCAL0: case SETLOCAL1: case SETLOCAL2: case SETLOCAL3: case SETLOCAL4: case SETLOCAL5: case SETLOCAL6: case SETLOCAL7: case SETLOCAL8: case SETLOCAL9: - *((luaD_stack.stack+base) + (int)(opcode-SETLOCAL0)) = - *(--luaD_stack.top); - break; - - case SETLOCAL: - *((luaD_stack.stack+base) + (*pc++)) = *(--luaD_stack.top); break; - - case SETGLOBALB: - luaV_setglobal(luaG_findsymbol(tsvalue(&func->consts[*pc++]))); + aux -= SETLOCAL0; + setlocal: + *((luaD_stack.stack+base) + aux) = *(--luaD_stack.top); break; case SETGLOBAL: - luaV_setglobal(luaG_findsymbol(tsvalue(&func->consts[get_word(pc)]))); + aux = get_word(pc); goto setglobal; + + case SETGLOBALB: + aux = *pc++; + setglobal: + luaV_setglobal(luaG_findsymbol(tsvalue(&consts[aux]))); break; case SETTABLE0: @@ -389,14 +395,17 @@ StkId luaV_execute (Closure *cl, StkId base) luaV_settable(luaD_stack.top-3-(*pc++), 2); break; + case SETLIST: + aux = *(pc++) * LFIELDS_PER_FLUSH; goto setlist; + case SETLIST0: - case SETLIST: { - int m = (opcode == SETLIST0) ? 0 : *(pc++) * LFIELDS_PER_FLUSH; + aux = 0; + setlist: { int n = *(pc++); TObject *arr = luaD_stack.top-n-1; for (; n; n--) { ttype(luaD_stack.top) = LUA_T_NUMBER; - nvalue(luaD_stack.top) = n+m; + nvalue(luaD_stack.top) = n+aux; *(luaH_set (avalue(arr), luaD_stack.top)) = *(luaD_stack.top-1); luaD_stack.top--; } @@ -414,7 +423,12 @@ StkId luaV_execute (Closure *cl, StkId base) } case POPS: - luaD_stack.top -= *(pc++); + aux = *pc++; goto pop; + + case POP1: case POP2: + aux -= (POP1-1); + pop: + luaD_stack.top -= aux; break; case ARGS: @@ -436,7 +450,7 @@ StkId luaV_execute (Closure *cl, StkId base) case EQOP: case NEQOP: { int res = luaO_equalObj(luaD_stack.top-2, luaD_stack.top-1); luaD_stack.top--; - if (opcode == NEQOP) res = !res; + if (aux == NEQOP) res = !res; ttype(luaD_stack.top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; nvalue(luaD_stack.top-1) = 1; break; @@ -578,6 +592,12 @@ StkId luaV_execute (Closure *cl, StkId base) break; case CLOSURE: + aux = get_word(pc); goto closure; + + case CLOSUREB: + aux = *pc++; + closure: + *luaD_stack.top++ = consts[aux]; luaV_closure(); luaC_checkGC(); break; @@ -594,7 +614,7 @@ StkId luaV_execute (Closure *cl, StkId base) case RETCODE: if (lua_callhook) luaD_callHook(base, LUA_T_MARK, 1); - return (base + ((opcode==RETCODE) ? *pc : 0)); + return (base + ((aux==RETCODE) ? *pc : 0)); case SETLINE: { int line = get_word(pc);