diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-08 21:19:22 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-08 21:19:22 -0300 |
commit | 88b306f495fa7034c708c6b75a355a6deee51c58 (patch) | |
tree | 7d8faaacd1f5c753ed9e77f0e2c8e27b9a002635 /lvm.c | |
parent | 563de491be90601f23a735aede89ea9a3ef86ee9 (diff) | |
download | lua-88b306f495fa7034c708c6b75a355a6deee51c58.tar.gz lua-88b306f495fa7034c708c6b75a355a6deee51c58.tar.bz2 lua-88b306f495fa7034c708c6b75a355a6deee51c58.zip |
some optimizations
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 76 |
1 files changed, 43 insertions, 33 deletions
@@ -39,17 +39,6 @@ | |||
39 | 39 | ||
40 | 40 | ||
41 | 41 | ||
42 | static 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 | |||
53 | int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */ | 42 | int 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 | ||
256 | int luaV_lessthan (lua_State *L, TObject *l, TObject *r) { | 245 | int 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 | ||
266 | static 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 | |||
283 | void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) { | 294 | void 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)) { |