| 322 | |
| 323 | |
| 324 | void luaV_concat (lua_State *L, int total, int last) { |
| 325 | do { |
| 326 | StkId top = L->base + last + 1; |
| 327 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
| 328 | if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { |
| 329 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) |
| 330 | luaG_concaterror(L, top-2, top-1); |
| 331 | } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ |
| 332 | (void)tostring(L, top - 2); /* result is first op (as string) */ |
| 333 | else { |
| 334 | /* at least two string values; get as many as possible */ |
| 335 | size_t tl = tsvalue(top-1)->len; |
| 336 | char *buffer; |
| 337 | int i; |
| 338 | /* collect total length */ |
| 339 | for (n = 1; n < total && tostring(L, top-n-1); n++) { |
| 340 | size_t l = tsvalue(top-n-1)->len; |
| 341 | if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); |
| 342 | tl += l; |
| 343 | } |
| 344 | buffer = luaZ_openspace(L, &G(L)->buff, tl); |
| 345 | tl = 0; |
| 346 | for (i=n; i>0; i--) { /* concat all strings */ |
| 347 | size_t l = tsvalue(top-i)->len; |
| 348 | memcpy(buffer+tl, svalue(top-i), l); |
| 349 | tl += l; |
| 350 | } |
| 351 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); |
| 352 | } |
| 353 | total -= n-1; /* got `n' strings to create 1 new */ |
| 354 | last -= n-1; |
| 355 | } while (total > 1); /* repeat until only 1 result left */ |
| 356 | } |
| 357 | |
| 358 | |
| 359 | static void Arith (lua_State *L, StkId ra, const TValue *rb, |
no test coverage detected