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