From b3d0682fb94f56a438dbb4fdb2b3440ccc10cfb4 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 8 Oct 2002 15:46:08 -0300 Subject: [PATCH] use of different buffers for scanner and concatenation --- ldo.c | 7 ++- lgc.c | 10 ++--- llex.c | 129 ++++++++++++++++++++++++++---------------------------- llex.h | 5 ++- llimits.h | 8 +++- lobject.c | 11 +---- lobject.h | 4 +- lparser.c | 5 ++- lparser.h | 4 +- lstate.c | 7 ++- lstate.h | 6 +-- lundump.c | 4 +- lvm.c | 4 +- lzio.c | 15 ++++++- lzio.h | 27 ++++++++++-- 15 files changed, 136 insertions(+), 110 deletions(-) diff --git a/ldo.c b/ldo.c index a0772421..27688d2d 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.193 2002/08/30 19:09:21 roberto Exp roberto $ +** $Id: ldo.c,v 1.194 2002/09/02 20:00:41 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -420,12 +420,13 @@ int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) { */ struct SParser { /* data to `f_parser' */ ZIO *z; + Mbuffer buff; /* buffer to be used by the scanner */ int bin; }; static void f_parser (lua_State *L, void *ud) { struct SParser *p = cast(struct SParser *, ud); - Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z); + Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z, &p->buff); Closure *cl = luaF_newLclosure(L, 0, gt(L)); cl->l.p = tf; setclvalue(L->top, cl); @@ -439,11 +440,13 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin) { int status; ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */ p.z = z; p.bin = bin; + luaZ_initbuffer(L, &p.buff); /* before parsing, give a (good) chance to GC */ if (G(L)->nblocks + G(L)->nblocks/4 >= G(L)->GCthreshold) luaC_collectgarbage(L); old_blocks = G(L)->nblocks; status = luaD_rawrunprotected(L, f_parser, &p); + luaZ_freebuffer(L, &p.buff); if (status == 0) { /* add new memory to threshold (as it probably will stay) */ lua_assert(G(L)->nblocks >= old_blocks); diff --git a/lgc.c b/lgc.c index afaba8c2..d23e7a02 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.150 2002/09/05 19:57:40 roberto Exp roberto $ +** $Id: lgc.c,v 1.151 2002/09/19 19:54:22 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -332,17 +332,15 @@ static void sweepstrings (lua_State *L, int all) { } -#define MINBUFFER 256 static void checkSizes (lua_State *L) { /* check size of string hash */ if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) && G(L)->strt.size > MINSTRTABSIZE*2) luaS_resize(L, G(L)->strt.size/2); /* table is too big */ /* check size of buffer */ - if (G(L)->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */ - size_t newsize = G(L)->Mbuffsize/2; /* still larger than MINBUFFER */ - luaM_reallocvector(L, G(L)->Mbuffer, G(L)->Mbuffsize, newsize, char); - G(L)->Mbuffsize = newsize; + if (luaZ_sizebuffer(&G(L)->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ + size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2; + luaZ_resizebuffer(L, &G(L)->buff, newsize); } } diff --git a/llex.c b/llex.c index 83ac742d..b2560fbd 100644 --- a/llex.c +++ b/llex.c @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 1.111 2002/09/05 19:45:42 roberto Exp roberto $ +** $Id: llex.c,v 1.112 2002/09/19 13:03:53 roberto Exp roberto $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -100,7 +100,7 @@ static void luaX_lexerror (LexState *ls, const char *s, int token) { if (token == TK_EOS) luaX_error(ls, s, luaX_token2str(ls, token)); else - luaX_error(ls, s, cast(char *, G(ls->L)->Mbuffer)); + luaX_error(ls, s, luaZ_buffer(ls->buff)); } @@ -138,146 +138,143 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) { /* use Mbuffer to store names, literal strings and numbers */ -#define EXTRABUFF 128 -#define checkbuffer(L, len) \ - if (((len)+10)*sizeof(char) > G(L)->Mbuffsize) \ - luaO_openspace(L, (len)+EXTRABUFF) +#define EXTRABUFF 32 +#define checkbuffer(LS, len) \ + if (((len)+3)*sizeof(char) > luaZ_sizebuffer((LS)->buff)) \ + luaZ_openspace((LS)->L, (LS)->buff, (len)+EXTRABUFF) -#define save(L, c, l) (cast(char *, G(L)->Mbuffer)[l++] = cast(char, c)) -#define save_and_next(L, LS, l) (save(L, LS->current, l), next(LS)) +#define save(LS, c, l) \ + (cast(char *, luaZ_buffer((LS)->buff))[l++] = cast(char, c)) +#define save_and_next(LS, l) (save(LS, LS->current, l), next(LS)) static size_t readname (LexState *LS) { - lua_State *L = LS->L; size_t l = 0; - checkbuffer(L, l); + checkbuffer(LS, l); do { - checkbuffer(L, l); - save_and_next(L, LS, l); + checkbuffer(LS, l); + save_and_next(LS, l); } while (isalnum(LS->current) || LS->current == '_'); - save(L, '\0', l); + save(LS, '\0', l); return l-1; } /* LUA_NUMBER */ static void read_numeral (LexState *LS, int comma, SemInfo *seminfo) { - lua_State *L = LS->L; size_t l = 0; - checkbuffer(L, l); - if (comma) save(L, '.', l); + checkbuffer(LS, l); + if (comma) save(LS, '.', l); while (isdigit(LS->current)) { - checkbuffer(L, l); - save_and_next(L, LS, l); + checkbuffer(LS, l); + save_and_next(LS, l); } if (LS->current == '.') { - save_and_next(L, LS, l); + save_and_next(LS, l); if (LS->current == '.') { - save_and_next(L, LS, l); - save(L, '\0', l); + save_and_next(LS, l); + save(LS, '\0', l); luaX_lexerror(LS, "ambiguous syntax (decimal point x string concatenation)", TK_NUMBER); } } while (isdigit(LS->current)) { - checkbuffer(L, l); - save_and_next(L, LS, l); + checkbuffer(LS, l); + save_and_next(LS, l); } if (LS->current == 'e' || LS->current == 'E') { - save_and_next(L, LS, l); /* read `E' */ + save_and_next(LS, l); /* read `E' */ if (LS->current == '+' || LS->current == '-') - save_and_next(L, LS, l); /* optional exponent sign */ + save_and_next(LS, l); /* optional exponent sign */ while (isdigit(LS->current)) { - checkbuffer(L, l); - save_and_next(L, LS, l); + checkbuffer(LS, l); + save_and_next(LS, l); } } - save(L, '\0', l); - if (!luaO_str2d(cast(char *, G(L)->Mbuffer), &seminfo->r)) + save(LS, '\0', l); + if (!luaO_str2d(cast(char *, luaZ_buffer(LS->buff)), &seminfo->r)) luaX_lexerror(LS, "malformed number", TK_NUMBER); } static void read_long_string (LexState *LS, SemInfo *seminfo) { - lua_State *L = LS->L; int cont = 0; size_t l = 0; - checkbuffer(L, l); - save(L, '[', l); /* save first `[' */ - save_and_next(L, LS, l); /* pass the second `[' */ + checkbuffer(LS, l); + save(LS, '[', l); /* save first `[' */ + save_and_next(LS, l); /* pass the second `[' */ if (LS->current == '\n') /* string starts with a newline? */ inclinenumber(LS); /* skip it */ for (;;) { - checkbuffer(L, l); + checkbuffer(LS, l); switch (LS->current) { case EOZ: - save(L, '\0', l); + save(LS, '\0', l); luaX_lexerror(LS, (seminfo) ? "unfinished long string" : "unfinished long comment", TK_EOS); break; /* to avoid warnings */ case '[': - save_and_next(L, LS, l); + save_and_next(LS, l); if (LS->current == '[') { cont++; - save_and_next(L, LS, l); + save_and_next(LS, l); } continue; case ']': - save_and_next(L, LS, l); + save_and_next(LS, l); if (LS->current == ']') { if (cont == 0) goto endloop; cont--; - save_and_next(L, LS, l); + save_and_next(LS, l); } continue; case '\n': - save(L, '\n', l); + save(LS, '\n', l); inclinenumber(LS); if (!seminfo) l = 0; /* reset buffer to avoid wasting space */ continue; default: - save_and_next(L, LS, l); + save_and_next(LS, l); } } endloop: - save_and_next(L, LS, l); /* skip the second `]' */ - save(L, '\0', l); + save_and_next(LS, l); /* skip the second `]' */ + save(LS, '\0', l); if (seminfo) - seminfo->ts = luaS_newlstr(L, cast(char *, G(L)->Mbuffer)+2, l-5); + seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 2, l - 5); } static void read_string (LexState *LS, int del, SemInfo *seminfo) { - lua_State *L = LS->L; size_t l = 0; - checkbuffer(L, l); - save_and_next(L, LS, l); + checkbuffer(LS, l); + save_and_next(LS, l); while (LS->current != del) { - checkbuffer(L, l); + checkbuffer(LS, l); switch (LS->current) { case EOZ: - save(L, '\0', l); + save(LS, '\0', l); luaX_lexerror(LS, "unfinished string", TK_EOS); break; /* to avoid warnings */ case '\n': - save(L, '\0', l); + save(LS, '\0', l); luaX_lexerror(LS, "unfinished string", TK_STRING); break; /* to avoid warnings */ case '\\': next(LS); /* do not save the `\' */ switch (LS->current) { - case 'a': save(L, '\a', l); next(LS); break; - case 'b': save(L, '\b', l); next(LS); break; - case 'f': save(L, '\f', l); next(LS); break; - case 'n': save(L, '\n', l); next(LS); break; - case 'r': save(L, '\r', l); next(LS); break; - case 't': save(L, '\t', l); next(LS); break; - case 'v': save(L, '\v', l); next(LS); break; - case '\n': save(L, '\n', l); inclinenumber(LS); break; + case 'a': save(LS, '\a', l); next(LS); break; + case 'b': save(LS, '\b', l); next(LS); break; + case 'f': save(LS, '\f', l); next(LS); break; + case 'n': save(LS, '\n', l); next(LS); break; + case 'r': save(LS, '\r', l); next(LS); break; + case 't': save(LS, '\t', l); next(LS); break; + case 'v': save(LS, '\v', l); next(LS); break; + case '\n': save(LS, '\n', l); inclinenumber(LS); break; case EOZ: break; /* will raise an error next loop */ default: { if (!isdigit(LS->current)) - save_and_next(L, LS, l); /* handles \\, \", \', and \? */ + save_and_next(LS, l); /* handles \\, \", \', and \? */ else { /* \xxx */ int c = 0; int i = 0; @@ -286,21 +283,21 @@ static void read_string (LexState *LS, int del, SemInfo *seminfo) { next(LS); } while (++i<3 && isdigit(LS->current)); if (c > UCHAR_MAX) { - save(L, '\0', l); + save(LS, '\0', l); luaX_lexerror(LS, "escape sequence too large", TK_STRING); } - save(L, c, l); + save(LS, c, l); } } } break; default: - save_and_next(L, LS, l); + save_and_next(LS, l); } } - save_and_next(L, LS, l); /* skip delimiter */ - save(L, '\0', l); - seminfo->ts = luaS_newlstr(L, cast(char *, G(L)->Mbuffer)+1, l-3); + save_and_next(LS, l); /* skip delimiter */ + save(LS, '\0', l); + seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 1, l - 3); } @@ -388,7 +385,7 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) { else if (isalpha(LS->current) || LS->current == '_') { /* identifier or reserved word */ size_t l = readname(LS); - TString *ts = luaS_newlstr(LS->L, cast(char *, G(LS->L)->Mbuffer), l); + TString *ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff), l); if (ts->tsv.reserved > 0) /* reserved word? */ return ts->tsv.reserved - 1 + FIRST_RESERVED; seminfo->ts = ts; diff --git a/llex.h b/llex.h index 514d5bbc..d0e4216c 100644 --- a/llex.h +++ b/llex.h @@ -1,5 +1,5 @@ /* -** $Id: llex.h,v 1.43 2002/05/07 17:36:56 roberto Exp roberto $ +** $Id: llex.h,v 1.44 2002/09/03 11:57:38 roberto Exp roberto $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -56,7 +56,8 @@ typedef struct LexState { Token lookahead; /* look ahead token */ struct FuncState *fs; /* `FuncState' is private to the parser */ struct lua_State *L; - struct zio *z; /* input stream */ + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ TString *source; /* current source name */ } LexState; diff --git a/llimits.h b/llimits.h index ca7dce5e..9acea06d 100644 --- a/llimits.h +++ b/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.44 2002/06/13 13:45:31 roberto Exp roberto $ +** $Id: llimits.h,v 1.45 2002/07/08 20:22:08 roberto Exp roberto $ ** Limits, basic types, and some other `installation-dependent' definitions ** See Copyright Notice in lua.h */ @@ -150,4 +150,10 @@ typedef unsigned long Instruction; #endif +/* minimum size for string buffer */ +#ifndef LUA_MINBUFFER +#define LUA_MINBUFFER 32 +#endif + + #endif diff --git a/lobject.c b/lobject.c index cdf49c92..bf6b4c00 100644 --- a/lobject.c +++ b/lobject.c @@ -1,5 +1,5 @@ /* -** $Id: lobject.c,v 1.88 2002/09/19 13:03:53 roberto Exp roberto $ +** $Id: lobject.c,v 1.89 2002/10/04 14:31:03 roberto Exp roberto $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ @@ -73,15 +73,6 @@ int luaO_rawequalObj (const TObject *t1, const TObject *t2) { } -char *luaO_openspace (lua_State *L, size_t n) { - if (n > G(L)->Mbuffsize) { - luaM_reallocvector(L, G(L)->Mbuffer, G(L)->Mbuffsize, n, char); - G(L)->Mbuffsize = n; - } - return G(L)->Mbuffer; -} - - int luaO_str2d (const char *s, lua_Number *result) { char *endptr; lua_Number res = lua_str2number(s, &endptr); diff --git a/lobject.h b/lobject.h index d9a5c242..c872ecc9 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 1.145 2002/09/02 19:54:49 roberto Exp roberto $ +** $Id: lobject.h,v 1.146 2002/09/19 13:03:53 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -316,8 +316,6 @@ extern const TObject luaO_nilobject; int luaO_log2 (unsigned int x); -char *luaO_openspace (lua_State *L, size_t n); - int luaO_rawequalObj (const TObject *t1, const TObject *t2); int luaO_str2d (const char *s, lua_Number *result); diff --git a/lparser.c b/lparser.c index e5dc2054..1009f87b 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.193 2002/08/22 19:51:08 roberto Exp roberto $ +** $Id: lparser.c,v 1.194 2002/08/30 19:09:21 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -351,9 +351,10 @@ static void close_func (LexState *ls) { } -Proto *luaY_parser (lua_State *L, ZIO *z) { +Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) { struct LexState lexstate; struct FuncState funcstate; + lexstate.buff = buff; luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); open_func(&lexstate, &funcstate); next(&lexstate); /* read first token */ diff --git a/lparser.h b/lparser.h index 2b9c64d4..011c59fe 100644 --- a/lparser.h +++ b/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.43 2002/05/10 19:22:11 roberto Exp roberto $ +** $Id: lparser.h,v 1.44 2002/05/14 17:52:22 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -65,7 +65,7 @@ typedef struct FuncState { } FuncState; -Proto *luaY_parser (lua_State *L, ZIO *z); +Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff); #endif diff --git a/lstate.c b/lstate.c index a2334cca..a8136d1a 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.104 2002/08/16 20:00:28 roberto Exp roberto $ +** $Id: lstate.c,v 1.105 2002/08/30 19:09:21 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -61,8 +61,7 @@ static void f_luaopen (lua_State *L, void *ud) { G(L)->strt.size = 0; G(L)->strt.nuse = 0; G(L)->strt.hash = NULL; - G(L)->Mbuffer = NULL; - G(L)->Mbuffsize = 0; + luaZ_initbuffer(L, &G(L)->buff); G(L)->panic = &default_panic; G(L)->rootgc = NULL; G(L)->rootudata = NULL; @@ -160,7 +159,7 @@ static void close_state (lua_State *L) { lua_assert(G(L)->rootgc == NULL); lua_assert(G(L)->rootudata == NULL); luaS_freeall(L); - luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char); + luaZ_freebuffer(L, &G(L)->buff); luaM_freelem(NULL, L->l_G); } luaE_closethread(NULL, L); diff --git a/lstate.h b/lstate.h index 618685c1..94af29ad 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 1.95 2002/08/30 19:09:21 roberto Exp roberto $ +** $Id: lstate.h,v 1.96 2002/09/19 13:03:53 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -11,6 +11,7 @@ #include "lobject.h" #include "ltm.h" +#include "lzio.h" /* @@ -124,8 +125,7 @@ typedef struct global_State { GCObject *rootgc; /* list of (almost) all collectable objects */ GCObject *rootudata; /* (separated) list of all userdata */ GCObject *tmudata; /* list of userdata to be GC */ - char *Mbuffer; /* global buffer */ - size_t Mbuffsize; /* size of Mbuffer */ + Mbuffer buff; /* temporary buffer for string concatentation */ lu_mem GCthreshold; lu_mem nblocks; /* number of `bytes' currently allocated */ lua_CFunction panic; /* to be called in unprotected errors */ diff --git a/lundump.c b/lundump.c index 6f2fa287..a555f97a 100644 --- a/lundump.c +++ b/lundump.c @@ -1,5 +1,5 @@ /* -** $Id: lundump.c,v 1.52 2002/08/12 13:37:19 roberto Exp roberto $ +** $Id: lundump.c,v 1.53 2002/09/19 13:03:53 roberto Exp roberto $ ** load pre-compiled Lua chunks ** See Copyright Notice in lua.h */ @@ -99,7 +99,7 @@ static TString* LoadString (LoadState* S) return NULL; else { - char* s=luaO_openspace(S->L,size); + char* s=luaZ_openspace(S->L,&G(S->L)->buff,size); ezread(S,s,size); return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ } diff --git a/lvm.c b/lvm.c index 0279dbe7..68e6a080 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.255 2002/09/19 13:03:53 roberto Exp roberto $ +** $Id: lvm.c,v 1.256 2002/09/19 20:12:47 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -303,7 +303,7 @@ void luaV_concat (lua_State *L, int total, int last) { n++; } if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow"); - buffer = luaO_openspace(L, tl); + buffer = luaZ_openspace(L, &G(L)->buff, tl); tl = 0; for (i=n; i>0; i--) { /* concat all strings */ size_t l = tsvalue(top-i)->tsv.len; diff --git a/lzio.c b/lzio.c index 7ae7abb5..b22c4242 100644 --- a/lzio.c +++ b/lzio.c @@ -1,5 +1,5 @@ /* -** $Id: lzio.c,v 1.20 2002/08/05 18:45:02 roberto Exp roberto $ +** $Id: lzio.c,v 1.21 2002/08/06 17:26:45 roberto Exp roberto $ ** a generic input stream interface ** See Copyright Notice in lua.h */ @@ -10,10 +10,10 @@ #include "lua.h" #include "llimits.h" +#include "lmem.h" #include "lzio.h" - int luaZ_fill (ZIO *z) { size_t size; const char *buff = z->reader(NULL, z->data, &size); @@ -66,3 +66,14 @@ size_t luaZ_read (ZIO *z, void *b, size_t n) { return 0; } +/* ------------------------------------------------------------------------ */ +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { + if (n > buff->buffsize) { + if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; + luaM_reallocvector(L, buff->buffer, buff->buffsize, n, char); + buff->buffsize = n; + } + return buff->buffer; +} + + diff --git a/lzio.h b/lzio.h index e7807ec3..f2fbad90 100644 --- a/lzio.h +++ b/lzio.h @@ -1,5 +1,5 @@ /* -** $Id: lzio.h,v 1.12 2002/06/06 12:40:22 roberto Exp roberto $ +** $Id: lzio.h,v 1.13 2002/08/05 18:45:02 roberto Exp roberto $ ** Buffered streams ** See Copyright Notice in lua.h */ @@ -13,7 +13,7 @@ #define EOZ (-1) /* end of stream */ -typedef struct zio ZIO; +typedef struct Zio ZIO; #define zgetc(z) (((z)->n--)>0 ? \ cast(int, cast(unsigned char, *(z)->p++)) : \ @@ -26,9 +26,30 @@ size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ int luaZ_lookahead (ZIO *z); + +typedef struct Mbuffer { + char *buffer; + size_t buffsize; +} Mbuffer; + + +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_buffer(buff) ((buff)->buffer) + +#define luaZ_resizebuffer(L, buff, size) \ + (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + /* --------- Private Part ------------------ */ -struct zio { +struct Zio { size_t n; /* bytes still unread */ const char *p; /* current position in buffer */ lua_Chunkreader reader;