From 7c261a13b572fb0f7449f6cdf2b495d0e5bd57d5 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 13 Oct 1997 20:12:04 -0200 Subject: more uniform treatment to opcode variants. --- lua.stx | 208 ++++++++++++++++++++++++++++------------------------------------ 1 file changed, 91 insertions(+), 117 deletions(-) (limited to 'lua.stx') diff --git a/lua.stx b/lua.stx index 28df6f36..fb85d18f 100644 --- a/lua.stx +++ b/lua.stx @@ -1,6 +1,6 @@ %{ /* -** $Id: lua.stx,v 1.7 1997/10/01 20:05:34 roberto Exp roberto $ +** $Id: lua.stx,v 1.8 1997/10/06 14:51:11 roberto Exp roberto $ ** Syntax analizer and code generator ** See Copyright Notice in lua.h */ @@ -23,9 +23,6 @@ /* to avoid warnings generated by yacc */ int luaY_parse (void); -#define malloc luaM_malloc -#define realloc luaM_realloc -#define free luaM_free /* size of a "normal" jump instruction: OpCode + 1 byte */ @@ -118,23 +115,6 @@ static void code_byte (Byte c) } -static void code_word_at (int pc, int n) -{ - 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 code_word (int n) -{ - check_pc(2); - currState->pc += 2; - code_word_at(currState->pc-2, n); -} - - static void deltastack (int delta) { currState->stacksize += delta; @@ -146,41 +126,55 @@ static void deltastack (int delta) } -static void code_opcode (OpCode op, int delta) +static int code_oparg_at (int pc, OpCode op, int builtin, int arg, int delta) { - code_byte(op); deltastack(delta); + if (arg < builtin) { + currState->f->code[pc] = op+1+arg; + return 1; + } + else if (arg <= 255) { + currState->f->code[pc] = op; + currState->f->code[pc+1] = arg; + return 2; + } + else if (arg <= MAX_WORD) { + currState->f->code[pc] = op+1+builtin; + currState->f->code[pc+1] = arg&0xFF; + currState->f->code[pc+2] = arg>>8; + return 3; + } + else luaY_error("construction too big - unable to compile"); + return 0; /* to avoid warnings */ } -static void code_opb (OpCode opbyte, int arg, int delta) +static int fix_opcode (int pc, OpCode op, int builtin, int 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); + if (arg < builtin) { /* close space */ + movecode_down(pc+1, pc+2, currState->pc-(pc+2)); + currState->pc--; + } + else if (arg > 255) { /* open space */ + check_pc(1); + movecode_up(pc+1, pc, currState->pc-pc); + currState->pc++; + } + return code_oparg_at(pc, op, builtin, arg, 0) - 2; } -static void code_opborw (OpCode opbyte, int arg, int delta) +static void code_oparg (OpCode op, int builtin, int arg, int delta) { - if (arg <= 255) - code_opb(opbyte, arg, delta); - else - code_opw(opbyte+1, arg, delta); + check_pc(3); /* maximum code size */ + currState->pc += code_oparg_at(currState->pc, op, builtin, arg, delta); } -static void code_oparg (OpCode firstop, OpCode opbyte, int arg, int delta) +static void code_opcode (OpCode op, int delta) { - if (firstop+arg < opbyte) - code_opcode(firstop+arg, delta); - else - code_opborw(opbyte, arg, delta); + deltastack(delta); + code_byte(op); } @@ -193,7 +187,10 @@ static void code_pop (OpCode op) #define code_binop(op) code_pop(op) -#define code_neutralop(op) code_byte(op) +static void code_neutralop (OpCode op) +{ + code_opcode(op, 0); +} /* unary operations get 1 argument and leave one, so they are neutral */ #define code_unop(op) code_neutralop(op) @@ -201,7 +198,7 @@ static void code_pop (OpCode op) static void code_constant (int c) { - code_oparg(PUSHCONSTANT0, PUSHCONSTANTB, c, 1); + code_oparg(PUSHCONSTANT, 8, c, 1); } @@ -237,7 +234,7 @@ static void code_string (TaggedString *s) } -#define LIM 13 +#define LIM 20 static int real_constant (real r) { /* check whether 'r' has appeared within the last LIM entries */ @@ -261,7 +258,7 @@ static void code_number (real f) { 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 */ + code_oparg(PUSHNUMBER, 3, i, 1); /* f has an (short) integer value */ else code_constant(real_constant(f)); } @@ -270,18 +267,13 @@ static void code_number (real f) static void flush_record (int n) { if (n > 0) - code_opb(SETMAP, n, -2*n); + code_oparg(SETMAP, 1, n-1, -2*n); } static void flush_list (int m, int n) { if (n == 0) return; - if (m == 0) - code_opcode(SETLIST0, -n); - else if (m < 255) - code_opb(SETLIST, m, -n); - else - luaY_error("list constructor too long"); + code_oparg(SETLIST, 1, m, -n); code_byte(n); } @@ -375,7 +367,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); - code_oparg(PUSHUPVALUE0, PUSHUPVALUE, i, 1); + code_oparg(PUSHUPVALUE, 2, i, 1); } @@ -383,7 +375,7 @@ void luaY_codedebugline (int line) { static int lastline = 0; if (lua_debug && line != lastline) { - code_opw(SETLINE, line, 0); + code_oparg(SETLINE, 0, line, 0); lastline = line; } } @@ -392,22 +384,25 @@ void luaY_codedebugline (int line) static void adjuststack (int n) { if (n > 0) - code_oparg(POP1-1, POPS, n, -n); /* POP1-1 = POP0 */ + code_oparg(POP, 2, n-1, -n); else if (n < 0) - code_oparg(PUSHNIL-1, PUSHNILS, -n, -n); /* PUSHNIL1-1 = PUSHNIL0 */ + code_oparg(PUSHNIL, 1, (-n)-1, -n); } -static long adjust_functioncall (long exp, int i) +static long adjust_functioncall (long exp, int nresults) { if (exp <= 0) return -exp; /* exp is -list length */ else { int temp = currState->f->code[exp]; - currState->f->code[exp] = i; - if (i != MULT_RET) - deltastack(i); - return temp+i; + int nparams = currState->f->code[exp-1]; + exp += fix_opcode(exp-2, CALLFUNC, 2, nresults); + currState->f->code[exp] = nparams; + if (nresults != MULT_RET) + deltastack(nresults); + deltastack(-(nparams+1)); + return temp+nresults; } } @@ -430,9 +425,9 @@ static void adjust_mult_assign (int vars, long exps) static void code_args (int dots) { if (!dots) - code_opb(ARGS, currState->nlocalvar, currState->nlocalvar); + code_oparg(ARGS, 0, currState->nlocalvar, currState->nlocalvar); else { - code_opb(VARARGS, currState->nlocalvar, currState->nlocalvar+1); + code_oparg(VARARGS, 0, currState->nlocalvar, currState->nlocalvar+1); add_localvar(luaS_new("arg")); } } @@ -441,9 +436,9 @@ static void code_args (int dots) static void lua_pushvar (vardesc number) { if (number > 0) /* global var */ - code_oparg(GETGLOBAL0, GETGLOBALB, number-1, 1); + code_oparg(GETGLOBAL, 8, number-1, 1); else if (number < 0) /* local var */ - code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1); + code_oparg(PUSHLOCAL, 8, (-number)-1, 1); else code_pop(GETTABLE); } @@ -454,9 +449,9 @@ static void storevar (vardesc number) if (number == 0) /* indexed var */ code_opcode(SETTABLE0, -3); else if (number > 0) /* global var */ - code_opborw(SETGLOBALB, number-1, -1); + code_oparg(SETGLOBAL, 8, number-1, -1); else /* number < 0 - local var */ - code_oparg(SETLOCAL0, SETLOCAL, (-number)-1, -1); + code_oparg(SETLOCAL, 8, (-number)-1, -1); } @@ -469,35 +464,16 @@ static int lua_codestore (int i, int left) return left; } else { /* indexed var with values in between*/ - code_pop(SETTABLE); - code_byte(left+i); /* number of elements between table/index and value */ + code_oparg(SETTABLE, 0, left+i, -1); return left+2; /* table/index are not poped, since they are not on top */ } } -static int fix_opcode (int pc, OpCode op, int n) -{ - if (n <= 255) { - currState->f->code[pc] = op; - currState->f->code[pc+1] = n; - return 0; - } - else { - check_pc(1); /* open space */ - movecode_up(pc+1, pc, currState->pc-pc); - currState->pc++; - currState->f->code[pc] = op+1; /* opcode must be word variant */ - code_word_at(pc+1, n); - return 1; - } -} - - static int fix_jump (int pc, OpCode op, int n) { /* jump is relative to position following jump instruction */ - return fix_opcode(pc, op, n-(pc+JMPSIZE)); + return fix_opcode(pc, op, 0, n-(pc+JMPSIZE)); } @@ -505,7 +481,7 @@ static void fix_upjmp (OpCode op, int pos) { int delta = currState->pc+JMPSIZE - pos; /* jump is relative */ if (delta > 255) delta++; - code_opborw(op, delta, 0); + code_oparg(op, 0, delta, 0); } @@ -517,25 +493,20 @@ static void codeIf (int thenAdd, int elseAdd) elseinit = currState->pc; } else - elseinit += fix_jump(elseAdd, JMPB, currState->pc); - fix_jump(thenAdd, IFFJMPB, elseinit); + elseinit += fix_jump(elseAdd, JMP, currState->pc); + fix_jump(thenAdd, IFFJMP, elseinit); } -static void code_shortcircuit (OpCode op, int pos) +static void code_shortcircuit (int pc, OpCode op) { - int dist = currState->pc - (pos+JMPSIZE); - if (dist > 255) - luaY_error("and/or expression too long"); - currState->f->code[pos] = op; - currState->f->code[pos+1] = dist; + fix_jump(pc, op, currState->pc); } static void codereturn (void) { - code_neutralop(RETCODE); - code_byte(currState->nlocalvar); + code_oparg(RETCODE, 0, currState->nlocalvar, 0); currState->stacksize = currState->nlocalvar; } @@ -549,7 +520,7 @@ static void func_onstack (TProtoFunc *f) currState->f->consts[c].value.tf = (currState+1)->f; for (i=0; iupvalues[i]); - code_opborw(CLOSUREB, c, 1-nupvalues); + code_oparg(CLOSURE, 0, c, 1-nupvalues); } @@ -585,7 +556,6 @@ static void init_func (void) currState->f->lineDefined = luaX_linenumber; } - static TProtoFunc *close_func (void) { TProtoFunc *f = currState->f; @@ -687,13 +657,13 @@ stat : IF cond THEN block SaveWord elsepart END memcpy(&currState->f->code[currState->pc], &currState->f->code[$2], expsize); movecode_down($2, $3, currState->pc-$2); - newpos += fix_jump($2, JMPB, currState->pc-expsize); - fix_upjmp(IFTUPJMPB, newpos); + newpos += fix_jump($2, JMP, currState->pc-expsize); + fix_upjmp(IFTUPJMP, newpos); }} | REPEAT GetPC block UNTIL expr1 { - fix_upjmp(IFFUPJMPB, $2); + fix_upjmp(IFFUPJMP, $2); deltastack(-1); /* pops condition */ } @@ -706,7 +676,7 @@ stat : IF cond THEN block SaveWord elsepart END left = lua_codestore(i, left); adjuststack(left); /* remove eventual 'garbage' left on stack */ }} - | functioncall + | functioncall { adjust_functioncall($1, 0); } | LOCAL localdeclist decinit { currState->nlocalvar += $2; @@ -757,7 +727,11 @@ ret : /* empty */ GetPC : /* empty */ { $$ = currState->pc; } ; -SaveWord : GetPC { $$ = $1; code_word(0); /* open space */ } +SaveWord : /* empty */ + { $$ = currState->pc; + check_pc(JMPSIZE); + currState->pc += JMPSIZE; /* open space */ + } ; SaveWordPop : SaveWord { $$ = $1; deltastack(-1); /* pop condition */ } @@ -787,33 +761,33 @@ expr : '(' expr ')' { $$ = $2; } | expr1 CONC expr1 { code_binop(CONCOP); $$ = 0; } | '-' expr1 %prec UNARY { code_unop(MINUSOP); $$ = 0;} | NOT expr1 { code_unop(NOTOP); $$ = 0;} - | table { $$ = 0; } + | table { $$ = 0; } | varexp { $$ = 0;} | NUMBER { code_number($1); $$ = 0; } | STRING { code_string($1); $$ = 0; } - | NIL {code_opcode(PUSHNIL, 1); $$ = 0; } + | NIL { adjuststack(-1); $$ = 0; } | functioncall { $$ = $1; } - | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } - | expr1 AND SaveWordPop expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; } - | expr1 OR SaveWordPop expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; } + | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } + | expr1 AND SaveWordPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; } + | expr1 OR SaveWordPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; } ; -table : '{' SaveWordPush fieldlist '}' { fix_opcode($2, CREATEARRAYB, $3); } +table : '{' SaveWordPush fieldlist '}' { fix_opcode($2, CREATEARRAY, 2, $3); } ; functioncall : funcvalue funcParams { - code_opcode(CALLFUNC, -($1+$2+1)); /* ajdust counts results */ - code_byte($1+$2); + code_byte(0); /* save space for opcode */ + code_byte($1+$2); /* number of parameters */ $$ = currState->pc; - code_byte(0); /* may be adjusted by other rules */ + code_byte(0); /* must be adjusted by other rules */ } ; funcvalue : varexp { $$ = 0; } | varexp ':' NAME { - code_opborw(PUSHSELFB, string_constant($3, currState), 1); + code_oparg(PUSHSELF, 0, string_constant($3, currState), 1); $$ = 1; } ; -- cgit v1.2.3-55-g6feb