some optimizations

This commit is contained in:
Roberto Ierusalimschy
2000-03-08 21:19:22 -03:00
parent 563de491be
commit 88b306f495
6 changed files with 105 additions and 75 deletions

76
lvm.c
View File

@@ -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)) {