| 276 | |
| 277 | |
| 278 | void luaV_concat (lua_State *L, int total, int last) { |
| 279 | do { |
| 280 | StkId top = L->base + last + 1; |
| 281 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
| 282 | if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { |
| 283 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) |
| 284 | luaG_concaterror(L, top-2, top-1); |
| 285 | } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ |
| 286 | (void)tostring(L, top - 2); /* result is first op (as string) */ |
| 287 | else { |
| 288 | /* at least two string values; get as many as possible */ |
| 289 | size_t tl = tsvalue(top-1)->len; |
| 290 | char *buffer; |
| 291 | int i; |
| 292 | /* collect total length */ |
| 293 | for (n = 1; n < total && tostring(L, top-n-1); n++) { |
| 294 | size_t l = tsvalue(top-n-1)->len; |
| 295 | if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); |
| 296 | tl += l; |
| 297 | } |
| 298 | buffer = luaZ_openspace(L, &G(L)->buff, tl); |
| 299 | tl = 0; |
| 300 | for (i=n; i>0; i--) { /* concat all strings */ |
| 301 | size_t l = tsvalue(top-i)->len; |
| 302 | memcpy(buffer+tl, svalue(top-i), l); |
| 303 | tl += l; |
| 304 | } |
| 305 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); |
| 306 | } |
| 307 | total -= n-1; /* got `n' strings to create 1 new */ |
| 308 | last -= n-1; |
| 309 | } while (total > 1); /* repeat until only 1 result left */ |
| 310 | } |
| 311 | |
| 312 | |
| 313 | static void Arith (lua_State *L, StkId ra, const TValue *rb, |
no test coverage detected