diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-09-08 12:41:05 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-09-08 12:41:05 -0300 |
commit | 41964648eea1427d53934b886abb68cc8457b019 (patch) | |
tree | b0388dfebe6614d5d49306193faf78f8b9e1a6a1 /lvm.c | |
parent | 502214f8a551cd01d94677f98a40aa51531ef71d (diff) | |
download | lua-41964648eea1427d53934b886abb68cc8457b019.tar.gz lua-41964648eea1427d53934b886abb68cc8457b019.tar.bz2 lua-41964648eea1427d53934b886abb68cc8457b019.zip |
long strings are created directly in final position when possible
(instead of using an auxiliar buffer to first create the string
and then allocate the final string and copy result there)
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 41 |
1 files changed, 26 insertions, 15 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.249 2015/08/03 19:50:49 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.250 2015/08/03 20:40:26 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -445,6 +445,17 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { | |||
445 | 445 | ||
446 | #define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0) | 446 | #define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0) |
447 | 447 | ||
448 | /* copy strings in stack from top - n up to top - 1 to buffer */ | ||
449 | static void copy2buff (StkId top, int n, char *buff) { | ||
450 | size_t tl = 0; /* size already copied */ | ||
451 | do { | ||
452 | size_t l = vslen(top - n); /* length of string being copied */ | ||
453 | memcpy(buff + tl, svalue(top - n), l * sizeof(char)); | ||
454 | tl += l; | ||
455 | } while (--n > 0); | ||
456 | } | ||
457 | |||
458 | |||
448 | /* | 459 | /* |
449 | ** Main operation for concatenation: concat 'total' values in the stack, | 460 | ** Main operation for concatenation: concat 'total' values in the stack, |
450 | ** from 'L->top - total' up to 'L->top - 1'. | 461 | ** from 'L->top - total' up to 'L->top - 1'. |
@@ -464,24 +475,24 @@ void luaV_concat (lua_State *L, int total) { | |||
464 | else { | 475 | else { |
465 | /* at least two non-empty string values; get as many as possible */ | 476 | /* at least two non-empty string values; get as many as possible */ |
466 | size_t tl = vslen(top - 1); | 477 | size_t tl = vslen(top - 1); |
467 | char *buffer; | 478 | TString *ts; |
468 | int i; | 479 | /* collect total length and number of strings */ |
469 | /* collect total length */ | 480 | for (n = 1; n < total && tostring(L, top - n - 1); n++) { |
470 | for (i = 1; i < total && tostring(L, top-i-1); i++) { | 481 | size_t l = vslen(top - n - 1); |
471 | size_t l = vslen(top - i - 1); | ||
472 | if (l >= (MAX_SIZE/sizeof(char)) - tl) | 482 | if (l >= (MAX_SIZE/sizeof(char)) - tl) |
473 | luaG_runerror(L, "string length overflow"); | 483 | luaG_runerror(L, "string length overflow"); |
474 | tl += l; | 484 | tl += l; |
475 | } | 485 | } |
476 | buffer = luaZ_openspace(L, &G(L)->buff, tl); | 486 | if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ |
477 | tl = 0; | 487 | char buff[LUAI_MAXSHORTLEN]; |
478 | n = i; | 488 | copy2buff(top, n, buff); /* copy strings to buffer */ |
479 | do { /* copy all strings to buffer */ | 489 | ts = luaS_newlstr(L, buff, tl); |
480 | size_t l = vslen(top - i); | 490 | } |
481 | memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); | 491 | else { /* long string; copy strings directly to final result */ |
482 | tl += l; | 492 | ts = luaS_createlngstrobj(L, tl); |
483 | } while (--i > 0); | 493 | copy2buff(top, n, getaddrstr(ts)); |
484 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); /* create result */ | 494 | } |
495 | setsvalue2s(L, top - n, ts); /* create result */ | ||
485 | } | 496 | } |
486 | total -= n-1; /* got 'n' strings to create 1 new */ | 497 | total -= n-1; /* got 'n' strings to create 1 new */ |
487 | L->top -= n-1; /* popped 'n' strings and pushed one */ | 498 | L->top -= n-1; /* popped 'n' strings and pushed one */ |