From 0dd6d1080e7f58eb17cb8a2ad3fc5801ed7c0532 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 24 Sep 1997 16:43:11 -0300 Subject: [PATCH] new opcode variants. --- lopcodes.h | 30 ++++++++++++-- lua.stx | 114 +++++++++++++++++++++++++++++------------------------ lvm.c | 85 +++++++++++++++++++++++++-------------- 3 files changed, 145 insertions(+), 84 deletions(-) diff --git a/lopcodes.h b/lopcodes.h index 7ba79e25..e1b95122 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.4 1997/09/22 20:53:20 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -29,10 +29,21 @@ PUSH2,/* - 2.0 */ PUSHBYTE,/* b - (float)b */ PUSHWORD,/* w - (float)w */ +PUSHCONSTANT0,/* - CNST[0] */ +PUSHCONSTANT1,/* - CNST[1] */ +PUSHCONSTANT2,/* - CNST[2] */ +PUSHCONSTANT3,/* - CNST[3] */ +PUSHCONSTANT4,/* - CNST[4] */ +PUSHCONSTANT5,/* - CNST[5] */ +PUSHCONSTANT6,/* - CNST[6] */ +PUSHCONSTANT7,/* - CNST[7] */ +PUSHCONSTANT8,/* - CNST[8] */ +PUSHCONSTANT9,/* - CNST[9] */ PUSHCONSTANTB,/*b - CNST[b] */ PUSHCONSTANT,/* w - CNST[w] */ PUSHUPVALUE0, +PUSHUPVALUE1, PUSHUPVALUE,/* b - Closure[b] */ PUSHLOCAL0,/* - LOC[0] */ @@ -47,6 +58,16 @@ PUSHLOCAL8,/* - LOC[8] */ PUSHLOCAL9,/* - LOC[9] */ PUSHLOCAL,/* b - LOC[b] */ +GETGLOBAL0,/* - VAR[CNST[0]] */ +GETGLOBAL1,/* - VAR[CNST[1]] */ +GETGLOBAL2,/* - VAR[CNST[2]] */ +GETGLOBAL3,/* - VAR[CNST[3]] */ +GETGLOBAL4,/* - VAR[CNST[4]] */ +GETGLOBAL5,/* - VAR[CNST[5]] */ +GETGLOBAL6,/* - VAR[CNST[6]] */ +GETGLOBAL7,/* - VAR[CNST[7]] */ +GETGLOBAL8,/* - VAR[CNST[8]] */ +GETGLOBAL9,/* - VAR[CNST[9]] */ GETGLOBALB,/* b - VAR[CNST[b]] */ GETGLOBAL,/* w - VAR[CNST[w]] */ @@ -94,11 +115,14 @@ CONCOP,/* y x x..y */ MINUSOP,/* x -x */ NOTOP,/* x (x==nil)? 1 : nil */ -ONTJMP,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */ -ONFJMP,/* w x (x==nil)? x : - (x==nil)? PC+=w */ +/* NOTICE: all jumps are relative to the position following the opcode */ +ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */ +ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */ JMP,/* w - - PC+=w */ +UPJMPB,/* b - - PC-=b */ UPJMP,/* w - - PC-=w */ IFFJMP,/* w x - (x==nil)? PC+=w */ +IFFUPJMPB,/* b x - (x==nil)? PC-=b */ IFFUPJMP,/* w x - (x==nil)? PC-=w */ CLOSUREB,/* b v_1...v_n c(CNST[b]) */ diff --git a/lua.stx b/lua.stx index c7d90e20..dfb80ce3 100644 --- a/lua.stx +++ b/lua.stx @@ -1,6 +1,6 @@ %{ /* -** $Id: lua.stx,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $ +** $Id: lua.stx,v 1.4 1997/09/22 20:53:20 roberto Exp roberto $ ** Syntax analizer and code generator ** See Copyright Notice in lua.h */ @@ -96,15 +96,24 @@ 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"); + if (n > MAX_WORD) + luaY_error("construction too big; unable to compile"); currState->f->code[pc] = n&0xFF; currState->f->code[pc+1] = n>>8; } + +static void fix_jump (int pc, OpCode op, int n) +{ + currState->f->code[pc] = op; + code_word_at(pc+1, n); +} + + static void code_word (int n) { + if (n > MAX_WORD) + luaY_error("construction too big; unable to compile"); code_byte(n&0xFF); code_byte(n>>8); } @@ -128,16 +137,25 @@ static void code_opcode (OpCode op, int delta) } -static void code_opborw(OpCode opbyte, int arg, int delta) +static void code_opb (OpCode opbyte, int arg, int delta) { - if (arg <= 255) { - code_opcode(opbyte, delta); - code_byte(arg); - } - else { - code_opcode(opbyte+1, delta); - code_word(arg); - } + code_opcode(opbyte, delta); + code_byte(arg); +} + +static void code_opw (OpCode opbyte, int arg, int delta) +{ + code_opcode(opbyte, delta); + code_word(arg); +} + + +static void code_opborw (OpCode opbyte, int arg, int delta) +{ + if (arg <= 255) + code_opb(opbyte, arg, delta); + else + code_opw(opbyte+1, arg, delta); } @@ -167,7 +185,7 @@ static void code_pop (OpCode op) static void code_constant (int c) { - code_opborw(PUSHCONSTANTB, c, 1); + code_oparg(PUSHCONSTANT0, PUSHCONSTANTB, c, 1); } @@ -235,9 +253,8 @@ static void code_number (real f) static void flush_record (int n) { - if (n == 0) return; - code_opcode(SETMAP, -2*n); - code_byte(n); + if (n > 0) + code_opb(SETMAP, n, -2*n); } static void flush_list (int m, int n) @@ -245,10 +262,8 @@ static void flush_list (int m, int n) if (n == 0) return; if (m == 0) code_opcode(SETLIST0, -n); - else if (m < 255) { - code_opcode(SETLIST, -n); - code_byte(m); - } + else if (m < 255) + code_opb(SETLIST, m, -n); else luaY_error("list constructor too long"); code_byte(n); @@ -352,8 +367,7 @@ void luaY_codedebugline (int line) { static int lastline = 0; if (lua_debug && line != lastline) { - code_neutralop(SETLINE); - code_word(line); + code_opw(SETLINE, line, 0); lastline = line; } } @@ -399,13 +413,10 @@ static void adjust_mult_assign (int vars, long exps) static void code_args (int dots) { - if (!dots) { - code_opcode(ARGS, currState->nlocalvar); - code_byte(currState->nlocalvar); - } + if (!dots) + code_opb(ARGS, currState->nlocalvar, currState->nlocalvar); else { - code_opcode(VARARGS, currState->nlocalvar+1); - code_byte(currState->nlocalvar); + code_opb(VARARGS, currState->nlocalvar, currState->nlocalvar+1); add_localvar(luaS_new("arg")); } } @@ -414,7 +425,7 @@ static void code_args (int dots) static void lua_pushvar (vardesc number) { if (number > 0) /* global var */ - code_opborw(GETGLOBALB, number-1, 1); + code_oparg(GETGLOBAL0, GETGLOBALB, number-1, 1); else if (number < 0) /* local var */ code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1); else @@ -456,19 +467,19 @@ static void codeIf (int thenAdd, int elseAdd) currState->pc -= sizeof(Word)+1; elseinit = currState->pc; } - else { - currState->f->code[elseAdd] = JMP; - code_word_at(elseAdd+1, currState->pc-elseinit); - } - currState->f->code[thenAdd] = IFFJMP; - code_word_at(thenAdd+1, elseinit-(thenAdd+sizeof(Word)+1)); + else + fix_jump(elseAdd, JMP, currState->pc-(elseAdd+1)); + fix_jump(thenAdd, IFFJMP, elseinit-(thenAdd+1)); } -static void code_shortcircuit (int pc, Byte jmp) +static void code_shortcircuit (OpCode op, int pos) { - currState->f->code[pc] = jmp; - code_word_at(pc+1, currState->pc - (pc + sizeof(Word)+1)); + int dist = currState->pc - (pos+1); + if (dist > 255) + luaY_error("and/or expression too long"); + currState->f->code[pos] = op; + currState->f->code[pos+1] = dist; } @@ -582,7 +593,7 @@ TProtoFunc *luaY_parser (ZIO *z, char *chunkname) %token NUMBER %token NAME STRING -%type PrepJump, PrepJumpPop +%type PrepJump, PrepJumpPop, PrepJumpSC %type exprlist, exprlist1 /* if > 0, points to function return counter (which has list length); if <= 0, -list lenght */ %type functioncall, expr /* if != 0, points to function return @@ -620,18 +631,15 @@ sc : /* empty */ | ';' ; stat : IF expr1 THEN PrepJumpPop block PrepJump elsepart END { codeIf($4, $6); } - | WHILE {$$=currState->pc;} expr1 DO PrepJumpPop block PrepJump END + | WHILE {$$=currState->pc;} expr1 DO PrepJumpPop block END { - currState->f->code[$5] = IFFJMP; - code_word_at($5+1, currState->pc - ($5+sizeof(Word)+1)); - currState->f->code[$7] = UPJMP; - code_word_at($7+1, currState->pc - ($2)); + code_opborw(UPJMPB, currState->pc+1 - ($2), 0); + fix_jump($5, IFFJMP, currState->pc - ($5+1)); } - | REPEAT {$$=currState->pc;} block UNTIL expr1 PrepJumpPop + | REPEAT {$$=currState->pc;} block UNTIL expr1 { - currState->f->code[$6] = IFFUPJMP; - code_word_at($6+1, currState->pc - ($2)); + code_opborw(IFFUPJMPB, currState->pc+1 - ($2), -1); } | varlist1 '=' exprlist1 @@ -699,6 +707,10 @@ PrepJump : /* empty */ } ; +PrepJumpSC : /* empty */ + { $$ = currState->pc; code_opcode(0, -1); code_byte(0); } + ; + PrepJumpPop : PrepJump { $$ = $1; deltastack(-1); /* pop condition */ } ; @@ -726,13 +738,13 @@ expr : '(' expr ')' { $$ = $2; } | STRING { code_string($1); $$ = 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; } | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } + | expr1 AND PrepJumpSC expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; } + | expr1 OR PrepJumpSC expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; } ; table : - { code_opcode(CREATEARRAY, 1); $$ = currState->pc; code_word(0); } + { $$ = currState->pc+1; code_opw(CREATEARRAY, 0, 1); } '{' fieldlist '}' { code_word_at($1, $3); } ; diff --git a/lvm.c b/lvm.c index 90237f14..5b7971c6 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $ +** $Id: lvm.c,v 1.4 1997/09/22 20:53:20 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -22,9 +22,9 @@ #include "lvm.h" -#define get_prevword(pc) (*(pc-2)+(*(pc-1)<<8)) -#define get_word(pc) (pc+=2, get_prevword(pc)) -#define skip_word(pc) {pc+=2;} +#define skip_word(pc) (pc+=2) +#define get_word(pc) (*(pc)+(*((pc)+1)<<8)) +#define next_word(pc) (pc+=2, get_word(pc-2)) /* Extra stack to run a function: LUA_T_LINE(1), TM calls(2), ... */ @@ -300,7 +300,7 @@ StkId luaV_execute (Closure *cl, StkId base) aux = *pc++; goto pushnumber; case PUSHWORD: - aux = get_word(pc); goto pushnumber; + aux = next_word(pc); goto pushnumber; case PUSH0: case PUSH1: case PUSH2: aux -= PUSH0; @@ -323,10 +323,16 @@ StkId luaV_execute (Closure *cl, StkId base) break; case GETGLOBAL: - aux = get_word(pc); goto getglobal; + aux = next_word(pc); goto getglobal; case GETGLOBALB: - aux = *pc++; + aux = *pc++; goto getglobal; + + case GETGLOBAL0: case GETGLOBAL1: case GETGLOBAL2: + case GETGLOBAL3: case GETGLOBAL4: case GETGLOBAL5: + case GETGLOBAL6: case GETGLOBAL7: case GETGLOBAL8: + case GETGLOBAL9: + aux -= GETGLOBAL0; getglobal: luaV_getglobal(luaG_findsymbol(tsvalue(&consts[aux]))); break; @@ -336,7 +342,7 @@ StkId luaV_execute (Closure *cl, StkId base) break; case PUSHSELF: - aux = get_word(pc); goto pushself; + aux = next_word(pc); goto pushself; case PUSHSELFB: aux = *pc++; @@ -349,10 +355,16 @@ StkId luaV_execute (Closure *cl, StkId base) } case PUSHCONSTANT: - aux = get_word(pc); goto pushconstant; + aux = next_word(pc); goto pushconstant; case PUSHCONSTANTB: - aux = *pc++; + aux = *pc++; goto pushconstant; + + case PUSHCONSTANT0: case PUSHCONSTANT1: case PUSHCONSTANT2: + case PUSHCONSTANT3: case PUSHCONSTANT4: case PUSHCONSTANT5: + case PUSHCONSTANT6: case PUSHCONSTANT7: case PUSHCONSTANT8: + case PUSHCONSTANT9: + aux -= PUSHCONSTANT0; pushconstant: *luaD_stack.top++ = consts[aux]; break; @@ -360,8 +372,8 @@ StkId luaV_execute (Closure *cl, StkId base) case PUSHUPVALUE: aux = *pc++; goto pushupvalue; - case PUSHUPVALUE0: - aux = 0; + case PUSHUPVALUE0: case PUSHUPVALUE1: + aux -= PUSHUPVALUE0; pushupvalue: *luaD_stack.top++ = cl->consts[aux+1]; break; @@ -379,7 +391,7 @@ StkId luaV_execute (Closure *cl, StkId base) break; case SETGLOBAL: - aux = get_word(pc); goto setglobal; + aux = next_word(pc); goto setglobal; case SETGLOBALB: aux = *pc++; @@ -442,7 +454,7 @@ StkId luaV_execute (Closure *cl, StkId base) case CREATEARRAY: luaC_checkGC(); - avalue(luaD_stack.top) = luaH_new(get_word(pc)); + avalue(luaD_stack.top) = luaH_new(next_word(pc)); ttype(luaD_stack.top) = LUA_T_ARRAY; luaD_stack.top++; break; @@ -554,45 +566,58 @@ StkId luaV_execute (Closure *cl, StkId base) break; case ONTJMP: - skip_word(pc); if (ttype(luaD_stack.top-1) != LUA_T_NIL) - pc += get_prevword(pc); - else + pc += *pc; + else { + pc++; luaD_stack.top--; + } break; case ONFJMP: - skip_word(pc); if (ttype(luaD_stack.top-1) == LUA_T_NIL) - pc += get_prevword(pc); - else + pc += *pc; + else { + pc++; luaD_stack.top--; + } break; case JMP: - skip_word(pc); - pc += get_prevword(pc); + pc += get_word(pc); + break; + + case UPJMPB: + pc -= *pc; break; case UPJMP: - skip_word(pc); - pc -= get_prevword(pc); + pc -= get_word(pc); break; case IFFJMP: - skip_word(pc); if (ttype(--luaD_stack.top) == LUA_T_NIL) - pc += get_prevword(pc); + pc += get_word(pc); + else + skip_word(pc); + break; + + case IFFUPJMPB: + if (ttype(--luaD_stack.top) == LUA_T_NIL) + pc -= *pc; + else + pc++; break; case IFFUPJMP: - skip_word(pc); if (ttype(--luaD_stack.top) == LUA_T_NIL) - pc -= get_prevword(pc); + pc -= get_word(pc); + else + skip_word(pc); break; case CLOSURE: - aux = get_word(pc); goto closure; + aux = next_word(pc); goto closure; case CLOSUREB: aux = *pc++; @@ -617,7 +642,7 @@ StkId luaV_execute (Closure *cl, StkId base) return (base + ((aux==RETCODE) ? *pc : 0)); case SETLINE: { - int line = get_word(pc); + int line = next_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);