From d1ea38580ae35a3a34e7122c41682af7f9901030 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 3 Mar 2000 15:53:17 -0300 Subject: [PATCH] change of code generation design (independent functions for each opcode) --- lcode.c | 237 ++++++++++++++++++++++++----------------------------- lcode.h | 25 +++--- lopcodes.h | 7 +- lparser.c | 85 +++++++++---------- lparser.h | 28 ++++--- 5 files changed, 187 insertions(+), 195 deletions(-) diff --git a/lcode.c b/lcode.c index cf9aee47..2d9c2285 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.2 2000/03/03 12:33:59 roberto Exp roberto $ +** $Id: lcode.c,v 1.3 2000/03/03 14:58:26 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -20,12 +20,10 @@ void luaK_error (LexState *ls, const char *msg) { } -static Instruction *last_i (FuncState *fs) { - static Instruction dummy = SET_OPCODE(0, ENDCODE); - if (fs->last_pc < 0) - return &dummy; - else - return &fs->f->code[fs->last_pc]; +static Instruction *last_i (LexState *ls, expdesc *v) { + FuncState *fs = ls->fs; + int last_pc = (v->info != NOJUMPS) ? v->info : fs->pc-1; + return &fs->f->code[last_pc]; } @@ -37,58 +35,64 @@ int luaK_primitivecode (LexState *ls, Instruction i) { } - -int luaK_code (LexState *ls, Instruction i) { - FuncState *fs = ls->fs; - Instruction *last = last_i(fs); - switch (GET_OPCODE(i)) { - - case MINUSOP: - switch(GET_OPCODE(*last)) { - case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); break; - case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); break; - case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); break; - default: fs->last_pc = luaK_primitivecode(ls, i); - } - break; - - case GETTABLE: - switch(GET_OPCODE(*last)) { - case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break; - default: fs->last_pc = luaK_primitivecode(ls, i); - } - break; - - case RETCODE: - switch(GET_OPCODE(*last)) { - case CALL: - *last = SET_OPCODE(*last, TAILCALL); - *last = SETARG_B(*last, GETARG_U(i)); - break; - default: fs->last_pc = luaK_primitivecode(ls, i); - } - break; - - case ADDOP: - switch(GET_OPCODE(*last)) { - case PUSHINT: *last = SET_OPCODE(*last, ADDI); break; - default: fs->last_pc = luaK_primitivecode(ls, i); - } - break; - - case SUBOP: - switch(GET_OPCODE(*last)) { - case PUSHINT: - *last = SET_OPCODE(*last, ADDI); - *last = SETARG_S(*last, -GETARG_S(*last)); - break; - default: fs->last_pc = luaK_primitivecode(ls, i); - } - break; - - default: fs->last_pc = luaK_primitivecode(ls, i); +static void luaK_minus (LexState *ls, expdesc *v) { + Instruction *last = last_i(ls, v); + switch(GET_OPCODE(*last)) { + case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); return; + case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); return; + case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); return; + default: luaK_primitivecode(ls, CREATE_0(MINUSOP)); } - return fs->last_pc; +} + + +static void luaK_gettable (LexState *ls, expdesc *v) { + Instruction *last = last_i(ls, v); + luaK_deltastack(ls, -1); + switch(GET_OPCODE(*last)) { + case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break; + default: luaK_primitivecode(ls, CREATE_0(GETTABLE)); + } +} + + +static void luaK_add (LexState *ls, expdesc *v) { + Instruction *last = last_i(ls, v); + luaK_deltastack(ls, -1); + switch(GET_OPCODE(*last)) { + case PUSHINT: *last = SET_OPCODE(*last, ADDI); break; + default: luaK_primitivecode(ls, CREATE_0(ADDOP)); + } +} + + +static void luaK_sub (LexState *ls, expdesc *v) { + Instruction *last = last_i(ls, v); + luaK_deltastack(ls, -1); + switch(GET_OPCODE(*last)) { + case PUSHINT: + *last = SET_OPCODE(*last, ADDI); + *last = SETARG_S(*last, -GETARG_S(*last)); + break; + default: luaK_primitivecode(ls, CREATE_0(SUBOP)); + } +} + + +void luaK_retcode (LexState *ls, int nlocals, listdesc *e) { + if (e->n > 0 && luaK_iscall(ls, e->info)) { + Instruction *last = &ls->fs->f->code[ls->fs->pc-1]; + *last = SET_OPCODE(*last, TAILCALL); + *last = SETARG_B(*last, nlocals); + } + else + luaK_U(ls, RETCODE, nlocals, 0); +} + + +int luaK_code (LexState *ls, Instruction i, int delta) { + luaK_deltastack(ls, delta); + return luaK_primitivecode(ls, i); } @@ -97,7 +101,6 @@ void luaK_fixjump (LexState *ls, int pc, int dest) { Instruction *jmp = &fs->f->code[pc]; /* jump is relative to position following jump instruction */ *jmp = SETARG_S(*jmp, dest-(pc+1)); - fs->last_pc = pc; } @@ -112,38 +115,8 @@ void luaK_deltastack (LexState *ls, int delta) { } -static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) { - luaK_deltastack(ls, delta); - return luaK_code(ls, SET_OPCODE(i, op)); -} - - -int luaK_0 (LexState *ls, OpCode op, int delta) { - return aux_code(ls, op, 0, delta); -} - - -int luaK_U (LexState *ls, OpCode op, int u, int delta) { - Instruction i = SETARG_U(0, u); - return aux_code(ls, op, i, delta); -} - - -int luaK_S (LexState *ls, OpCode op, int s, int delta) { - Instruction i = SETARG_S(0, s); - return aux_code(ls, op, i, delta); -} - - -int luaK_AB (LexState *ls, OpCode op, int a, int b, int delta) { - Instruction i = SETARG_A(0, a); - i = SETARG_B(i, b); - return aux_code(ls, op, i, delta); -} - - -int luaK_kstr (LexState *ls, int c) { - return luaK_U(ls, PUSHSTRING, c, 1); +void luaK_kstr (LexState *ls, int c) { + luaK_U(ls, PUSHSTRING, c, 1); } @@ -166,37 +139,40 @@ static int real_constant (LexState *ls, real r) { } -int luaK_number (LexState *ls, real f) { +void luaK_number (LexState *ls, real f) { if (f <= (real)MAXARG_S && (int)f == f) - return luaK_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */ + luaK_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */ else - return luaK_U(ls, PUSHNUM, real_constant(ls, f), 1); + luaK_U(ls, PUSHNUM, real_constant(ls, f), 1); } -int luaK_adjuststack (LexState *ls, int n) { +void luaK_adjuststack (LexState *ls, int n) { if (n > 0) - return luaK_U(ls, POP, n, -n); + luaK_U(ls, POP, n, -n); else if (n < 0) - return luaK_U(ls, PUSHNIL, (-n)-1, -n); - else return 0; + luaK_U(ls, PUSHNIL, (-n)-1, -n); } -int luaK_iscall (LexState *ls, int pc) { - return (GET_OPCODE(ls->fs->f->code[pc]) == CALL); +int luaK_iscall (LexState *ls, int hasjumps) { + if (hasjumps) return 0; /* a call cannot have internal jumps */ + else /* check whether last instruction is a function call */ + return (GET_OPCODE(ls->fs->f->code[ls->fs->pc-1]) == CALL); } -void luaK_setcallreturns (LexState *ls, int pc, int nresults) { - if (luaK_iscall(ls, pc)) { /* expression is a function call? */ - Instruction *i = &ls->fs->f->code[pc]; - int old_nresults = GETARG_B(*i); - if (old_nresults != MULT_RET) - luaK_deltastack(ls, -old_nresults); /* pop old nresults */ - *i = SETARG_B(*i, nresults); /* set nresults */ - if (nresults != MULT_RET) - luaK_deltastack(ls, nresults); /* push results */ +void luaK_setcallreturns (LexState *ls, int hasjumps, int nresults) { + if (!hasjumps) { /* if `hasjumps' cannot be a function call */ + Instruction *i = &ls->fs->f->code[ls->fs->pc-1]; + if (GET_OPCODE(*i) == CALL) { /* expression is a function call? */ + int old_nresults = GETARG_B(*i); + if (old_nresults != MULT_RET) + luaK_deltastack(ls, -old_nresults); /* pop old nresults */ + *i = SETARG_B(*i, nresults); /* set nresults */ + if (nresults != MULT_RET) + luaK_deltastack(ls, nresults); /* push results */ + } } } @@ -209,20 +185,21 @@ static void assertglobal (LexState *ls, int index) { void luaK_2stack (LexState *ls, expdesc *var) { switch (var->k) { case VLOCAL: - var->info = luaK_U(ls, PUSHLOCAL, var->info, 1); + luaK_U(ls, PUSHLOCAL, var->info, 1); break; case VGLOBAL: + luaK_U(ls, GETGLOBAL, var->info, 1); assertglobal(ls, var->info); /* make sure that there is a global */ - var->info = luaK_U(ls, GETGLOBAL, var->info, 1); break; case VINDEXED: - var->info = luaK_0(ls, GETTABLE, -1); + luaK_gettable(ls, var); break; case VEXP: luaK_setcallreturns(ls, var->info, 1); /* call must return 1 value */ - break; + return; /* does not change var->info */ } var->k = VEXP; + var->info = NOJUMPS; } @@ -246,10 +223,9 @@ void luaK_storevar (LexState *ls, const expdesc *var) { void luaK_prefix (LexState *ls, int op, expdesc *v) { luaK_2stack(ls, v); - if (op == '-') - v->info = luaK_0(ls, MINUSOP, 0); - else - v->info = luaK_0(ls, NOTOP, 0); + if (op == '-') luaK_minus(ls, v); + else luaK_0(ls, NOTOP, 0); + v->info = NOJUMPS; } @@ -267,19 +243,20 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) { switch (op) { case AND: case OR: luaK_fixjump(ls, v1->info, ls->fs->pc); - break; - case '+': v1->info = luaK_0(ls, ADDOP, -1); break; - case '-': v1->info = luaK_0(ls, SUBOP, -1); break; - case '*': v1->info = luaK_0(ls, MULTOP, -1); break; - case '/': v1->info = luaK_0(ls, DIVOP, -1); break; - case '^': v1->info = luaK_0(ls, POWOP, -1); break; - case CONC: v1->info = luaK_0(ls, CONCOP, -1); break; - case EQ: v1->info = luaK_0(ls, EQOP, -1); break; - case NE: v1->info = luaK_0(ls, NEQOP, -1); break; - case '>': v1->info = luaK_0(ls, GTOP, -1); break; - case '<': v1->info = luaK_0(ls, LTOP, -1); break; - case GE: v1->info = luaK_0(ls, GEOP, -1); break; - case LE: v1->info = luaK_0(ls, LEOP, -1); break; + return; /* keep v1->info != NOJUMPS */ + case '+': luaK_add(ls, v2); break; + case '-': luaK_sub(ls, v2); break; + case '*': luaK_0(ls, MULTOP, -1); break; + case '/': luaK_0(ls, DIVOP, -1); break; + case '^': luaK_0(ls, POWOP, -1); break; + case CONC: luaK_0(ls, CONCOP, -1); break; + case EQ: luaK_0(ls, EQOP, -1); break; + case NE: luaK_0(ls, NEQOP, -1); break; + case '>': luaK_0(ls, GTOP, -1); break; + case '<': luaK_0(ls, LTOP, -1); break; + case GE: luaK_0(ls, GEOP, -1); break; + case LE: luaK_0(ls, LEOP, -1); break; } + v1->info = NOJUMPS; } diff --git a/lcode.h b/lcode.h index 23a26dc7..0ba83766 100644 --- a/lcode.h +++ b/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.1 2000/02/22 13:31:19 roberto Exp roberto $ +** $Id: lcode.h,v 1.2 2000/03/03 12:33:59 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -13,20 +13,23 @@ #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_primitivecode (LexState *ls, Instruction i); -int luaK_code (LexState *ls, Instruction i); +int luaK_code (LexState *ls, Instruction i, int delta); +void luaK_retcode (LexState *ls, int nlocals, listdesc *e); void luaK_fixjump (LexState *ls, int pc, int dest); void luaK_deltastack (LexState *ls, int delta); -int luaK_0 (LexState *ls, OpCode op, int delta); -int luaK_U (LexState *ls, OpCode op, int u, int delta); -int luaK_S (LexState *ls, OpCode op, int s, int delta); -int luaK_AB (LexState *ls, OpCode op, int a, int b, int delta); -int luaK_kstr (LexState *ls, int c); -int luaK_number (LexState *ls, real f); -int luaK_adjuststack (LexState *ls, int n); -int luaK_iscall (LexState *ls, int pc); -void luaK_setcallreturns (LexState *ls, int pc, int nresults); +void luaK_kstr (LexState *ls, int c); +void luaK_number (LexState *ls, real f); +void luaK_adjuststack (LexState *ls, int n); +int luaK_iscall (LexState *ls, int hasjumps); +void luaK_setcallreturns (LexState *ls, int hasjumps, int nresults); void luaK_2stack (LexState *ls, expdesc *var); void luaK_storevar (LexState *ls, const expdesc *var); void luaK_prefix (LexState *ls, int op, expdesc *v); diff --git a/lopcodes.h b/lopcodes.h index c822049c..b2819c3b 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.42 2000/03/02 12:32:53 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.43 2000/03/03 14:58:26 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -47,6 +47,11 @@ #define SETARG_A(i,a) (((i)&0x0000FFFFu) | ((Instruction)(a)<<16)) #define SETARG_B(i,b) (((i)&0xFFFF00FFu) | ((Instruction)(b)<<8)) +#define CREATE_0(o) ((Instruction)(o)) +#define CREATE_U(o,u) ((Instruction)(o) | (Instruction)(u)<<8) +#define CREATE_S(o,s) ((Instruction)(o) | ((Instruction)(s)+EXCESS_S)<<8) +#define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<16) \ + | ((Instruction)(b)<<8)) /* diff --git a/lparser.c b/lparser.c index 1cdc35b6..b13ee9d5 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.61 2000/03/03 12:33:59 roberto Exp roberto $ +** $Id: lparser.c,v 1.62 2000/03/03 14:58:26 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -23,15 +23,13 @@ /* -** Expression List descriptor: -** tells number of expressions in the list, -** and, if last expression is open (a function call), -** where is the call pc index. +** check whether arbitrary limits fit in respective opcode types */ -typedef struct listdesc { - int n; - int pc; /* 0 if last expression is closed */ -} listdesc; +#if MAXLOCALS>MAXARG_U || MAXUPVALUES>MAXARG_B || MAXVARSLH>MAXARG_B || \ + MAXPARAMS>MAXLOCALS || MAXSTACK>MAXARG_A || LFIELDS_PER_FLUSH>MAXARG_B +#error invalid limits +#endif + /* @@ -51,11 +49,11 @@ typedef struct constdesc { /* ** prototypes for recursive non-terminal functions */ -static int body (LexState *ls, int needself, int line); +static void body (LexState *ls, int needself, int line); static void chunk (LexState *ls); -static int constructor (LexState *ls); +static void constructor (LexState *ls); static void expr (LexState *ls, expdesc *v); -static void exp1 (LexState *ls); +static int exp1 (LexState *ls); static void next (LexState *ls) { @@ -145,8 +143,8 @@ static int string_constant (LexState *ls, FuncState *fs, TaggedString *s) { } -static int code_string (LexState *ls, TaggedString *s) { - return luaK_kstr(ls, string_constant(ls, ls->fs, s)); +static void code_string (LexState *ls, TaggedString *s) { + luaK_kstr(ls, string_constant(ls, ls->fs, s)); } @@ -249,18 +247,18 @@ static int indexupvalue (LexState *ls, TaggedString *n) { } -static int pushupvalue (LexState *ls, TaggedString *n) { +static void pushupvalue (LexState *ls, TaggedString *n) { if (ls->fs->prev == NULL) luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); if (aux_localname(ls->fs, n) >= 0) luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); - return luaK_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); + luaK_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); } static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { int diff = d->n - nvars; - if (d->n == 0 || !luaK_iscall(ls, d->pc)) { /* list is empty or closed */ + if (d->n == 0 || !luaK_iscall(ls, d->info)) { /* list is empty or closed */ /* push or pop eventual difference between list lengths */ luaK_adjuststack(ls, diff); } @@ -268,10 +266,10 @@ static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { diff--; /* do not count function call itself */ if (diff <= 0) { /* more variables than values? */ /* function call must provide extra values */ - luaK_setcallreturns(ls, d->pc, -diff); + luaK_setcallreturns(ls, d->info, -diff); } else { /* more values than variables */ - luaK_setcallreturns(ls, d->pc, 0); /* call should provide no value */ + luaK_setcallreturns(ls, d->info, 0); /* call should provide no value */ luaK_adjuststack(ls, diff); /* pop eventual extra values */ } } @@ -308,7 +306,7 @@ static int getvarname (LexState *ls, expdesc *var) { } -static int func_onstack (LexState *ls, FuncState *func) { +static void func_onstack (LexState *ls, FuncState *func) { TProtoFunc *f = ls->fs->f; int i; for (i=0; inupvalues; i++) @@ -317,7 +315,7 @@ static int func_onstack (LexState *ls, FuncState *func) { constantEM, MAXARG_A); f->kproto[f->nkproto++] = func->f; luaK_deltastack(ls, 1); /* CLOSURE puts one extra element before popping */ - return luaK_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues); + luaK_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues); } @@ -333,7 +331,6 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) { fs->f = f; f->source = source; fs->pc = 0; - fs->last_pc = -1; /* invalid index to signal no last instruction */ f->code = NULL; f->maxstacksize = 0; f->numparams = 0; /* default for main chunk */ @@ -395,7 +392,7 @@ static void explist1 (LexState *ls, listdesc *d) { } luaK_2stack(ls, &v); luaK_setcallreturns(ls, v.info, MULT_RET); /* default for explists */ - d->pc = v.info; + d->info = v.info; } @@ -412,7 +409,7 @@ static void explist (LexState *ls, listdesc *d) { } -static int funcparams (LexState *ls, int slf) { +static void funcparams (LexState *ls, int slf) { FuncState *fs = ls->fs; int slevel = fs->stacksize - slf - 1; /* where is func in the stack */ switch (ls->token) { @@ -443,7 +440,7 @@ static int funcparams (LexState *ls, int slf) { break; } fs->stacksize = slevel; /* call will remove func and params */ - return luaK_AB(ls, CALL, slevel, 0, 0); + luaK_AB(ls, CALL, slevel, 0, 0); } @@ -455,14 +452,15 @@ static void var_or_func_tail (LexState *ls, expdesc *v) { luaK_2stack(ls, v); /* `v' must be on stack */ luaK_kstr(ls, checkname(ls)); v->k = VINDEXED; + v->info = NOJUMPS; break; case '[': /* var_or_func_tail -> '[' exp1 ']' */ next(ls); luaK_2stack(ls, v); /* `v' must be on stack */ - exp1(ls); - check(ls, ']'); v->k = VINDEXED; + v->info = exp1(ls); + check(ls, ']'); break; case ':': { /* var_or_func_tail -> ':' NAME funcparams */ @@ -471,15 +469,17 @@ static void var_or_func_tail (LexState *ls, expdesc *v) { name = checkname(ls); luaK_2stack(ls, v); /* `v' must be on stack */ luaK_U(ls, PUSHSELF, name, 1); + funcparams(ls, 1); v->k = VEXP; - v->info = funcparams(ls, 1); + v->info = NOJUMPS; break; } case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ luaK_2stack(ls, v); /* `v' must be on stack */ + funcparams(ls, 0); v->k = VEXP; - v->info = funcparams(ls, 0); + v->info = NOJUMPS; break; default: return; /* should be follow... */ @@ -491,8 +491,9 @@ static void var_or_func_tail (LexState *ls, expdesc *v) { static void var_or_func (LexState *ls, expdesc *v) { /* var_or_func -> ['%'] NAME var_or_func_tail */ if (optional(ls, '%')) { /* upvalue? */ + pushupvalue(ls, str_checkname(ls)); v->k = VEXP; - v->info = pushupvalue(ls, str_checkname(ls)); + v->info = NOJUMPS; } else /* variable name */ singlevar(ls, str_checkname(ls), v, 0); @@ -614,7 +615,7 @@ static void constructor_part (LexState *ls, constdesc *cd) { } -static int constructor (LexState *ls) { +static void constructor (LexState *ls) { /* constructor -> '{' constructor_part [';' constructor_part] '}' */ int line = ls->linenumber; int pc = luaK_U(ls, CREATETABLE, 0, 1); @@ -634,7 +635,6 @@ static int constructor (LexState *ls) { check_match(ls, '}', '{', line); /* set initial table size */ ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems); - return pc; } /* }====================================================================== */ @@ -655,28 +655,27 @@ static void simpleexp (LexState *ls, expdesc *v) { case NUMBER: { /* simpleexp -> NUMBER */ real r = ls->seminfo.r; next(ls); - v->info = luaK_number(ls, r); + luaK_number(ls, r); break; } case STRING: /* simpleexp -> STRING */ - /* must use `seminfo' before `next' */ - v->info = code_string(ls, ls->seminfo.ts); + code_string(ls, ls->seminfo.ts); /* must use `seminfo' before `next' */ next(ls); break; case NIL: /* simpleexp -> NIL */ - v->info = luaK_adjuststack(ls, -1); + luaK_adjuststack(ls, -1); next(ls); break; case '{': /* simpleexp -> constructor */ - v->info = constructor(ls); + constructor(ls); break; case FUNCTION: /* simpleexp -> FUNCTION body */ next(ls); - v->info = body(ls, 0, ls->linenumber); + body(ls, 0, ls->linenumber); break; case '(': /* simpleexp -> '(' expr ')' */ @@ -694,13 +693,15 @@ static void simpleexp (LexState *ls, expdesc *v) { return; } v->k = VEXP; + v->info = NOJUMPS; } -static void exp1 (LexState *ls) { +static int exp1 (LexState *ls) { expdesc v; expr(ls, &v); luaK_2stack(ls, &v); + return v.info; } @@ -1052,7 +1053,7 @@ static void parlist (LexState *ls) { } -static int body (LexState *ls, int needself, int line) { +static void body (LexState *ls, int needself, int line) { /* body -> '(' parlist ')' chunk END */ FuncState new_fs; init_state(ls, &new_fs, ls->fs->f->source); @@ -1065,7 +1066,7 @@ static int body (LexState *ls, int needself, int line) { chunk(ls); check_match(ls, END, FUNCTION, line); close_func(ls); - return func_onstack(ls, &new_fs); + func_onstack(ls, &new_fs); } @@ -1076,7 +1077,7 @@ static void ret (LexState *ls) { check_debugline(ls); next(ls); explist(ls, &e); - luaK_U(ls, RETCODE, ls->fs->nlocalvar, 0); + luaK_retcode(ls, ls->fs->nlocalvar, &e); ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ optional(ls, ';'); } diff --git a/lparser.h b/lparser.h index a3568a6f..a64b8dda 100644 --- a/lparser.h +++ b/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.7 2000/03/03 12:33:59 roberto Exp roberto $ +** $Id: lparser.h,v 1.8 2000/03/03 14:58:26 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -8,7 +8,6 @@ #define lparser_h #include "lobject.h" -#include "lopcodes.h" #include "lzio.h" @@ -42,21 +41,18 @@ #endif -#if MAXLOCALS>MAXARG_U || MAXUPVALUES>MAXARG_B || MAXVARSLH>MAXARG_B || \ - MAXPARAMS>MAXLOCALS || MAXSTACK>MAXARG_A || LFIELDS_PER_FLUSH>MAXARG_B -#error invalid limits -#endif - - /* ** Expression descriptor */ + +#define NOJUMPS 0 + typedef enum { VGLOBAL, /* info is constant index of global name */ VLOCAL, /* info is stack index */ - VINDEXED, /* no info (table and index are on the stack) */ - VEXP /* info is pc index of exp main operator */ + VINDEXED, /* info is info of the index expression */ + VEXP /* info is NOJUMPS if exp has no internal jumps */ } expkind; typedef struct expdesc { @@ -65,12 +61,22 @@ typedef struct expdesc { } expdesc; +/* +** Expression List descriptor: +** tells number of expressions in the list, +** and gives the `info' of last expression. +*/ +typedef struct listdesc { + int n; + int info; /* 0 if last expression has no internal jumps */ +} listdesc; + + /* state needed to generate code for a given function */ typedef struct FuncState { TProtoFunc *f; /* current function header */ struct FuncState *prev; /* enclosing function */ int pc; /* next position to code */ - int last_pc; /* last instruction coded (for optimizations) */ int stacksize; /* number of values on activation register */ int nlocalvar; /* number of active local variables */ int nupvalues; /* number of upvalues */