mirror of
https://github.com/lua/lua
synced 2024-11-22 12:51:30 +03:00
some optimizations
This commit is contained in:
parent
563de491be
commit
88b306f495
11
lbuiltin.c
11
lbuiltin.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lbuiltin.c,v 1.93 2000/02/22 18:12:46 roberto Exp roberto $
|
||||
** $Id: lbuiltin.c,v 1.94 2000/03/03 14:58:26 roberto Exp $
|
||||
** Built-in functions
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -553,13 +553,8 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a,
|
||||
L->top--;
|
||||
return (ttype(L->top) != LUA_T_NIL);
|
||||
}
|
||||
else { /* a < b? */
|
||||
int res;
|
||||
*(L->top) = *a;
|
||||
*(L->top+1) = *b;
|
||||
res = luaV_lessthan(L, L->top, L->top+1);
|
||||
return res;
|
||||
}
|
||||
else /* a < b? */
|
||||
return luaV_lessthan(L, a, b, L->top);
|
||||
}
|
||||
|
||||
static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
|
||||
|
12
lcode.c
12
lcode.c
@ -88,6 +88,16 @@ static void luaK_sub (LexState *ls) {
|
||||
}
|
||||
|
||||
|
||||
static void luaK_conc (LexState *ls) {
|
||||
Instruction *previous = previous_instruction(ls);
|
||||
luaK_deltastack(ls, -1);
|
||||
switch(GET_OPCODE(*previous)) {
|
||||
case CONCOP: *previous = SETARG_U(*previous, GETARG_U(*previous)+1); break;
|
||||
default: luaK_primitivecode(ls, CREATE_U(CONCOP, 2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaK_retcode (LexState *ls, int nlocals, int nexps) {
|
||||
Instruction *previous = previous_instruction(ls);
|
||||
if (nexps > 0 && GET_OPCODE(*previous) == CALL) {
|
||||
@ -286,7 +296,7 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) {
|
||||
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 CONC: luaK_conc(ls); break;
|
||||
case EQ: luaK_0(ls, EQOP, -1); break;
|
||||
case NE: luaK_0(ls, NEQOP, -1); break;
|
||||
case '>': luaK_0(ls, GTOP, -1); break;
|
||||
|
57
lopcodes.h
57
lopcodes.h
@ -24,34 +24,51 @@
|
||||
is the usigned value minus 2^23.
|
||||
===========================================================================*/
|
||||
|
||||
#define EXCESS_S (1<<23) /* == 2^23 */
|
||||
#define SIZE_OP 8
|
||||
#define SIZE_U 24
|
||||
#define POS_U 8
|
||||
#define SIZE_S 24
|
||||
#define POS_S 8
|
||||
#define SIZE_A 16
|
||||
#define POS_A 16
|
||||
#define SIZE_B 8
|
||||
#define POS_B 8
|
||||
|
||||
#define EXCESS_S (1<<(SIZE_S-1)) /* == 2^23 */
|
||||
|
||||
|
||||
/* creates a mask with `n' 1 bits at position `p' */
|
||||
#define MASK1(n,p) ((~((~0ul)<<n))<<p)
|
||||
|
||||
/* creates a mask with `n' 0 bits at position `p' */
|
||||
#define MASK0(n,p) (~MASK1(n,p))
|
||||
|
||||
/*
|
||||
** the following macros help to manipulate instructions
|
||||
*/
|
||||
|
||||
#define MAXARG_U ((1<<24)-1)
|
||||
#define MAXARG_S ((1<<23)-1)
|
||||
#define MAXARG_A ((1<<16)-1)
|
||||
#define MAXARG_B ((1<<8)-1)
|
||||
#define MAXARG_U ((1<<SIZE_U)-1)
|
||||
#define MAXARG_S ((1<<(SIZE_S-1))-1) /* `S' is signed */
|
||||
#define MAXARG_A ((1<<SIZE_A)-1)
|
||||
#define MAXARG_B ((1<<SIZE_B)-1)
|
||||
|
||||
#define GET_OPCODE(i) ((OpCode)((i)&0xFF))
|
||||
#define GETARG_U(i) ((int)((i)>>8))
|
||||
#define GETARG_S(i) ((int)((i)>>8)-EXCESS_S)
|
||||
#define GETARG_A(i) ((int)((i)>>16))
|
||||
#define GETARG_B(i) ((int)(((i)>>8) & 0xFF))
|
||||
#define GET_OPCODE(i) ((OpCode)((i)&MASK1(SIZE_OP,0)))
|
||||
#define GETARG_U(i) ((int)((i)>>POS_U))
|
||||
#define GETARG_S(i) ((int)((i)>>POS_S)-EXCESS_S)
|
||||
#define GETARG_A(i) ((int)((i)>>POS_A))
|
||||
#define GETARG_B(i) ((int)(((i)>>POS_B) & MASK1(SIZE_B,0)))
|
||||
|
||||
#define SET_OPCODE(i,o) (((i)&0xFFFFFF00u) | (Instruction)(o))
|
||||
#define SETARG_U(i,u) (((i)&0x000000FFu) | ((Instruction)(u)<<8))
|
||||
#define SETARG_S(i,s) (((i)&0x000000FFu) | ((Instruction)((s)+EXCESS_S)<<8))
|
||||
#define SETARG_A(i,a) (((i)&0x0000FFFFu) | ((Instruction)(a)<<16))
|
||||
#define SETARG_B(i,b) (((i)&0xFFFF00FFu) | ((Instruction)(b)<<8))
|
||||
#define SET_OPCODE(i,o) (((i)&MASK0(SIZE_OP,0)) | (Instruction)(o))
|
||||
#define SETARG_U(i,u) (((i)&MASK0(SIZE_U,POS_U)) | ((Instruction)(u)<<POS_U))
|
||||
#define SETARG_S(i,s) (((i)&MASK0(SIZE_S,POS_S)) | ((Instruction)((s)+EXCESS_S)<<POS_S))
|
||||
#define SETARG_A(i,a) (((i)&MASK0(SIZE_A,POS_A)) | ((Instruction)(a)<<POS_A))
|
||||
#define SETARG_B(i,b) (((i)&MASK0(SIZE_B,POS_B)) | ((Instruction)(b)<<POS_B))
|
||||
|
||||
#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))
|
||||
#define CREATE_U(o,u) ((Instruction)(o) | (Instruction)(u)<<POS_U)
|
||||
#define CREATE_S(o,s) ((Instruction)(o) | ((Instruction)(s)+EXCESS_S)<<POS_S)
|
||||
#define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<POS_A) \
|
||||
| ((Instruction)(b)<<POS_B))
|
||||
|
||||
|
||||
/*
|
||||
@ -111,7 +128,7 @@ SUBOP,/* - y x x-y */
|
||||
MULTOP,/* - y x x*y */
|
||||
DIVOP,/* - y x x/y */
|
||||
POWOP,/* - y x x^y */
|
||||
CONCOP,/* - y x x..y */
|
||||
CONCOP,/* U v_u-v_1 v1..-..v_u */
|
||||
MINUSOP,/* - x -x */
|
||||
NOTOP,/* - x (x==nil)? 1 : nil */
|
||||
|
||||
|
20
lparser.c
20
lparser.c
@ -716,7 +716,7 @@ static int get_priority (int op, int *rp) {
|
||||
|
||||
case '+': case '-': *rp = 5; return 5;
|
||||
|
||||
case CONC: *rp = 4; return 4; /* left associative (?) */
|
||||
case CONC: *rp = 3; return 4; /* right associative (?) */
|
||||
|
||||
case EQ: case NE: case '>': case '<': case LE: case GE:
|
||||
*rp = 2; return 2;
|
||||
@ -941,18 +941,17 @@ static void namestat (LexState *ls) {
|
||||
|
||||
|
||||
static void ifpart (LexState *ls, int line) {
|
||||
/* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */
|
||||
/* ifpart -> cond THEN block (ELSEIF ifpart | [ELSE block] END) */
|
||||
FuncState *fs = ls->fs;
|
||||
int c; /* address of the conditional jump */
|
||||
int je; /* address of the unconditional jump (to skip `else' part) */
|
||||
int elseinit;
|
||||
next(ls); /* skip IF or ELSEIF */
|
||||
exp1(ls); /* cond */
|
||||
c = luaK_S(ls, IFFJMP, 0, -1); /* jump over `then' part if `cond' is false */
|
||||
c = luaK_S(ls, IFFJMP, 0, -1); /* 1st jump: over `then' part */
|
||||
check(ls, THEN);
|
||||
block(ls); /* `then' part */
|
||||
je = luaK_S(ls, JMP, 0, 0); /* jump over `else' part after `then' */
|
||||
elseinit = luaK_getlabel(ls);
|
||||
luaK_S(ls, JMP, 0, 0); /* 2nd jump: over `else' part */
|
||||
elseinit = luaK_getlabel(ls); /* address of 2nd jump == elseinit-1 */
|
||||
if (ls->token == ELSEIF)
|
||||
ifpart(ls, line);
|
||||
else {
|
||||
@ -961,13 +960,12 @@ static void ifpart (LexState *ls, int line) {
|
||||
check_match(ls, END, IF, line);
|
||||
}
|
||||
if (fs->pc > elseinit) { /* is there an `else' part? */
|
||||
luaK_fixjump(ls, je, luaK_getlabel(ls)); /* last jump jumps over it */
|
||||
luaK_fixjump(ls, c, elseinit); /* fix first jump to `else' part */
|
||||
luaK_fixjump(ls, c, elseinit); /* fix 1st jump to `else' part */
|
||||
luaK_fixjump(ls, elseinit-1, luaK_getlabel(ls)); /* fix 2nd jump */
|
||||
}
|
||||
else { /* no else part */
|
||||
fs->pc--; /* remove last jump */
|
||||
LUA_ASSERT(L, fs->pc == je, "jump out of place");
|
||||
luaK_fixjump(ls, c, luaK_getlabel(ls)); /* fix first jump to `if' end */
|
||||
fs->pc--; /* remove 2nd jump */
|
||||
luaK_fixjump(ls, c, luaK_getlabel(ls)); /* fix 1st jump to `if' end */
|
||||
}
|
||||
}
|
||||
|
||||
|
76
lvm.c
76
lvm.c
@ -39,17 +39,6 @@
|
||||
|
||||
|
||||
|
||||
static TaggedString *strconc (lua_State *L, const TaggedString *l,
|
||||
const TaggedString *r) {
|
||||
long nl = l->u.s.len;
|
||||
long nr = r->u.s.len;
|
||||
char *buffer = luaL_openspace(L, nl+nr);
|
||||
memcpy(buffer, l->str, nl);
|
||||
memcpy(buffer+nl, r->str, nr);
|
||||
return luaS_newlstr(L, buffer, nl+nr);
|
||||
}
|
||||
|
||||
|
||||
int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */
|
||||
if (ttype(obj) != LUA_T_STRING)
|
||||
return 1;
|
||||
@ -253,22 +242,16 @@ static int luaV_strcomp (const TaggedString *ls, const TaggedString *rs) {
|
||||
}
|
||||
|
||||
|
||||
int luaV_lessthan (lua_State *L, TObject *l, TObject *r) {
|
||||
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) {
|
||||
if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
|
||||
return (nvalue(l) < nvalue(r));
|
||||
else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
|
||||
return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0);
|
||||
else {
|
||||
/* update top and put arguments in correct order to call TM */
|
||||
if (l<r) /* are arguments in correct order? */
|
||||
L->top = r+1; /* yes; 2nd is on top */
|
||||
else { /* no; exchange them */
|
||||
TObject temp = *r;
|
||||
*r = *l;
|
||||
*l = temp;
|
||||
L->top = l+1; /* 1st is on top */
|
||||
}
|
||||
call_binTM(L, L->top, IM_LT, "unexpected type in comparison");
|
||||
else { /* call TM */
|
||||
luaD_checkstack(L, 2);
|
||||
*top++ = *l;
|
||||
*top++ = *r;
|
||||
call_binTM(L, top, IM_LT, "unexpected type in comparison");
|
||||
L->top--;
|
||||
return (ttype(L->top) != LUA_T_NIL);
|
||||
}
|
||||
@ -280,6 +263,34 @@ int luaV_lessthan (lua_State *L, TObject *l, TObject *r) {
|
||||
else ttype(o) = LUA_T_NIL
|
||||
|
||||
|
||||
static void strconc (lua_State *L, int total, StkId top) {
|
||||
do {
|
||||
int n = 2; /* number of elements handled in this pass (at least 2) */
|
||||
if (tostring(L, top-2) || tostring(L, top-1))
|
||||
call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation");
|
||||
else { /* at least two string values; get as many as possible */
|
||||
long tl = tsvalue(top-2)->u.s.len + tsvalue(top-1)->u.s.len;
|
||||
char *buffer;
|
||||
int i;
|
||||
while (n < total && !tostring(L, top-n-1)) { /* collect total length */
|
||||
tl += tsvalue(top-n-1)->u.s.len;
|
||||
n++;
|
||||
}
|
||||
buffer = luaL_openspace(L, tl);
|
||||
tl = 0;
|
||||
for (i=n; i>0; i--) { /* concat all strings */
|
||||
long l = tsvalue(top-i)->u.s.len;
|
||||
memcpy(buffer+tl, tsvalue(top-i)->str, l);
|
||||
tl += l;
|
||||
}
|
||||
tsvalue(top-n) = luaS_newlstr(L, buffer, tl);
|
||||
}
|
||||
total -= n-1; /* got `n' strings to create 1 new */
|
||||
top -= n-1;
|
||||
} while (total > 1); /* repeat until only 1 result left */
|
||||
}
|
||||
|
||||
|
||||
void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) {
|
||||
int i;
|
||||
Hash *htab;
|
||||
@ -479,22 +490,22 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
|
||||
|
||||
case LTOP:
|
||||
top--;
|
||||
setbool(top-1, luaV_lessthan(L, top-1, top));
|
||||
setbool(top-1, luaV_lessthan(L, top-1, top, top+1));
|
||||
break;
|
||||
|
||||
case LEOP: /* a <= b === !(b<a) */
|
||||
top--;
|
||||
setbool(top-1, !luaV_lessthan(L, top, top-1));
|
||||
setbool(top-1, !luaV_lessthan(L, top, top-1, top+1));
|
||||
break;
|
||||
|
||||
case GTOP: /* a > b === (b<a) */
|
||||
top--;
|
||||
setbool(top-1, luaV_lessthan(L, top, top-1));
|
||||
setbool(top-1, luaV_lessthan(L, top, top-1, top+1));
|
||||
break;
|
||||
|
||||
case GEOP: /* a >= b === !(a<b) */
|
||||
top--;
|
||||
setbool(top-1, !luaV_lessthan(L, top-1, top));
|
||||
setbool(top-1, !luaV_lessthan(L, top-1, top, top+1));
|
||||
break;
|
||||
|
||||
case ADDOP:
|
||||
@ -544,15 +555,14 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
|
||||
top--;
|
||||
break;
|
||||
|
||||
case CONCOP:
|
||||
if (tostring(L, top-2) || tostring(L, top-1))
|
||||
call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation");
|
||||
else
|
||||
tsvalue(top-2) = strconc(L, tsvalue(top-2), tsvalue(top-1));
|
||||
top--;
|
||||
case CONCOP: {
|
||||
int n = GETARG_U(i);
|
||||
strconc(L, n, top);
|
||||
top -= n-1;
|
||||
L->top = top;
|
||||
luaC_checkGC(L);
|
||||
break;
|
||||
}
|
||||
|
||||
case MINUSOP:
|
||||
if (tonumber(top-1)) {
|
||||
|
4
lvm.h
4
lvm.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lvm.h,v 1.16 2000/02/22 18:12:46 roberto Exp roberto $
|
||||
** $Id: lvm.h,v 1.17 2000/03/03 14:58:26 roberto Exp $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -28,6 +28,6 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top);
|
||||
void luaV_setglobal (lua_State *L, GlobalVar *gv, StkId top);
|
||||
StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base);
|
||||
void luaV_closure (lua_State *L, int nelems);
|
||||
int luaV_lessthan (lua_State *L, TObject *l, TObject *r);
|
||||
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user