aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-08 21:19:22 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-08 21:19:22 -0300
commit88b306f495fa7034c708c6b75a355a6deee51c58 (patch)
tree7d8faaacd1f5c753ed9e77f0e2c8e27b9a002635 /lvm.c
parent563de491be90601f23a735aede89ea9a3ef86ee9 (diff)
downloadlua-88b306f495fa7034c708c6b75a355a6deee51c58.tar.gz
lua-88b306f495fa7034c708c6b75a355a6deee51c58.tar.bz2
lua-88b306f495fa7034c708c6b75a355a6deee51c58.zip
some optimizations
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c76
1 files changed, 43 insertions, 33 deletions
diff --git a/lvm.c b/lvm.c
index 819e9a0e..4a24c43a 100644
--- a/lvm.c
+++ b/lvm.c
@@ -39,17 +39,6 @@
39 39
40 40
41 41
42static TaggedString *strconc (lua_State *L, const TaggedString *l,
43 const TaggedString *r) {
44 long nl = l->u.s.len;
45 long nr = r->u.s.len;
46 char *buffer = luaL_openspace(L, nl+nr);
47 memcpy(buffer, l->str, nl);
48 memcpy(buffer+nl, r->str, nr);
49 return luaS_newlstr(L, buffer, nl+nr);
50}
51
52
53int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */ 42int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */
54 if (ttype(obj) != LUA_T_STRING) 43 if (ttype(obj) != LUA_T_STRING)
55 return 1; 44 return 1;
@@ -253,22 +242,16 @@ static int luaV_strcomp (const TaggedString *ls, const TaggedString *rs) {
253} 242}
254 243
255 244
256int luaV_lessthan (lua_State *L, TObject *l, TObject *r) { 245int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) {
257 if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) 246 if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
258 return (nvalue(l) < nvalue(r)); 247 return (nvalue(l) < nvalue(r));
259 else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING) 248 else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
260 return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0); 249 return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0);
261 else { 250 else { /* call TM */
262 /* update top and put arguments in correct order to call TM */ 251 luaD_checkstack(L, 2);
263 if (l<r) /* are arguments in correct order? */ 252 *top++ = *l;
264 L->top = r+1; /* yes; 2nd is on top */ 253 *top++ = *r;
265 else { /* no; exchange them */ 254 call_binTM(L, top, IM_LT, "unexpected type in comparison");
266 TObject temp = *r;
267 *r = *l;
268 *l = temp;
269 L->top = l+1; /* 1st is on top */
270 }
271 call_binTM(L, L->top, IM_LT, "unexpected type in comparison");
272 L->top--; 255 L->top--;
273 return (ttype(L->top) != LUA_T_NIL); 256 return (ttype(L->top) != LUA_T_NIL);
274 } 257 }
@@ -280,6 +263,34 @@ int luaV_lessthan (lua_State *L, TObject *l, TObject *r) {
280 else ttype(o) = LUA_T_NIL 263 else ttype(o) = LUA_T_NIL
281 264
282 265
266static void strconc (lua_State *L, int total, StkId top) {
267 do {
268 int n = 2; /* number of elements handled in this pass (at least 2) */
269 if (tostring(L, top-2) || tostring(L, top-1))
270 call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation");
271 else { /* at least two string values; get as many as possible */
272 long tl = tsvalue(top-2)->u.s.len + tsvalue(top-1)->u.s.len;
273 char *buffer;
274 int i;
275 while (n < total && !tostring(L, top-n-1)) { /* collect total length */
276 tl += tsvalue(top-n-1)->u.s.len;
277 n++;
278 }
279 buffer = luaL_openspace(L, tl);
280 tl = 0;
281 for (i=n; i>0; i--) { /* concat all strings */
282 long l = tsvalue(top-i)->u.s.len;
283 memcpy(buffer+tl, tsvalue(top-i)->str, l);
284 tl += l;
285 }
286 tsvalue(top-n) = luaS_newlstr(L, buffer, tl);
287 }
288 total -= n-1; /* got `n' strings to create 1 new */
289 top -= n-1;
290 } while (total > 1); /* repeat until only 1 result left */
291}
292
293
283void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) { 294void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) {
284 int i; 295 int i;
285 Hash *htab; 296 Hash *htab;
@@ -479,22 +490,22 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
479 490
480 case LTOP: 491 case LTOP:
481 top--; 492 top--;
482 setbool(top-1, luaV_lessthan(L, top-1, top)); 493 setbool(top-1, luaV_lessthan(L, top-1, top, top+1));
483 break; 494 break;
484 495
485 case LEOP: /* a <= b === !(b<a) */ 496 case LEOP: /* a <= b === !(b<a) */
486 top--; 497 top--;
487 setbool(top-1, !luaV_lessthan(L, top, top-1)); 498 setbool(top-1, !luaV_lessthan(L, top, top-1, top+1));
488 break; 499 break;
489 500
490 case GTOP: /* a > b === (b<a) */ 501 case GTOP: /* a > b === (b<a) */
491 top--; 502 top--;
492 setbool(top-1, luaV_lessthan(L, top, top-1)); 503 setbool(top-1, luaV_lessthan(L, top, top-1, top+1));
493 break; 504 break;
494 505
495 case GEOP: /* a >= b === !(a<b) */ 506 case GEOP: /* a >= b === !(a<b) */
496 top--; 507 top--;
497 setbool(top-1, !luaV_lessthan(L, top-1, top)); 508 setbool(top-1, !luaV_lessthan(L, top-1, top, top+1));
498 break; 509 break;
499 510
500 case ADDOP: 511 case ADDOP:
@@ -544,15 +555,14 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
544 top--; 555 top--;
545 break; 556 break;
546 557
547 case CONCOP: 558 case CONCOP: {
548 if (tostring(L, top-2) || tostring(L, top-1)) 559 int n = GETARG_U(i);
549 call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation"); 560 strconc(L, n, top);
550 else 561 top -= n-1;
551 tsvalue(top-2) = strconc(L, tsvalue(top-2), tsvalue(top-1));
552 top--;
553 L->top = top; 562 L->top = top;
554 luaC_checkGC(L); 563 luaC_checkGC(L);
555 break; 564 break;
565 }
556 566
557 case MINUSOP: 567 case MINUSOP:
558 if (tonumber(top-1)) { 568 if (tonumber(top-1)) {