mirror of https://github.com/rusefi/lua.git
optimization for `while' (first version)
This commit is contained in:
parent
94e5545806
commit
b487975344
27
lcode.c
27
lcode.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lcode.c,v 1.99 2002/05/07 17:36:56 roberto Exp roberto $
|
** $Id: lcode.c,v 1.100 2002/05/09 14:14:34 roberto Exp roberto $
|
||||||
** Code generator for Lua
|
** Code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -39,6 +39,13 @@ void luaK_nil (FuncState *fs, int from, int n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaK_moveexp (expdesc *e, int offset) {
|
||||||
|
if (e->t != NO_JUMP) e->t += offset;
|
||||||
|
if (e->f != NO_JUMP) e->f += offset;
|
||||||
|
if (e->k == VRELOCABLE || e->k == VJMP) e->info += offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaK_jump (FuncState *fs) {
|
int luaK_jump (FuncState *fs) {
|
||||||
int j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
|
int j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
|
||||||
if (j == fs->lasttarget) { /* possible jumps to this jump? */
|
if (j == fs->lasttarget) { /* possible jumps to this jump? */
|
||||||
|
@ -515,12 +522,10 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
|
luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
|
||||||
luaK_patchtohere(fs, e->t);
|
|
||||||
e->t = NO_JUMP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void luaK_goiffalse (FuncState *fs, expdesc *e) {
|
void luaK_goiffalse (FuncState *fs, expdesc *e) {
|
||||||
int pc; /* pc of last jump */
|
int pc; /* pc of last jump */
|
||||||
luaK_dischargevars(fs, e);
|
luaK_dischargevars(fs, e);
|
||||||
switch (e->k) {
|
switch (e->k) {
|
||||||
|
@ -542,8 +547,6 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
|
luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
|
||||||
luaK_patchtohere(fs, e->f);
|
|
||||||
e->f = NO_JUMP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -607,10 +610,14 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case OPR_AND: {
|
case OPR_AND: {
|
||||||
luaK_goiftrue(fs, v);
|
luaK_goiftrue(fs, v);
|
||||||
|
luaK_patchtohere(fs, v->t);
|
||||||
|
v->t = NO_JUMP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPR_OR: {
|
case OPR_OR: {
|
||||||
luaK_goiffalse(fs, v);
|
luaK_goiffalse(fs, v);
|
||||||
|
luaK_patchtohere(fs, v->f);
|
||||||
|
v->f = NO_JUMP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPR_CONCAT: {
|
case OPR_CONCAT: {
|
||||||
|
@ -727,7 +734,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int luaK_code (FuncState *fs, Instruction i) {
|
int luaK_code (FuncState *fs, Instruction i, int line) {
|
||||||
Proto *f = fs->f;
|
Proto *f = fs->f;
|
||||||
int oldsize = f->sizecode;
|
int oldsize = f->sizecode;
|
||||||
/* put new instruction in code array */
|
/* put new instruction in code array */
|
||||||
|
@ -736,19 +743,19 @@ static int luaK_code (FuncState *fs, Instruction i) {
|
||||||
f->code[fs->pc] = i;
|
f->code[fs->pc] = i;
|
||||||
if (f->sizecode != oldsize)
|
if (f->sizecode != oldsize)
|
||||||
luaM_reallocvector(fs->L, f->lineinfo, oldsize, f->sizecode, int);
|
luaM_reallocvector(fs->L, f->lineinfo, oldsize, f->sizecode, int);
|
||||||
f->lineinfo[fs->pc] = fs->ls->lastline;
|
f->lineinfo[fs->pc] = line;
|
||||||
return fs->pc++;
|
return fs->pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
|
int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
|
||||||
lua_assert(getOpMode(o) == iABC);
|
lua_assert(getOpMode(o) == iABC);
|
||||||
return luaK_code(fs, CREATE_ABC(o, a, b, c));
|
return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
|
int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
|
||||||
lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
|
lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
|
||||||
return luaK_code(fs, CREATE_ABx(o, a, bc));
|
return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
lcode.h
5
lcode.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lcode.h,v 1.32 2002/04/24 20:07:46 roberto Exp roberto $
|
** $Id: lcode.h,v 1.33 2002/05/07 17:36:56 roberto Exp roberto $
|
||||||
** Code generator for Lua
|
** Code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -41,6 +41,7 @@ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;
|
||||||
|
|
||||||
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
|
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
|
||||||
|
|
||||||
|
int luaK_code (FuncState *fs, Instruction i, int line);
|
||||||
int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
|
int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
|
||||||
int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
|
int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
|
||||||
void luaK_nil (FuncState *fs, int from, int n);
|
void luaK_nil (FuncState *fs, int from, int n);
|
||||||
|
@ -54,7 +55,9 @@ void luaK_exp2val (FuncState *fs, expdesc *e);
|
||||||
int luaK_exp2RK (FuncState *fs, expdesc *e);
|
int luaK_exp2RK (FuncState *fs, expdesc *e);
|
||||||
void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
|
void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
|
||||||
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
|
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
|
||||||
|
void luaK_moveexp (expdesc *e, int offset);
|
||||||
void luaK_goiftrue (FuncState *fs, expdesc *e);
|
void luaK_goiftrue (FuncState *fs, expdesc *e);
|
||||||
|
void luaK_goiffalse (FuncState *fs, expdesc *e);
|
||||||
void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
|
void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
|
||||||
void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults);
|
void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults);
|
||||||
int luaK_jump (FuncState *fs);
|
int luaK_jump (FuncState *fs);
|
||||||
|
|
47
lparser.c
47
lparser.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 1.178 2002/04/24 20:07:46 roberto Exp roberto $
|
** $Id: lparser.c,v 1.179 2002/05/07 17:36:56 roberto Exp roberto $
|
||||||
** Lua Parser
|
** Lua Parser
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -946,22 +946,61 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
|
||||||
static void cond (LexState *ls, expdesc *v) {
|
static void cond (LexState *ls, expdesc *v) {
|
||||||
/* cond -> exp */
|
/* cond -> exp */
|
||||||
expr(ls, v); /* read condition */
|
expr(ls, v); /* read condition */
|
||||||
|
if (v->k == VNIL) v->k = VFALSE; /* `falses' are all equal here */
|
||||||
luaK_goiftrue(ls->fs, v);
|
luaK_goiftrue(ls->fs, v);
|
||||||
|
luaK_patchtohere(ls->fs, v->t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The while statement optimizes its code by coding the condition
|
||||||
|
** after its body (and thus avoiding one jump in the loop).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** maximum size of expressions for optimizing `while' code
|
||||||
|
*/
|
||||||
|
#ifndef MAXEXPWHILE
|
||||||
|
#define MAXEXPWHILE 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** the call `luaK_goiffalse' may grow the size of an expression by
|
||||||
|
** at most this:
|
||||||
|
*/
|
||||||
|
#define EXTRAEXP 5
|
||||||
|
|
||||||
static void whilestat (LexState *ls, int line) {
|
static void whilestat (LexState *ls, int line) {
|
||||||
/* whilestat -> WHILE cond DO block END */
|
/* whilestat -> WHILE cond DO block END */
|
||||||
|
Instruction codeexp[MAXEXPWHILE + EXTRAEXP];
|
||||||
|
int lineexp = 0;
|
||||||
|
int i;
|
||||||
|
int sizeexp;
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
int while_init = luaK_getlabel(fs);
|
int while_init = luaK_getlabel(fs);
|
||||||
expdesc v;
|
expdesc v;
|
||||||
BlockCnt bl;
|
BlockCnt bl;
|
||||||
enterblock(fs, &bl, 1);
|
|
||||||
next(ls);
|
next(ls);
|
||||||
cond(ls, &v);
|
expr(ls, &v);
|
||||||
|
if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */
|
||||||
|
lineexp = ls->linenumber;
|
||||||
|
luaK_goiffalse(fs, &v);
|
||||||
|
sizeexp = fs->pc - while_init;
|
||||||
|
if (sizeexp > MAXEXPWHILE)
|
||||||
|
luaX_syntaxerror(ls, "while condition too complex");
|
||||||
|
fs->pc = while_init; /* remove `exp' code */
|
||||||
|
luaK_getlabel(fs);
|
||||||
|
for (i = 0; i < sizeexp; i++) /* save `exp' code */
|
||||||
|
codeexp[i] = fs->f->code[while_init + i];
|
||||||
|
luaK_jump(fs);
|
||||||
|
enterblock(fs, &bl, 1);
|
||||||
check(ls, TK_DO);
|
check(ls, TK_DO);
|
||||||
block(ls);
|
block(ls);
|
||||||
luaK_patchlist(fs, luaK_jump(fs), while_init);
|
luaK_patchtohere(fs, while_init); /* initial jump jumps to here */
|
||||||
|
luaK_moveexp(&v, fs->pc - while_init); /* correct pointers */
|
||||||
|
for (i=0; i<sizeexp; i++)
|
||||||
|
luaK_code(fs, codeexp[i], lineexp);
|
||||||
|
luaK_patchlist(fs, v.t, while_init+1);
|
||||||
luaK_patchtohere(fs, v.f);
|
luaK_patchtohere(fs, v.f);
|
||||||
check_match(ls, TK_END, TK_WHILE, line);
|
check_match(ls, TK_END, TK_WHILE, line);
|
||||||
leaveblock(fs);
|
leaveblock(fs);
|
||||||
|
|
Loading…
Reference in New Issue