aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
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 */