aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-05-10 14:02:32 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-05-10 14:02:32 -0300
commitb487975344ee90c0410e79e1af08461bdbc0f3da (patch)
tree4ae1c9f12afe1edbcc0c8de22abdac4b19e2844d /lparser.c
parent94e5545806515bc830982dedc4966bd2756a023e (diff)
downloadlua-b487975344ee90c0410e79e1af08461bdbc0f3da.tar.gz
lua-b487975344ee90c0410e79e1af08461bdbc0f3da.tar.bz2
lua-b487975344ee90c0410e79e1af08461bdbc0f3da.zip
optimization for `while' (first version)
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/lparser.c b/lparser.c
index b6e500b8..eaf0bc8a 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.178 2002/04/24 20:07:46 roberto Exp roberto $ 2** $Id: lparser.c,v 1.179 2002/05/07 17:36:56 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -946,22 +946,61 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
946static void cond (LexState *ls, expdesc *v) { 946static void cond (LexState *ls, expdesc *v) {
947 /* cond -> exp */ 947 /* cond -> exp */
948 expr(ls, v); /* read condition */ 948 expr(ls, v); /* read condition */
949 if (v->k == VNIL) v->k = VFALSE; /* `falses' are all equal here */
949 luaK_goiftrue(ls->fs, v); 950 luaK_goiftrue(ls->fs, v);
951 luaK_patchtohere(ls->fs, v->t);
950} 952}
951 953
952 954
955/*
956** The while statement optimizes its code by coding the condition
957** after its body (and thus avoiding one jump in the loop).
958*/
959
960/*
961** maximum size of expressions for optimizing `while' code
962*/
963#ifndef MAXEXPWHILE
964#define MAXEXPWHILE 100
965#endif
966
967/*
968** the call `luaK_goiffalse' may grow the size of an expression by
969** at most this:
970*/
971#define EXTRAEXP 5
972
953static void whilestat (LexState *ls, int line) { 973static void whilestat (LexState *ls, int line) {
954 /* whilestat -> WHILE cond DO block END */ 974 /* whilestat -> WHILE cond DO block END */
975 Instruction codeexp[MAXEXPWHILE + EXTRAEXP];
976 int lineexp = 0;
977 int i;
978 int sizeexp;
955 FuncState *fs = ls->fs; 979 FuncState *fs = ls->fs;
956 int while_init = luaK_getlabel(fs); 980 int while_init = luaK_getlabel(fs);
957 expdesc v; 981 expdesc v;
958 BlockCnt bl; 982 BlockCnt bl;
959 enterblock(fs, &bl, 1);
960 next(ls); 983 next(ls);
961 cond(ls, &v); 984 expr(ls, &v);
985 if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */
986 lineexp = ls->linenumber;
987 luaK_goiffalse(fs, &v);
988 sizeexp = fs->pc - while_init;
989 if (sizeexp > MAXEXPWHILE)
990 luaX_syntaxerror(ls, "while condition too complex");
991 fs->pc = while_init; /* remove `exp' code */
992 luaK_getlabel(fs);
993 for (i = 0; i < sizeexp; i++) /* save `exp' code */
994 codeexp[i] = fs->f->code[while_init + i];
995 luaK_jump(fs);
996 enterblock(fs, &bl, 1);
962 check(ls, TK_DO); 997 check(ls, TK_DO);
963 block(ls); 998 block(ls);
964 luaK_patchlist(fs, luaK_jump(fs), while_init); 999 luaK_patchtohere(fs, while_init); /* initial jump jumps to here */
1000 luaK_moveexp(&v, fs->pc - while_init); /* correct pointers */
1001 for (i=0; i<sizeexp; i++)
1002 luaK_code(fs, codeexp[i], lineexp);
1003 luaK_patchlist(fs, v.t, while_init+1);
965 luaK_patchtohere(fs, v.f); 1004 luaK_patchtohere(fs, v.f);
966 check_match(ls, TK_END, TK_WHILE, line); 1005 check_match(ls, TK_END, TK_WHILE, line);
967 leaveblock(fs); 1006 leaveblock(fs);