From 2c8e28d75a09fb6de3c3b16a64561a0103866cea Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 17 Mar 2000 10:09:46 -0300 Subject: small changes --- lcode.c | 182 ++++++++++++++++++++++++++++++++++------------------------------ lcode.h | 12 ++--- 2 files changed, 101 insertions(+), 93 deletions(-) diff --git a/lcode.c b/lcode.c index b04632e8..26a606ef 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.12 2000/03/15 20:50:33 roberto Exp roberto $ +** $Id: lcode.c,v 1.13 2000/03/16 18:03:09 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -22,130 +22,147 @@ void luaK_error (LexState *ls, const char *msg) { } +int luaK_code (FuncState *fs, Instruction i, int delta) { + luaK_deltastack(fs, delta); + luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT); + fs->f->code[fs->pc] = i; + return fs->pc++; +} + +int luaK_0(FuncState *fs, OpCode o, int d) { + return luaK_code(fs, CREATE_0(o), d); +} + +int luaK_U(FuncState *fs, OpCode o, int u, int d) { + return luaK_code(fs, CREATE_U(o,u), d); +} + +int luaK_S(FuncState *fs, OpCode o, int s, int d) { + return luaK_code(fs, CREATE_S(o,s), d); +} + +int luaK_AB(FuncState *fs, OpCode o, int a, int b, int d) { + return luaK_code(fs, CREATE_AB(o,a,b), d); +} + + /* -** Returns the address of the previous instruction, for optimizations. +** Returns the the previous instruction, for optimizations. ** If there is a jump target between this and the current instruction, -** returns the address of a dummy instruction to avoid wrong optimizations. +** returns a dummy instruction to avoid wrong optimizations. */ -static Instruction *previous_instruction (FuncState *fs) { +static Instruction previous_instruction (FuncState *fs) { if (fs->pc > fs->lasttarget) /* no jumps to current position? */ - return &fs->f->code[fs->pc-1]; /* returns previous instruction */ - else { - static Instruction dummy = CREATE_0(OP_END); - return &dummy; /* no optimizations after an `END' */ - } + return fs->f->code[fs->pc-1]; /* returns previous instruction */ + else + return CREATE_0(OP_END); /* no optimizations after an `END' */ } -static int luaK_primitivecode (FuncState *fs, Instruction i) { - luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT); - fs->f->code[fs->pc] = i; - return fs->pc++; +static Instruction prepare (FuncState *fs, Instruction i, int delta) { + Instruction previous = previous_instruction(fs); + luaK_code(fs, i, delta); + return previous; +} + + +static void setprevious (FuncState *fs, Instruction i) { + fs->pc--; /* remove last instruction */ + fs->f->code[fs->pc-1] = i; /* change previous instruction */ } static void luaK_minus (FuncState *fs) { - Instruction *previous = previous_instruction(fs); - switch(GET_OPCODE(*previous)) { - case OP_PUSHINT: SETARG_S(*previous, -GETARG_S(*previous)); return; - case OP_PUSHNUM: SET_OPCODE(*previous, OP_PUSHNEGNUM); return; - case OP_PUSHNEGNUM: SET_OPCODE(*previous, OP_PUSHNUM); return; - default: luaK_primitivecode(fs, CREATE_0(OP_MINUS)); + Instruction previous = prepare(fs, CREATE_0(OP_MINUS), 0); + switch(GET_OPCODE(previous)) { + case OP_PUSHINT: SETARG_S(previous, -GETARG_S(previous)); break; + case OP_PUSHNUM: SET_OPCODE(previous, OP_PUSHNEGNUM); break; + case OP_PUSHNEGNUM: SET_OPCODE(previous, OP_PUSHNUM); break; + default: return; } + setprevious(fs, previous); } static void luaK_gettable (FuncState *fs) { - Instruction *previous = previous_instruction(fs); - luaK_deltastack(fs, -1); - switch(GET_OPCODE(*previous)) { - case OP_PUSHSTRING: SET_OPCODE(*previous, OP_GETDOTTED); break; - default: luaK_primitivecode(fs, CREATE_0(OP_GETTABLE)); + Instruction previous = prepare(fs, CREATE_0(OP_GETTABLE), -1); + switch(GET_OPCODE(previous)) { + case OP_PUSHSTRING: SET_OPCODE(previous, OP_GETDOTTED); break; + default: return; } + setprevious(fs, previous); } static void luaK_add (FuncState *fs) { - Instruction *previous = previous_instruction(fs); - luaK_deltastack(fs, -1); - switch(GET_OPCODE(*previous)) { - case OP_PUSHINT: SET_OPCODE(*previous, OP_ADDI); break; - default: luaK_primitivecode(fs, CREATE_0(OP_ADD)); + Instruction previous = prepare(fs, CREATE_0(OP_ADD), -1); + switch(GET_OPCODE(previous)) { + case OP_PUSHINT: SET_OPCODE(previous, OP_ADDI); break; + default: return; } + setprevious(fs, previous); } static void luaK_sub (FuncState *fs) { - Instruction *previous = previous_instruction(fs); - luaK_deltastack(fs, -1); - switch(GET_OPCODE(*previous)) { + Instruction previous = prepare(fs, CREATE_0(OP_SUB), -1); + switch(GET_OPCODE(previous)) { case OP_PUSHINT: - SET_OPCODE(*previous, OP_ADDI); - SETARG_S(*previous, -GETARG_S(*previous)); + SET_OPCODE(previous, OP_ADDI); + SETARG_S(previous, -GETARG_S(previous)); break; - default: luaK_primitivecode(fs, CREATE_0(OP_SUB)); + default: return; } + setprevious(fs, previous); } static void luaK_conc (FuncState *fs) { - Instruction *previous = previous_instruction(fs); - luaK_deltastack(fs, -1); - switch(GET_OPCODE(*previous)) { - case OP_CONC: SETARG_U(*previous, GETARG_U(*previous)+1); break; - default: luaK_primitivecode(fs, CREATE_U(OP_CONC, 2)); + Instruction previous = prepare(fs, CREATE_U(OP_CONC, 2), -1); + switch(GET_OPCODE(previous)) { + case OP_CONC: SETARG_U(previous, GETARG_U(previous)+1); break; + default: return; } + setprevious(fs, previous); } static void luaK_eq (FuncState *fs) { - Instruction *previous = previous_instruction(fs); - if (*previous == CREATE_U(OP_PUSHNIL, 1)) { - *previous = CREATE_0(OP_NOT); - luaK_deltastack(fs, -1); /* undo effect of PUSHNIL */ + Instruction previous = prepare(fs, CREATE_S(OP_IFEQJMP, 0), -2); + if (previous == CREATE_U(OP_PUSHNIL, 1)) { + setprevious(fs, CREATE_0(OP_NOT)); + luaK_deltastack(fs, 1); /* undo delta from `prepare' */ } - else - luaK_S(fs, OP_IFEQJMP, 0, -2); } static void luaK_neq (FuncState *fs) { - Instruction *previous = previous_instruction(fs); - if (*previous == CREATE_U(OP_PUSHNIL, 1)) { - fs->pc--; /* remove PUSHNIL */ - luaK_deltastack(fs, -1); /* undo effect of PUSHNIL */ - luaK_getlabel(fs); /* previous instruction could be a (closed) call */ + Instruction previous = prepare(fs, CREATE_S(OP_IFNEQJMP, 0), -2); + if (previous == CREATE_U(OP_PUSHNIL, 1)) { + fs->pc -= 2; /* remove PUSHNIL and IFNEQJMP */ + luaK_deltastack(fs, 1); /* undo delta from `prepare' */ } - else - luaK_S(fs, OP_IFNEQJMP, 0, -2); } void luaK_retcode (FuncState *fs, int nlocals, int nexps) { - Instruction *previous = previous_instruction(fs); - if (nexps > 0 && GET_OPCODE(*previous) == OP_CALL) { - LUA_ASSERT(fs->L, GETARG_B(*previous) == MULT_RET, "call should be open"); - SET_OPCODE(*previous, OP_TAILCALL); - SETARG_B(*previous, nlocals); + Instruction previous = prepare(fs, CREATE_U(OP_RETURN, nlocals), 0); + if (nexps > 0 && GET_OPCODE(previous) == OP_CALL) { + LUA_ASSERT(fs->L, GETARG_B(previous) == MULT_RET, "call should be open"); + SET_OPCODE(previous, OP_TAILCALL); + SETARG_B(previous, nlocals); + setprevious(fs, previous); } - else - luaK_primitivecode(fs, CREATE_U(OP_RETURN, nlocals)); } static void luaK_pushnil (FuncState *fs, int n) { - Instruction *previous = previous_instruction(fs); - luaK_deltastack(fs, n); - switch(GET_OPCODE(*previous)) { - case OP_PUSHNIL: SETARG_U(*previous, GETARG_U(*previous)+n); break; - default: luaK_primitivecode(fs, CREATE_U(OP_PUSHNIL, n)); + Instruction previous = prepare(fs, CREATE_U(OP_PUSHNIL, n), n); + switch(GET_OPCODE(previous)) { + case OP_PUSHNIL: SETARG_U(previous, GETARG_U(previous)+n); break; + default: return; } -} - - -int luaK_code (FuncState *fs, Instruction i, int delta) { - luaK_deltastack(fs, delta); - return luaK_primitivecode(fs, i); + setprevious(fs, previous); } @@ -232,21 +249,17 @@ void luaK_adjuststack (FuncState *fs, int n) { int luaK_lastisopen (FuncState *fs) { - /* check whether last instruction is an (open) function call */ - Instruction *i = previous_instruction(fs); - if (GET_OPCODE(*i) == OP_CALL) { - LUA_ASSERT(fs->L, GETARG_B(*i) == MULT_RET, "call should be open"); + /* check whether last instruction is an open function call */ + Instruction i = previous_instruction(fs); + if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) return 1; - } else return 0; } void luaK_setcallreturns (FuncState *fs, int nresults) { - Instruction *i = previous_instruction(fs); - if (GET_OPCODE(*i) == OP_CALL) { /* expression is a function call? */ - LUA_ASSERT(fs->L, GETARG_B(*i) == MULT_RET, "call should be open"); - SETARG_B(*i, nresults); /* set nresults */ + if (luaK_lastisopen(fs)) { /* expression is an open function call? */ + SETARG_B(fs->f->code[fs->pc-1], nresults); /* set number of results */ luaK_deltastack(fs, nresults); /* push results */ } } @@ -323,12 +336,9 @@ static OpCode invertjump (OpCode op) { static void luaK_jump (FuncState *fs, OpCode jump) { - Instruction *previous = previous_instruction(fs); - luaK_deltastack(fs, -1); - if (*previous == CREATE_0(OP_NOT)) - *previous = CREATE_S(invertjump(jump), 0); - else - luaK_primitivecode(fs, CREATE_S(jump, 0)); + Instruction previous = prepare(fs, CREATE_S(jump, 0), -1); + if (previous == CREATE_0(OP_NOT)) + setprevious(fs, CREATE_S(invertjump(jump), 0)); } diff --git a/lcode.h b/lcode.h index 61c574cc..ce3901db 100644 --- a/lcode.h +++ b/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.7 2000/03/13 20:37:16 roberto Exp roberto $ +** $Id: lcode.h,v 1.8 2000/03/15 20:50:33 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -13,13 +13,11 @@ #include "lparser.h" -#define luaK_0(ls,o,d) luaK_code(ls, CREATE_0(o), d) -#define luaK_U(ls,o,u,d) luaK_code(ls, CREATE_U(o,u), d) -#define luaK_S(ls,o,s,d) luaK_code(ls, CREATE_S(o,s), d) -#define luaK_AB(ls,o,a,b,d) luaK_code(ls, CREATE_AB(o,a,b), d) - - void luaK_error (LexState *ls, const char *msg); +int luaK_0(FuncState *fs, OpCode o, int d); +int luaK_U(FuncState *fs, OpCode o, int u, int d); +int luaK_S(FuncState *fs, OpCode o, int s, int d); +int luaK_AB(FuncState *fs, OpCode o, int a, int b, int d); int luaK_code (FuncState *fs, Instruction i, int delta); void luaK_retcode (FuncState *fs, int nlocals, int nexps); void luaK_fixjump (FuncState *fs, int pc, int dest); -- cgit v1.2.3-55-g6feb