diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-04-25 13:26:20 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-04-25 13:26:20 -0300 |
| commit | deb807837c1ed327d6069fb6676e624784d01e22 (patch) | |
| tree | 65ae02ce78887eb04beb801a6c34c55d835df46a | |
| parent | 26eb144541714343f8aeb124150d60cf7d91fac7 (diff) | |
| download | lua-deb807837c1ed327d6069fb6676e624784d01e22.tar.gz lua-deb807837c1ed327d6069fb6676e624784d01e22.tar.bz2 lua-deb807837c1ed327d6069fb6676e624784d01e22.zip | |
'luaO_pushvfstring' does not need to reallocate stack
(less error cases in the API)
| -rw-r--r-- | lobject.c | 22 |
1 files changed, 12 insertions, 10 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 2.123 2018/01/28 15:13:26 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 2.124 2018/02/27 18:47:32 roberto Exp roberto $ |
| 3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -393,7 +393,7 @@ void luaO_tostring (lua_State *L, TValue *obj) { | |||
| 393 | 393 | ||
| 394 | static void pushstr (lua_State *L, const char *str, size_t l) { | 394 | static void pushstr (lua_State *L, const char *str, size_t l) { |
| 395 | setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); | 395 | setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); |
| 396 | luaD_inctop(L); | 396 | L->top++; |
| 397 | } | 397 | } |
| 398 | 398 | ||
| 399 | 399 | ||
| @@ -402,11 +402,10 @@ static void pushstr (lua_State *L, const char *str, size_t l) { | |||
| 402 | conventional formats, plus Lua-specific '%I' and '%U' | 402 | conventional formats, plus Lua-specific '%I' and '%U' |
| 403 | */ | 403 | */ |
| 404 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | 404 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { |
| 405 | int n = 0; | 405 | int n = 0; /* number of strings in the stack to concatenate */ |
| 406 | for (;;) { | 406 | const char *e; /* points to next conversion specifier */ |
| 407 | const char *e = strchr(fmt, '%'); | 407 | while ((e = strchr(fmt, '%')) != NULL) { |
| 408 | if (e == NULL) break; | 408 | pushstr(L, fmt, e - fmt); /* string up to conversion specifier */ |
| 409 | pushstr(L, fmt, e - fmt); | ||
| 410 | switch (*(e+1)) { | 409 | switch (*(e+1)) { |
| 411 | case 's': { /* zero-terminated string */ | 410 | case 's': { /* zero-terminated string */ |
| 412 | const char *s = va_arg(argp, char *); | 411 | const char *s = va_arg(argp, char *); |
| @@ -433,7 +432,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | |||
| 433 | case 'f': { /* a 'lua_Number' */ | 432 | case 'f': { /* a 'lua_Number' */ |
| 434 | setfltvalue(s2v(L->top), cast_num(va_arg(argp, l_uacNumber))); | 433 | setfltvalue(s2v(L->top), cast_num(va_arg(argp, l_uacNumber))); |
| 435 | top2str: /* convert the top element to a string */ | 434 | top2str: /* convert the top element to a string */ |
| 436 | luaD_inctop(L); | 435 | L->top++; |
| 437 | luaO_tostring(L, s2v(L->top - 1)); | 436 | luaO_tostring(L, s2v(L->top - 1)); |
| 438 | break; | 437 | break; |
| 439 | } | 438 | } |
| @@ -460,9 +459,12 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | |||
| 460 | } | 459 | } |
| 461 | } | 460 | } |
| 462 | n += 2; | 461 | n += 2; |
| 463 | fmt = e+2; | 462 | if (L->top + 2 > L->stack_last) { /* no free stack space? */ |
| 463 | luaV_concat(L, n); | ||
| 464 | n = 1; | ||
| 465 | } | ||
| 466 | fmt = e + 2; | ||
| 464 | } | 467 | } |
| 465 | luaD_checkstack(L, 1); | ||
| 466 | pushstr(L, fmt, strlen(fmt)); | 468 | pushstr(L, fmt, strlen(fmt)); |
| 467 | if (n > 0) luaV_concat(L, n + 1); | 469 | if (n > 0) luaV_concat(L, n + 1); |
| 468 | return svalue(s2v(L->top - 1)); | 470 | return svalue(s2v(L->top - 1)); |
