diff options
Diffstat (limited to 'lauxlib.c')
-rw-r--r-- | lauxlib.c | 22 |
1 files changed, 17 insertions, 5 deletions
@@ -516,6 +516,15 @@ static void newbox (lua_State *L) { | |||
516 | 516 | ||
517 | 517 | ||
518 | /* | 518 | /* |
519 | ** Whenever buffer is accessed, slot 'idx' must either be a box (which | ||
520 | ** cannot be NULL) or it is a placeholder for the buffer. | ||
521 | */ | ||
522 | #define checkbufferlevel(B,idx) \ | ||
523 | lua_assert(buffonstack(B) ? lua_touserdata(B->L, idx) != NULL \ | ||
524 | : lua_touserdata(B->L, idx) == (void*)B) | ||
525 | |||
526 | |||
527 | /* | ||
519 | ** Compute new size for buffer 'B', enough to accommodate extra 'sz' | 528 | ** Compute new size for buffer 'B', enough to accommodate extra 'sz' |
520 | ** bytes. | 529 | ** bytes. |
521 | */ | 530 | */ |
@@ -531,10 +540,11 @@ static size_t newbuffsize (luaL_Buffer *B, size_t sz) { | |||
531 | 540 | ||
532 | /* | 541 | /* |
533 | ** Returns a pointer to a free area with at least 'sz' bytes in buffer | 542 | ** Returns a pointer to a free area with at least 'sz' bytes in buffer |
534 | ** 'B'. 'boxidx' is the relative position in the stack where the | 543 | ** 'B'. 'boxidx' is the relative position in the stack where is the |
535 | ** buffer's box is or should be. | 544 | ** buffer's box or its placeholder. |
536 | */ | 545 | */ |
537 | static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) { | 546 | static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) { |
547 | checkbufferlevel(B, boxidx); | ||
538 | if (B->size - B->n >= sz) /* enough space? */ | 548 | if (B->size - B->n >= sz) /* enough space? */ |
539 | return B->b + B->n; | 549 | return B->b + B->n; |
540 | else { | 550 | else { |
@@ -545,6 +555,7 @@ static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) { | |||
545 | if (buffonstack(B)) /* buffer already has a box? */ | 555 | if (buffonstack(B)) /* buffer already has a box? */ |
546 | newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */ | 556 | newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */ |
547 | else { /* no box yet */ | 557 | else { /* no box yet */ |
558 | lua_remove(L, boxidx); /* remove placeholder */ | ||
548 | newbox(L); /* create a new box */ | 559 | newbox(L); /* create a new box */ |
549 | lua_insert(L, boxidx); /* move box to its intended position */ | 560 | lua_insert(L, boxidx); /* move box to its intended position */ |
550 | lua_toclose(L, boxidx); | 561 | lua_toclose(L, boxidx); |
@@ -581,11 +592,11 @@ LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { | |||
581 | 592 | ||
582 | LUALIB_API void luaL_pushresult (luaL_Buffer *B) { | 593 | LUALIB_API void luaL_pushresult (luaL_Buffer *B) { |
583 | lua_State *L = B->L; | 594 | lua_State *L = B->L; |
595 | checkbufferlevel(B, -1); | ||
584 | lua_pushlstring(L, B->b, B->n); | 596 | lua_pushlstring(L, B->b, B->n); |
585 | if (buffonstack(B)) { | 597 | if (buffonstack(B)) |
586 | lua_closeslot(L, -2); /* close the box */ | 598 | lua_closeslot(L, -2); /* close the box */ |
587 | lua_remove(L, -2); /* remove box from the stack */ | 599 | lua_remove(L, -2); /* remove box or placeholder from the stack */ |
588 | } | ||
589 | } | 600 | } |
590 | 601 | ||
591 | 602 | ||
@@ -620,6 +631,7 @@ LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { | |||
620 | B->b = B->init.b; | 631 | B->b = B->init.b; |
621 | B->n = 0; | 632 | B->n = 0; |
622 | B->size = LUAL_BUFFERSIZE; | 633 | B->size = LUAL_BUFFERSIZE; |
634 | lua_pushlightuserdata(L, (void*)B); /* push placeholder */ | ||
623 | } | 635 | } |
624 | 636 | ||
625 | 637 | ||