aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-09-08 12:41:05 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-09-08 12:41:05 -0300
commit41964648eea1427d53934b886abb68cc8457b019 (patch)
treeb0388dfebe6614d5d49306193faf78f8b9e1a6a1 /lvm.c
parent502214f8a551cd01d94677f98a40aa51531ef71d (diff)
downloadlua-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.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/lvm.c b/lvm.c
index 6a6710b3..59f36e3a 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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 */
449static 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 */