diff --git a/lopcodes.h b/lopcodes.h index b916092d..29392229 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: $ +** $Id: lopcodes.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -36,7 +36,7 @@ PUSHLOCAL8,/* - LOC[8] */ PUSHLOCAL9,/* - LOC[9] */ PUSHLOCAL,/* b - LOC[b] */ PUSHGLOBAL,/* w - VAR[w] */ -PUSHTABLE,/* i t t[i] */ +GETTABLE,/* i t t[i] */ PUSHSELF,/* w t t t[CNST[w]] */ CREATEARRAY,/* w - newarray(size = w) */ diff --git a/lua.stx b/lua.stx index fcd8cb65..4829e9ff 100644 --- a/lua.stx +++ b/lua.stx @@ -1,6 +1,6 @@ %{ /* -** $Id: $ +** $Id: lua.stx,v 1.1 1997/09/16 19:33:21 roberto Exp roberto $ ** Syntax analizer and code generator ** See Copyright Notice in lua.h */ @@ -111,6 +111,27 @@ static void code_opcode (OpCode op, int delta) } +static void code_push (OpCode op) +{ + code_opcode(op, 1); +} + + +static void code_pop (OpCode op) +{ + code_opcode(op, -1); +} + +/* binary operations get 2 arguments and leave one, so they pop one */ +#define code_binop(op) code_pop(op) + + +#define code_neutralop(op) code_byte(op) + +/* unary operations get 1 argument and leave one, so they are neutral */ +#define code_unop(op) code_neutralop(op) + + static void code_word_at (int pc, int n) { Word w = n; @@ -129,11 +150,11 @@ static void code_word (int n) static void code_constant (int c) { if (c <= 255) { - code_opcode(PUSHCONSTANTB, 1); + code_push(PUSHCONSTANTB); code_byte(c); } else { - code_opcode(PUSHCONSTANT, 1); + code_push(PUSHCONSTANT); code_word(c); } } @@ -197,13 +218,13 @@ 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_opcode(PUSH0 + i, 1); + if (i <= 2) code_push(PUSH0 + i); else if (i <= 255) { - code_opcode(PUSHBYTE, 1); + code_push(PUSHBYTE); code_byte(i); } else { - code_opcode(PUSHWORD, 1); + code_push(PUSHWORD); code_word(i); } } @@ -324,9 +345,9 @@ static void pushupvalue (TaggedString *n) luaY_syntaxerror("cannot access an upvalue in current scope", n->str); i = indexupvalue(n); if (i == 0) - code_opcode(PUSHUPVALUE0, 1); + code_push(PUSHUPVALUE0); else { - code_opcode(PUSHUPVALUE, 1); + code_push(PUSHUPVALUE); code_byte(i); } } @@ -336,7 +357,7 @@ void luaY_codedebugline (int line) { static int lastline = 0; if (lua_debug && line != lastline) { - code_opcode(SETLINE, 0); + code_neutralop(SETLINE); code_word(line); lastline = line; } @@ -351,7 +372,7 @@ static void adjuststack (int n) } else if (n < 0) { if (n == -1) - code_opcode(PUSHNIL, 1); + code_push(PUSHNIL); else { code_opcode(PUSHNILS, -n); code_byte(-n); @@ -406,20 +427,20 @@ static void code_args (int dots) static void lua_pushvar (vardesc number) { if (number > 0) { /* global var */ - code_opcode(PUSHGLOBAL, 1); + code_push(PUSHGLOBAL); code_word(number-1); } else if (number < 0) { /* local var */ number = (-number) - 1; if (number < 10) - code_opcode(PUSHLOCAL0 + number, 1); + code_push(PUSHLOCAL0 + number); else { - code_opcode(PUSHLOCAL, 1); + code_push(PUSHLOCAL); code_byte(number); } } else { - code_opcode(PUSHTABLE, -1); + code_pop(GETTABLE); } } @@ -429,15 +450,15 @@ static void storevar (vardesc number) if (number == 0) /* indexed var */ code_opcode(SETTABLE0, -3); else if (number > 0) { /* global var */ - code_opcode(SETGLOBAL, -1); + code_pop(SETGLOBAL); code_word(number-1); } else { /* number < 0 - local var */ number = (-number) - 1; if (number < 10) - code_opcode(SETLOCAL0 + number, -1); + code_pop(SETLOCAL0 + number); else { - code_opcode(SETLOCAL, -1); + code_pop(SETLOCAL); code_byte(number); } } @@ -453,7 +474,7 @@ static int lua_codestore (int i, int left) return left; } else { /* indexed var with values in between*/ - code_opcode(SETTABLE, -1); + code_pop(SETTABLE); code_byte(left+i); /* number of elements between table/index and value */ return left+2; /* table/index are not poped, since they are not on top */ } @@ -485,7 +506,7 @@ static void code_shortcircuit (int pc, Byte jmp) static void codereturn (void) { - code_opcode(RETCODE, 0); + code_neutralop(RETCODE); code_byte(currState->nlocalvar); currState->stacksize = currState->nlocalvar; } @@ -542,7 +563,7 @@ static void init_func (void) static TProtoFunc *close_func (void) { TProtoFunc *f = currState->f; - code_opcode(ENDCODE, 0); + code_neutralop(ENDCODE); f->code[0] = currState->maxstacksize; f->code = luaM_reallocvector(f->code, currState->pc, Byte); f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject); @@ -624,8 +645,7 @@ chunk : statlist ret ; statlist : /* empty */ - | statlist stat sc { if (currState->stacksize != currState->nlocalvar) - { luaY_error("contagem"); exit(1); }} + | statlist stat sc ; sc : /* empty */ | ';' ; @@ -707,7 +727,7 @@ ret : /* empty */ PrepJump : /* empty */ { $$ = currState->pc; - code_opcode(0, 0); /* open space */ + code_byte(0); /* open space */ code_word(0); } ; @@ -718,47 +738,35 @@ PrepJumpPop : PrepJump { $$ = $1; deltastack(-1); /* pop condition */ } expr1 : expr { adjust_functioncall($1, 1); } ; -expr : '(' expr ')' { $$ = $2; } - | expr1 EQ expr1 { code_opcode(EQOP, -1); $$ = 0; } - | expr1 '<' expr1 { code_opcode(LTOP, -1); $$ = 0; } - | expr1 '>' expr1 { code_opcode(GTOP, -1); $$ = 0; } - | expr1 NE expr1 { code_opcode(NEQOP, -1); $$ = 0; } - | expr1 LE expr1 { code_opcode(LEOP, -1); $$ = 0; } - | expr1 GE expr1 { code_opcode(GEOP, -1); $$ = 0; } - | expr1 '+' expr1 { code_opcode(ADDOP, -1); $$ = 0; } - | expr1 '-' expr1 { code_opcode(SUBOP, -1); $$ = 0; } - | expr1 '*' expr1 { code_opcode(MULTOP, -1); $$ = 0; } - | expr1 '/' expr1 { code_opcode(DIVOP, -1); $$ = 0; } - | expr1 '^' expr1 { code_opcode(POWOP, -1); $$ = 0; } - | expr1 CONC expr1 { code_opcode(CONCOP, -1); $$ = 0; } - | '-' expr1 %prec UNARY { code_opcode(MINUSOP, 0); $$ = 0;} +expr : '(' expr ')' { $$ = $2; } + | expr1 EQ expr1 { code_binop(EQOP); $$ = 0; } + | expr1 '<' expr1 { code_binop(LTOP); $$ = 0; } + | expr1 '>' expr1 { code_binop(GTOP); $$ = 0; } + | expr1 NE expr1 { code_binop(NEQOP); $$ = 0; } + | expr1 LE expr1 { code_binop(LEOP); $$ = 0; } + | expr1 GE expr1 { code_binop(GEOP); $$ = 0; } + | expr1 '+' expr1 { code_binop(ADDOP); $$ = 0; } + | expr1 '-' expr1 { code_binop(SUBOP); $$ = 0; } + | expr1 '*' expr1 { code_binop(MULTOP); $$ = 0; } + | expr1 '/' expr1 { code_binop(DIVOP); $$ = 0; } + | expr1 '^' expr1 { code_binop(POWOP); $$ = 0; } + | expr1 CONC expr1 { code_binop(CONCOP); $$ = 0; } + | '-' expr1 %prec UNARY { code_unop(MINUSOP); $$ = 0;} + | NOT expr1 { code_unop(NOTOP); $$ = 0;} | table { $$ = 0; } - | varexp { $$ = 0;} - | NUMBER { code_number($1); $$ = 0; } - | STRING - { - code_string($1); - $$ = 0; - } - | NIL {code_opcode(PUSHNIL, 1); $$ = 0; } - | functioncall { $$ = $1; } - | NOT expr1 { code_opcode(NOTOP, 0); $$ = 0;} - | expr1 AND PrepJumpPop expr1 - { - code_shortcircuit($3, ONFJMP); - $$ = 0; - } - | expr1 OR PrepJumpPop expr1 - { - code_shortcircuit($3, ONTJMP); - $$ = 0; - } + | varexp { $$ = 0;} + | NUMBER { code_number($1); $$ = 0; } + | STRING { code_string($1); $$ = 0; } + | NIL {code_push(PUSHNIL); $$ = 0; } + | functioncall { $$ = $1; } + | expr1 AND PrepJumpPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; } + | expr1 OR PrepJumpPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; } | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } ; table : { - code_opcode(CREATEARRAY, 1); + code_push(CREATEARRAY); $$ = currState->pc; code_word(0); } '{' fieldlist '}' @@ -779,7 +787,7 @@ functioncall : funcvalue funcParams funcvalue : varexp { $$ = 0; } | varexp ':' NAME { - code_opcode(PUSHSELF, 1); + code_push(PUSHSELF); code_word(string_constant($3)); $$ = 1; } diff --git a/lvm.c b/lvm.c index 8993056b..b4818ea9 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: $ +** $Id: lvm.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -22,7 +22,9 @@ #include "lvm.h" -#define get_word(w,pc) {w=*pc+(*(pc+1)<<8); pc+=2;} +#define get_prevword(pc) (*(pc-2)+(*(pc-1)<<8)) +#define get_word(pc) (pc+=2, get_prevword(pc)) +#define skip_word(pc) {pc+=2;} /* Extra stack to run a function: LUA_T_LINE(1), TM calls(2), ... */ @@ -159,15 +161,13 @@ void luaV_getglobal (Word n) TObject *value = &luaG_global[n].object; TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL); if (ttype(im) == LUA_T_NIL) { /* default behavior */ - *luaD_stack.top = *value; - luaD_stack.top++; + *luaD_stack.top++ = *value; } else { ttype(luaD_stack.top) = LUA_T_STRING; tsvalue(luaD_stack.top) = luaG_global[n].varname; luaD_stack.top++; - *luaD_stack.top = *value; - luaD_stack.top++; + *luaD_stack.top++ = *value; luaD_callTM(im, 2, 1); } } @@ -184,10 +184,8 @@ void luaV_setglobal (Word n) TObject newvalue = *(luaD_stack.top-1); ttype(luaD_stack.top-1) = LUA_T_STRING; tsvalue(luaD_stack.top-1) = luaG_global[n].varname; - *luaD_stack.top = *oldvalue; - luaD_stack.top++; - *luaD_stack.top = newvalue; - luaD_stack.top++; + *luaD_stack.top++ = *oldvalue; + *luaD_stack.top++ = newvalue; luaD_callTM(im, 3, 0); } } @@ -266,8 +264,7 @@ static void adjust_varargs (StkId first_extra_arg) luaV_pack(first_extra_arg, (luaD_stack.top-luaD_stack.stack)-first_extra_arg, &arg); luaD_adjusttop(first_extra_arg); - *luaD_stack.top = arg; - luaD_stack.top++; + *luaD_stack.top++ = arg; } @@ -289,8 +286,7 @@ StkId luaV_execute (Closure *cl, StkId base) switch (opcode = (OpCode)*pc++) { case PUSHNIL: - ttype(luaD_stack.top) = LUA_T_NIL; - luaD_stack.top++; + ttype(luaD_stack.top++) = LUA_T_NIL; break; case PUSHNILS: { @@ -312,72 +308,55 @@ StkId luaV_execute (Closure *cl, StkId base) luaD_stack.top++; break; - case PUSHWORD: { - Word w; - get_word(w,pc); + case PUSHWORD: ttype(luaD_stack.top) = LUA_T_NUMBER; - nvalue(luaD_stack.top) = w; + nvalue(luaD_stack.top) = get_word(pc); luaD_stack.top++; break; - } 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)); - luaD_stack.top++; + *luaD_stack.top++ = + *((luaD_stack.stack+base) + (int)(opcode-PUSHLOCAL0)); break; case PUSHLOCAL: - *luaD_stack.top = *((luaD_stack.stack+base) + (*pc++)); - luaD_stack.top++; + *luaD_stack.top++ = *((luaD_stack.stack+base) + (*pc++)); break; - case PUSHGLOBAL: { - Word w; - get_word(w,pc); - luaV_getglobal(w); + case PUSHGLOBAL: + luaV_getglobal(get_word(pc)); break; - } - case PUSHTABLE: + case GETTABLE: luaV_gettable(); break; case PUSHSELF: { TObject receiver = *(luaD_stack.top-1); - Word w; - get_word(w,pc); - *luaD_stack.top = func->consts[w]; - luaD_stack.top++; + *luaD_stack.top++ = func->consts[get_word(pc)]; luaV_gettable(); - *luaD_stack.top = receiver; - luaD_stack.top++; + *luaD_stack.top++ = receiver; break; } - case PUSHCONSTANTB: { - *luaD_stack.top = func->consts[*pc++]; - luaD_stack.top++; + case PUSHCONSTANTB: + *luaD_stack.top++ = func->consts[*pc++]; break; - } - case PUSHCONSTANT: { - Word w; - get_word(w,pc); - *luaD_stack.top = func->consts[w]; - luaD_stack.top++; + case PUSHCONSTANT: + *luaD_stack.top++ = func->consts[get_word(pc)]; break; - } case PUSHUPVALUE0: - case PUSHUPVALUE: { - int i = (opcode == PUSHUPVALUE0) ? 0 : *pc++; - *luaD_stack.top = cl->consts[i+1]; - luaD_stack.top++; + *luaD_stack.top++ = cl->consts[1]; + break; + + case PUSHUPVALUE: + *luaD_stack.top++ = cl->consts[(*pc++)+1]; break; - } case SETLOCAL0: case SETLOCAL1: case SETLOCAL2: case SETLOCAL3: case SETLOCAL4: case SETLOCAL5: @@ -390,36 +369,28 @@ StkId luaV_execute (Closure *cl, StkId base) case SETLOCAL: *((luaD_stack.stack+base) + (*pc++)) = *(--luaD_stack.top); break; - case SETGLOBAL: { - Word w; - get_word(w,pc); - luaV_setglobal(w); + case SETGLOBAL: + luaV_setglobal(get_word(pc)); break; - } case SETTABLE0: luaV_settable(luaD_stack.top-3, 1); break; - case SETTABLE: { - int n = *pc++; - luaV_settable(luaD_stack.top-3-n, 2); + case SETTABLE: + luaV_settable(luaD_stack.top-3-(*pc++), 2); break; - } case SETLIST0: case SETLIST: { - int m, n; - TObject *arr; - if (opcode == SETLIST0) m = 0; - else m = *(pc++) * LFIELDS_PER_FLUSH; - n = *(pc++); - arr = luaD_stack.top-n-1; - while (n) { - ttype(luaD_stack.top) = LUA_T_NUMBER; nvalue(luaD_stack.top) = n+m; + int m = (opcode == SETLIST0) ? 0 : *(pc++) * LFIELDS_PER_FLUSH; + 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; *(luaH_set (avalue(arr), luaD_stack.top)) = *(luaD_stack.top-1); luaD_stack.top--; - n--; } break; } @@ -447,19 +418,16 @@ StkId luaV_execute (Closure *cl, StkId base) adjust_varargs(base + *(pc++)); break; - case CREATEARRAY: { - Word size; + case CREATEARRAY: luaC_checkGC(); - get_word(size,pc); - avalue(luaD_stack.top) = luaH_new(size); + avalue(luaD_stack.top) = luaH_new(get_word(pc)); ttype(luaD_stack.top) = LUA_T_ARRAY; luaD_stack.top++; break; - } case EQOP: case NEQOP: { int res = luaO_equalObj(luaD_stack.top-2, luaD_stack.top-1); - --luaD_stack.top; + luaD_stack.top--; if (opcode == NEQOP) res = !res; ttype(luaD_stack.top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; nvalue(luaD_stack.top-1) = 1; @@ -563,51 +531,43 @@ StkId luaV_execute (Closure *cl, StkId base) nvalue(luaD_stack.top-1) = 1; break; - case ONTJMP: { - Word w; - get_word(w,pc); - if (ttype(luaD_stack.top-1) != LUA_T_NIL) pc += w; - else luaD_stack.top--; - } - break; - - case ONFJMP: { - Word w; - get_word(w,pc); - if (ttype(luaD_stack.top-1) == LUA_T_NIL) pc += w; - else luaD_stack.top--; + case ONTJMP: + skip_word(pc); + if (ttype(luaD_stack.top-1) != LUA_T_NIL) + pc += get_prevword(pc); + else + luaD_stack.top--; break; - } - case JMP: { - Word w; - get_word(w,pc); - pc += w; + case ONFJMP: + skip_word(pc); + if (ttype(luaD_stack.top-1) == LUA_T_NIL) + pc += get_prevword(pc); + else + luaD_stack.top--; break; - } - case UPJMP: { - Word w; - get_word(w,pc); - pc -= w; + case JMP: + skip_word(pc); + pc += get_prevword(pc); break; - } - case IFFJMP: { - Word w; - get_word(w,pc); - luaD_stack.top--; - if (ttype(luaD_stack.top) == LUA_T_NIL) pc += w; + case UPJMP: + skip_word(pc); + pc -= get_prevword(pc); break; - } - case IFFUPJMP: { - Word w; - get_word(w,pc); - luaD_stack.top--; - if (ttype(luaD_stack.top) == LUA_T_NIL) pc -= w; + case IFFJMP: + skip_word(pc); + if (ttype(--luaD_stack.top) == LUA_T_NIL) + pc += get_prevword(pc); + break; + + case IFFUPJMP: + skip_word(pc); + if (ttype(--luaD_stack.top) == LUA_T_NIL) + pc -= get_prevword(pc); break; - } case CLOSURE: luaV_closure(); @@ -615,10 +575,8 @@ StkId luaV_execute (Closure *cl, StkId base) break; case CALLFUNC: { - int nParams = *pc++; - int nResults = *pc++; - StkId newBase = (luaD_stack.top-luaD_stack.stack)-nParams; - luaD_call(newBase, nResults); + StkId newBase = (luaD_stack.top-luaD_stack.stack)-(*pc++); + luaD_call(newBase, *pc++); break; } @@ -631,8 +589,7 @@ StkId luaV_execute (Closure *cl, StkId base) return (base + ((opcode==RETCODE) ? *pc : 0)); case SETLINE: { - Word line; - get_word(line,pc); + int line = get_word(pc); if ((luaD_stack.stack+base-1)->ttype != LUA_T_LINE) { /* open space for LINE value */ luaD_openstack((luaD_stack.top-luaD_stack.stack)-base);