diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-04-06 14:36:52 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-04-06 14:36:52 -0300 |
| commit | d615e78e08201906e2f1dfc054b080fbbf7db428 (patch) | |
| tree | bc5e815f32ef1c49cb6f4c5a9fb1786365258d54 | |
| parent | c6965ce551ec8097dcaa3ed066fa12011857d42a (diff) | |
| download | lua-d615e78e08201906e2f1dfc054b080fbbf7db428.tar.gz lua-d615e78e08201906e2f1dfc054b080fbbf7db428.tar.bz2 lua-d615e78e08201906e2f1dfc054b080fbbf7db428.zip | |
new optimization: jumps to jumps
| -rw-r--r-- | lcode.c | 22 | ||||
| -rw-r--r-- | lparser.c | 36 | ||||
| -rw-r--r-- | lparser.h | 3 |
3 files changed, 38 insertions, 23 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 1.19 2000/04/04 20:48:44 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.20 2000/04/05 17:51:58 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -171,7 +171,12 @@ static void luaK_neq (FuncState *fs) { | |||
| 171 | 171 | ||
| 172 | 172 | ||
| 173 | int luaK_jump (FuncState *fs) { | 173 | int luaK_jump (FuncState *fs) { |
| 174 | return luaK_S(fs, OP_JMP, NO_JUMP, 0); | 174 | int j = luaK_S(fs, OP_JMP, NO_JUMP, 0); |
| 175 | if (j == fs->lasttarget) { /* possible jumps to this jump? */ | ||
| 176 | luaK_concat(fs, &j, fs->jlt); /* keep them on hold */ | ||
| 177 | fs->jlt = NO_JUMP; | ||
| 178 | } | ||
| 179 | return j; | ||
| 175 | } | 180 | } |
| 176 | 181 | ||
| 177 | 182 | ||
| @@ -220,11 +225,17 @@ static int luaK_getjump (FuncState *fs, int pc) { | |||
| 220 | 225 | ||
| 221 | 226 | ||
| 222 | /* | 227 | /* |
| 228 | ** discharge list of jumps to last target. | ||
| 223 | ** returns current `pc' and marks it as a jump target (to avoid wrong | 229 | ** returns current `pc' and marks it as a jump target (to avoid wrong |
| 224 | ** optimizations with consecutive instructions not in the same basic block). | 230 | ** optimizations with consecutive instructions not in the same basic block). |
| 225 | */ | 231 | */ |
| 226 | int luaK_getlabel (FuncState *fs) { | 232 | int luaK_getlabel (FuncState *fs) { |
| 227 | fs->lasttarget = fs->pc; | 233 | if (fs->pc != fs->lasttarget) { |
| 234 | int lasttarget = fs->lasttarget; | ||
| 235 | fs->lasttarget = fs->pc; | ||
| 236 | luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */ | ||
| 237 | fs->jlt = NO_JUMP; /* nobody jumps to this new label (till now) */ | ||
| 238 | } | ||
| 228 | return fs->pc; | 239 | return fs->pc; |
| 229 | } | 240 | } |
| 230 | 241 | ||
| @@ -394,7 +405,10 @@ static void luaK_patchlistaux (FuncState *fs, int list, int target, | |||
| 394 | 405 | ||
| 395 | 406 | ||
| 396 | void luaK_patchlist (FuncState *fs, int list, int target) { | 407 | void luaK_patchlist (FuncState *fs, int list, int target) { |
| 397 | luaK_patchlistaux(fs, list, target, OP_END, 0); | 408 | if (target == fs->lasttarget) /* same target that list `jlt'? */ |
| 409 | luaK_concat(fs, &fs->jlt, list); /* delay fixing */ | ||
| 410 | else | ||
| 411 | luaK_patchlistaux(fs, list, target, OP_END, 0); | ||
| 398 | } | 412 | } |
| 399 | 413 | ||
| 400 | 414 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.75 2000/04/03 13:44:55 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.76 2000/04/05 17:51:58 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -71,20 +71,6 @@ static void error_unexpected (LexState *ls) { | |||
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | 73 | ||
| 74 | static void error_unmatched (LexState *ls, int what, int who, int where) { | ||
| 75 | if (where == ls->linenumber) | ||
| 76 | error_expected(ls, what); | ||
| 77 | else { | ||
| 78 | char buff[100]; | ||
| 79 | char t_what[TOKEN_LEN], t_who[TOKEN_LEN]; | ||
| 80 | luaX_token2str(what, t_what); | ||
| 81 | luaX_token2str(who, t_who); | ||
| 82 | sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", | ||
| 83 | t_what, t_who, where); | ||
| 84 | luaK_error(ls, buff); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | static void check (LexState *ls, int c) { | 74 | static void check (LexState *ls, int c) { |
| 89 | if (ls->token != c) | 75 | if (ls->token != c) |
| 90 | error_expected(ls, c); | 76 | error_expected(ls, c); |
| @@ -121,8 +107,19 @@ static int optional (LexState *ls, int c) { | |||
| 121 | 107 | ||
| 122 | 108 | ||
| 123 | static void check_match (LexState *ls, int what, int who, int where) { | 109 | static void check_match (LexState *ls, int what, int who, int where) { |
| 124 | if (ls->token != what) | 110 | if (ls->token != what) { |
| 125 | error_unmatched(ls, what, who, where); | 111 | if (where == ls->linenumber) |
| 112 | error_expected(ls, what); | ||
| 113 | else { | ||
| 114 | char buff[100]; | ||
| 115 | char t_what[TOKEN_LEN], t_who[TOKEN_LEN]; | ||
| 116 | luaX_token2str(what, t_what); | ||
| 117 | luaX_token2str(who, t_who); | ||
| 118 | sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", | ||
| 119 | t_what, t_who, where); | ||
| 120 | luaK_error(ls, buff); | ||
| 121 | } | ||
| 122 | } | ||
| 126 | next(ls); | 123 | next(ls); |
| 127 | } | 124 | } |
| 128 | 125 | ||
| @@ -363,6 +360,7 @@ static void init_state (LexState *ls, FuncState *fs, TString *source) { | |||
| 363 | f->source = source; | 360 | f->source = source; |
| 364 | fs->pc = 0; | 361 | fs->pc = 0; |
| 365 | fs->lasttarget = 0; | 362 | fs->lasttarget = 0; |
| 363 | fs->jlt = NO_JUMP; | ||
| 366 | f->code = NULL; | 364 | f->code = NULL; |
| 367 | f->maxstacksize = 0; | 365 | f->maxstacksize = 0; |
| 368 | f->numparams = 0; /* default for main chunk */ | 366 | f->numparams = 0; /* default for main chunk */ |
| @@ -376,6 +374,7 @@ static void close_func (LexState *ls) { | |||
| 376 | FuncState *fs = ls->fs; | 374 | FuncState *fs = ls->fs; |
| 377 | Proto *f = fs->f; | 375 | Proto *f = fs->f; |
| 378 | luaK_0(fs, OP_END, 0); | 376 | luaK_0(fs, OP_END, 0); |
| 377 | luaK_getlabel(fs); /* close eventual list of pending jumps */ | ||
| 379 | luaM_reallocvector(L, f->code, fs->pc, Instruction); | 378 | luaM_reallocvector(L, f->code, fs->pc, Instruction); |
| 380 | luaM_reallocvector(L, f->kstr, f->nkstr, TString *); | 379 | luaM_reallocvector(L, f->kstr, f->nkstr, TString *); |
| 381 | luaM_reallocvector(L, f->knum, f->nknum, Number); | 380 | luaM_reallocvector(L, f->knum, f->nknum, Number); |
| @@ -1114,7 +1113,8 @@ static void ret (LexState *ls) { | |||
| 1114 | Breaklabel *bl = fs->bl; | 1113 | Breaklabel *bl = fs->bl; |
| 1115 | int currentlevel = fs->stacklevel; | 1114 | int currentlevel = fs->stacklevel; |
| 1116 | if (bl == NULL) | 1115 | if (bl == NULL) |
| 1117 | luaK_error(ls, "no breakable structure to break"); | 1116 | luaK_error(ls, "break not inside while or repeat loop"); |
| 1117 | |||
| 1118 | setline_and_next(ls); /* skip BREAK */ | 1118 | setline_and_next(ls); /* skip BREAK */ |
| 1119 | luaK_adjuststack(fs, currentlevel - bl->stacklevel); | 1119 | luaK_adjuststack(fs, currentlevel - bl->stacklevel); |
| 1120 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); | 1120 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.h,v 1.14 2000/03/24 17:26:08 roberto Exp roberto $ | 2 | ** $Id: lparser.h,v 1.15 2000/04/05 17:51:58 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -43,6 +43,7 @@ typedef struct FuncState { | |||
| 43 | struct lua_State *L; /* copy of the Lua state */ | 43 | struct lua_State *L; /* copy of the Lua state */ |
| 44 | int pc; /* next position to code */ | 44 | int pc; /* next position to code */ |
| 45 | int lasttarget; /* `pc' of last `jump target' */ | 45 | int lasttarget; /* `pc' of last `jump target' */ |
| 46 | int jlt; /* list of jumps to `lasttarged' */ | ||
| 46 | int stacklevel; /* number of values on activation register */ | 47 | int stacklevel; /* number of values on activation register */ |
| 47 | int nlocalvar; /* number of active local variables */ | 48 | int nlocalvar; /* number of active local variables */ |
| 48 | int nupvalues; /* number of upvalues */ | 49 | int nupvalues; /* number of upvalues */ |
