mirror of https://github.com/rusefi/lua.git
new optimization: jumps to jumps
This commit is contained in:
parent
c6965ce551
commit
d615e78e08
22
lcode.c
22
lcode.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lcode.c,v 1.19 2000/04/04 20:48:44 roberto Exp roberto $
|
** $Id: lcode.c,v 1.20 2000/04/05 17:51:58 roberto Exp roberto $
|
||||||
** Code generator for Lua
|
** Code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -171,7 +171,12 @@ static void luaK_neq (FuncState *fs) {
|
||||||
|
|
||||||
|
|
||||||
int luaK_jump (FuncState *fs) {
|
int luaK_jump (FuncState *fs) {
|
||||||
return luaK_S(fs, OP_JMP, NO_JUMP, 0);
|
int j = luaK_S(fs, OP_JMP, NO_JUMP, 0);
|
||||||
|
if (j == fs->lasttarget) { /* possible jumps to this jump? */
|
||||||
|
luaK_concat(fs, &j, fs->jlt); /* keep them on hold */
|
||||||
|
fs->jlt = NO_JUMP;
|
||||||
|
}
|
||||||
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,11 +225,17 @@ static int luaK_getjump (FuncState *fs, int pc) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
** discharge list of jumps to last target.
|
||||||
** returns current `pc' and marks it as a jump target (to avoid wrong
|
** returns current `pc' and marks it as a jump target (to avoid wrong
|
||||||
** optimizations with consecutive instructions not in the same basic block).
|
** optimizations with consecutive instructions not in the same basic block).
|
||||||
*/
|
*/
|
||||||
int luaK_getlabel (FuncState *fs) {
|
int luaK_getlabel (FuncState *fs) {
|
||||||
fs->lasttarget = fs->pc;
|
if (fs->pc != fs->lasttarget) {
|
||||||
|
int lasttarget = fs->lasttarget;
|
||||||
|
fs->lasttarget = fs->pc;
|
||||||
|
luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */
|
||||||
|
fs->jlt = NO_JUMP; /* nobody jumps to this new label (till now) */
|
||||||
|
}
|
||||||
return fs->pc;
|
return fs->pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +405,10 @@ static void luaK_patchlistaux (FuncState *fs, int list, int target,
|
||||||
|
|
||||||
|
|
||||||
void luaK_patchlist (FuncState *fs, int list, int target) {
|
void luaK_patchlist (FuncState *fs, int list, int target) {
|
||||||
luaK_patchlistaux(fs, list, target, OP_END, 0);
|
if (target == fs->lasttarget) /* same target that list `jlt'? */
|
||||||
|
luaK_concat(fs, &fs->jlt, list); /* delay fixing */
|
||||||
|
else
|
||||||
|
luaK_patchlistaux(fs, list, target, OP_END, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
36
lparser.c
36
lparser.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 1.75 2000/04/03 13:44:55 roberto Exp roberto $
|
** $Id: lparser.c,v 1.76 2000/04/05 17:51:58 roberto Exp roberto $
|
||||||
** LL(1) Parser and code generator for Lua
|
** LL(1) Parser and code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -71,20 +71,6 @@ static void error_unexpected (LexState *ls) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void error_unmatched (LexState *ls, int what, int who, int where) {
|
|
||||||
if (where == ls->linenumber)
|
|
||||||
error_expected(ls, what);
|
|
||||||
else {
|
|
||||||
char buff[100];
|
|
||||||
char t_what[TOKEN_LEN], t_who[TOKEN_LEN];
|
|
||||||
luaX_token2str(what, t_what);
|
|
||||||
luaX_token2str(who, t_who);
|
|
||||||
sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
|
|
||||||
t_what, t_who, where);
|
|
||||||
luaK_error(ls, buff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check (LexState *ls, int c) {
|
static void check (LexState *ls, int c) {
|
||||||
if (ls->token != c)
|
if (ls->token != c)
|
||||||
error_expected(ls, c);
|
error_expected(ls, c);
|
||||||
|
@ -121,8 +107,19 @@ static int optional (LexState *ls, int c) {
|
||||||
|
|
||||||
|
|
||||||
static void check_match (LexState *ls, int what, int who, int where) {
|
static void check_match (LexState *ls, int what, int who, int where) {
|
||||||
if (ls->token != what)
|
if (ls->token != what) {
|
||||||
error_unmatched(ls, what, who, where);
|
if (where == ls->linenumber)
|
||||||
|
error_expected(ls, what);
|
||||||
|
else {
|
||||||
|
char buff[100];
|
||||||
|
char t_what[TOKEN_LEN], t_who[TOKEN_LEN];
|
||||||
|
luaX_token2str(what, t_what);
|
||||||
|
luaX_token2str(who, t_who);
|
||||||
|
sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
|
||||||
|
t_what, t_who, where);
|
||||||
|
luaK_error(ls, buff);
|
||||||
|
}
|
||||||
|
}
|
||||||
next(ls);
|
next(ls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,6 +360,7 @@ static void init_state (LexState *ls, FuncState *fs, TString *source) {
|
||||||
f->source = source;
|
f->source = source;
|
||||||
fs->pc = 0;
|
fs->pc = 0;
|
||||||
fs->lasttarget = 0;
|
fs->lasttarget = 0;
|
||||||
|
fs->jlt = NO_JUMP;
|
||||||
f->code = NULL;
|
f->code = NULL;
|
||||||
f->maxstacksize = 0;
|
f->maxstacksize = 0;
|
||||||
f->numparams = 0; /* default for main chunk */
|
f->numparams = 0; /* default for main chunk */
|
||||||
|
@ -376,6 +374,7 @@ static void close_func (LexState *ls) {
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
Proto *f = fs->f;
|
Proto *f = fs->f;
|
||||||
luaK_0(fs, OP_END, 0);
|
luaK_0(fs, OP_END, 0);
|
||||||
|
luaK_getlabel(fs); /* close eventual list of pending jumps */
|
||||||
luaM_reallocvector(L, f->code, fs->pc, Instruction);
|
luaM_reallocvector(L, f->code, fs->pc, Instruction);
|
||||||
luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
|
luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
|
||||||
luaM_reallocvector(L, f->knum, f->nknum, Number);
|
luaM_reallocvector(L, f->knum, f->nknum, Number);
|
||||||
|
@ -1114,7 +1113,8 @@ static void ret (LexState *ls) {
|
||||||
Breaklabel *bl = fs->bl;
|
Breaklabel *bl = fs->bl;
|
||||||
int currentlevel = fs->stacklevel;
|
int currentlevel = fs->stacklevel;
|
||||||
if (bl == NULL)
|
if (bl == NULL)
|
||||||
luaK_error(ls, "no breakable structure to break");
|
luaK_error(ls, "break not inside while or repeat loop");
|
||||||
|
|
||||||
setline_and_next(ls); /* skip BREAK */
|
setline_and_next(ls); /* skip BREAK */
|
||||||
luaK_adjuststack(fs, currentlevel - bl->stacklevel);
|
luaK_adjuststack(fs, currentlevel - bl->stacklevel);
|
||||||
luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
|
luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lparser.h,v 1.14 2000/03/24 17:26:08 roberto Exp roberto $
|
** $Id: lparser.h,v 1.15 2000/04/05 17:51:58 roberto Exp roberto $
|
||||||
** LL(1) Parser and code generator for Lua
|
** LL(1) Parser and code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -43,6 +43,7 @@ typedef struct FuncState {
|
||||||
struct lua_State *L; /* copy of the Lua state */
|
struct lua_State *L; /* copy of the Lua state */
|
||||||
int pc; /* next position to code */
|
int pc; /* next position to code */
|
||||||
int lasttarget; /* `pc' of last `jump target' */
|
int lasttarget; /* `pc' of last `jump target' */
|
||||||
|
int jlt; /* list of jumps to `lasttarged' */
|
||||||
int stacklevel; /* number of values on activation register */
|
int stacklevel; /* number of values on activation register */
|
||||||
int nlocalvar; /* number of active local variables */
|
int nlocalvar; /* number of active local variables */
|
||||||
int nupvalues; /* number of upvalues */
|
int nupvalues; /* number of upvalues */
|
||||||
|
|
Loading…
Reference in New Issue