use of different buffers for scanner and concatenation

This commit is contained in:
Roberto Ierusalimschy 2002-10-08 15:46:08 -03:00
parent 02afc892d5
commit b3d0682fb9
15 changed files with 136 additions and 110 deletions

7
ldo.c
View File

@ -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 ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** 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' */ struct SParser { /* data to `f_parser' */
ZIO *z; ZIO *z;
Mbuffer buff; /* buffer to be used by the scanner */
int bin; int bin;
}; };
static void f_parser (lua_State *L, void *ud) { static void f_parser (lua_State *L, void *ud) {
struct SParser *p = cast(struct SParser *, 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)); Closure *cl = luaF_newLclosure(L, 0, gt(L));
cl->l.p = tf; cl->l.p = tf;
setclvalue(L->top, cl); setclvalue(L->top, cl);
@ -439,11 +440,13 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
int status; int status;
ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */ ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */
p.z = z; p.bin = bin; p.z = z; p.bin = bin;
luaZ_initbuffer(L, &p.buff);
/* before parsing, give a (good) chance to GC */ /* before parsing, give a (good) chance to GC */
if (G(L)->nblocks + G(L)->nblocks/4 >= G(L)->GCthreshold) if (G(L)->nblocks + G(L)->nblocks/4 >= G(L)->GCthreshold)
luaC_collectgarbage(L); luaC_collectgarbage(L);
old_blocks = G(L)->nblocks; old_blocks = G(L)->nblocks;
status = luaD_rawrunprotected(L, f_parser, &p); status = luaD_rawrunprotected(L, f_parser, &p);
luaZ_freebuffer(L, &p.buff);
if (status == 0) { if (status == 0) {
/* add new memory to threshold (as it probably will stay) */ /* add new memory to threshold (as it probably will stay) */
lua_assert(G(L)->nblocks >= old_blocks); lua_assert(G(L)->nblocks >= old_blocks);

10
lgc.c
View File

@ -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 ** Garbage Collector
** See Copyright Notice in lua.h ** 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) { static void checkSizes (lua_State *L) {
/* check size of string hash */ /* check size of string hash */
if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) && if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) &&
G(L)->strt.size > MINSTRTABSIZE*2) G(L)->strt.size > MINSTRTABSIZE*2)
luaS_resize(L, G(L)->strt.size/2); /* table is too big */ luaS_resize(L, G(L)->strt.size/2); /* table is too big */
/* check size of buffer */ /* check size of buffer */
if (G(L)->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */ if (luaZ_sizebuffer(&G(L)->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
size_t newsize = G(L)->Mbuffsize/2; /* still larger than MINBUFFER */ size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2;
luaM_reallocvector(L, G(L)->Mbuffer, G(L)->Mbuffsize, newsize, char); luaZ_resizebuffer(L, &G(L)->buff, newsize);
G(L)->Mbuffsize = newsize;
} }
} }

129
llex.c
View File

@ -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 ** Lexical Analyzer
** See Copyright Notice in lua.h ** 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) if (token == TK_EOS)
luaX_error(ls, s, luaX_token2str(ls, token)); luaX_error(ls, s, luaX_token2str(ls, token));
else 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 */ /* use Mbuffer to store names, literal strings and numbers */
#define EXTRABUFF 128 #define EXTRABUFF 32
#define checkbuffer(L, len) \ #define checkbuffer(LS, len) \
if (((len)+10)*sizeof(char) > G(L)->Mbuffsize) \ if (((len)+3)*sizeof(char) > luaZ_sizebuffer((LS)->buff)) \
luaO_openspace(L, (len)+EXTRABUFF) luaZ_openspace((LS)->L, (LS)->buff, (len)+EXTRABUFF)
#define save(L, c, l) (cast(char *, G(L)->Mbuffer)[l++] = cast(char, c)) #define save(LS, c, l) \
#define save_and_next(L, LS, l) (save(L, LS->current, l), next(LS)) (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) { static size_t readname (LexState *LS) {
lua_State *L = LS->L;
size_t l = 0; size_t l = 0;
checkbuffer(L, l); checkbuffer(LS, l);
do { do {
checkbuffer(L, l); checkbuffer(LS, l);
save_and_next(L, LS, l); save_and_next(LS, l);
} while (isalnum(LS->current) || LS->current == '_'); } while (isalnum(LS->current) || LS->current == '_');
save(L, '\0', l); save(LS, '\0', l);
return l-1; return l-1;
} }
/* LUA_NUMBER */ /* LUA_NUMBER */
static void read_numeral (LexState *LS, int comma, SemInfo *seminfo) { static void read_numeral (LexState *LS, int comma, SemInfo *seminfo) {
lua_State *L = LS->L;
size_t l = 0; size_t l = 0;
checkbuffer(L, l); checkbuffer(LS, l);
if (comma) save(L, '.', l); if (comma) save(LS, '.', l);
while (isdigit(LS->current)) { while (isdigit(LS->current)) {
checkbuffer(L, l); checkbuffer(LS, l);
save_and_next(L, LS, l); save_and_next(LS, l);
} }
if (LS->current == '.') { if (LS->current == '.') {
save_and_next(L, LS, l); save_and_next(LS, l);
if (LS->current == '.') { if (LS->current == '.') {
save_and_next(L, LS, l); save_and_next(LS, l);
save(L, '\0', l); save(LS, '\0', l);
luaX_lexerror(LS, luaX_lexerror(LS,
"ambiguous syntax (decimal point x string concatenation)", "ambiguous syntax (decimal point x string concatenation)",
TK_NUMBER); TK_NUMBER);
} }
} }
while (isdigit(LS->current)) { while (isdigit(LS->current)) {
checkbuffer(L, l); checkbuffer(LS, l);
save_and_next(L, LS, l); save_and_next(LS, l);
} }
if (LS->current == 'e' || LS->current == 'E') { 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 == '-') 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)) { while (isdigit(LS->current)) {
checkbuffer(L, l); checkbuffer(LS, l);
save_and_next(L, LS, l); save_and_next(LS, l);
} }
} }
save(L, '\0', l); save(LS, '\0', l);
if (!luaO_str2d(cast(char *, G(L)->Mbuffer), &seminfo->r)) if (!luaO_str2d(cast(char *, luaZ_buffer(LS->buff)), &seminfo->r))
luaX_lexerror(LS, "malformed number", TK_NUMBER); luaX_lexerror(LS, "malformed number", TK_NUMBER);
} }
static void read_long_string (LexState *LS, SemInfo *seminfo) { static void read_long_string (LexState *LS, SemInfo *seminfo) {
lua_State *L = LS->L;
int cont = 0; int cont = 0;
size_t l = 0; size_t l = 0;
checkbuffer(L, l); checkbuffer(LS, l);
save(L, '[', l); /* save first `[' */ save(LS, '[', l); /* save first `[' */
save_and_next(L, LS, l); /* pass the second `[' */ save_and_next(LS, l); /* pass the second `[' */
if (LS->current == '\n') /* string starts with a newline? */ if (LS->current == '\n') /* string starts with a newline? */
inclinenumber(LS); /* skip it */ inclinenumber(LS); /* skip it */
for (;;) { for (;;) {
checkbuffer(L, l); checkbuffer(LS, l);
switch (LS->current) { switch (LS->current) {
case EOZ: case EOZ:
save(L, '\0', l); save(LS, '\0', l);
luaX_lexerror(LS, (seminfo) ? "unfinished long string" : luaX_lexerror(LS, (seminfo) ? "unfinished long string" :
"unfinished long comment", TK_EOS); "unfinished long comment", TK_EOS);
break; /* to avoid warnings */ break; /* to avoid warnings */
case '[': case '[':
save_and_next(L, LS, l); save_and_next(LS, l);
if (LS->current == '[') { if (LS->current == '[') {
cont++; cont++;
save_and_next(L, LS, l); save_and_next(LS, l);
} }
continue; continue;
case ']': case ']':
save_and_next(L, LS, l); save_and_next(LS, l);
if (LS->current == ']') { if (LS->current == ']') {
if (cont == 0) goto endloop; if (cont == 0) goto endloop;
cont--; cont--;
save_and_next(L, LS, l); save_and_next(LS, l);
} }
continue; continue;
case '\n': case '\n':
save(L, '\n', l); save(LS, '\n', l);
inclinenumber(LS); inclinenumber(LS);
if (!seminfo) l = 0; /* reset buffer to avoid wasting space */ if (!seminfo) l = 0; /* reset buffer to avoid wasting space */
continue; continue;
default: default:
save_and_next(L, LS, l); save_and_next(LS, l);
} }
} endloop: } endloop:
save_and_next(L, LS, l); /* skip the second `]' */ save_and_next(LS, l); /* skip the second `]' */
save(L, '\0', l); save(LS, '\0', l);
if (seminfo) 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) { static void read_string (LexState *LS, int del, SemInfo *seminfo) {
lua_State *L = LS->L;
size_t l = 0; size_t l = 0;
checkbuffer(L, l); checkbuffer(LS, l);
save_and_next(L, LS, l); save_and_next(LS, l);
while (LS->current != del) { while (LS->current != del) {
checkbuffer(L, l); checkbuffer(LS, l);
switch (LS->current) { switch (LS->current) {
case EOZ: case EOZ:
save(L, '\0', l); save(LS, '\0', l);
luaX_lexerror(LS, "unfinished string", TK_EOS); luaX_lexerror(LS, "unfinished string", TK_EOS);
break; /* to avoid warnings */ break; /* to avoid warnings */
case '\n': case '\n':
save(L, '\0', l); save(LS, '\0', l);
luaX_lexerror(LS, "unfinished string", TK_STRING); luaX_lexerror(LS, "unfinished string", TK_STRING);
break; /* to avoid warnings */ break; /* to avoid warnings */
case '\\': case '\\':
next(LS); /* do not save the `\' */ next(LS); /* do not save the `\' */
switch (LS->current) { switch (LS->current) {
case 'a': save(L, '\a', l); next(LS); break; case 'a': save(LS, '\a', l); next(LS); break;
case 'b': save(L, '\b', l); next(LS); break; case 'b': save(LS, '\b', l); next(LS); break;
case 'f': save(L, '\f', l); next(LS); break; case 'f': save(LS, '\f', l); next(LS); break;
case 'n': save(L, '\n', l); next(LS); break; case 'n': save(LS, '\n', l); next(LS); break;
case 'r': save(L, '\r', l); next(LS); break; case 'r': save(LS, '\r', l); next(LS); break;
case 't': save(L, '\t', l); next(LS); break; case 't': save(LS, '\t', l); next(LS); break;
case 'v': save(L, '\v', l); next(LS); break; case 'v': save(LS, '\v', l); next(LS); break;
case '\n': save(L, '\n', l); inclinenumber(LS); break; case '\n': save(LS, '\n', l); inclinenumber(LS); break;
case EOZ: break; /* will raise an error next loop */ case EOZ: break; /* will raise an error next loop */
default: { default: {
if (!isdigit(LS->current)) if (!isdigit(LS->current))
save_and_next(L, LS, l); /* handles \\, \", \', and \? */ save_and_next(LS, l); /* handles \\, \", \', and \? */
else { /* \xxx */ else { /* \xxx */
int c = 0; int c = 0;
int i = 0; int i = 0;
@ -286,21 +283,21 @@ static void read_string (LexState *LS, int del, SemInfo *seminfo) {
next(LS); next(LS);
} while (++i<3 && isdigit(LS->current)); } while (++i<3 && isdigit(LS->current));
if (c > UCHAR_MAX) { if (c > UCHAR_MAX) {
save(L, '\0', l); save(LS, '\0', l);
luaX_lexerror(LS, "escape sequence too large", TK_STRING); luaX_lexerror(LS, "escape sequence too large", TK_STRING);
} }
save(L, c, l); save(LS, c, l);
} }
} }
} }
break; break;
default: default:
save_and_next(L, LS, l); save_and_next(LS, l);
} }
} }
save_and_next(L, LS, l); /* skip delimiter */ save_and_next(LS, l); /* skip delimiter */
save(L, '\0', l); save(LS, '\0', l);
seminfo->ts = luaS_newlstr(L, cast(char *, G(L)->Mbuffer)+1, l-3); 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 == '_') { else if (isalpha(LS->current) || LS->current == '_') {
/* identifier or reserved word */ /* identifier or reserved word */
size_t l = readname(LS); 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? */ if (ts->tsv.reserved > 0) /* reserved word? */
return ts->tsv.reserved - 1 + FIRST_RESERVED; return ts->tsv.reserved - 1 + FIRST_RESERVED;
seminfo->ts = ts; seminfo->ts = ts;

5
llex.h
View File

@ -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 ** Lexical Analyzer
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -56,7 +56,8 @@ typedef struct LexState {
Token lookahead; /* look ahead token */ Token lookahead; /* look ahead token */
struct FuncState *fs; /* `FuncState' is private to the parser */ struct FuncState *fs; /* `FuncState' is private to the parser */
struct lua_State *L; struct lua_State *L;
struct zio *z; /* input stream */ ZIO *z; /* input stream */
Mbuffer *buff; /* buffer for tokens */
TString *source; /* current source name */ TString *source; /* current source name */
} LexState; } LexState;

View File

@ -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 ** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -150,4 +150,10 @@ typedef unsigned long Instruction;
#endif #endif
/* minimum size for string buffer */
#ifndef LUA_MINBUFFER
#define LUA_MINBUFFER 32
#endif
#endif #endif

View File

@ -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 ** Some generic functions over Lua objects
** See Copyright Notice in lua.h ** 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) { int luaO_str2d (const char *s, lua_Number *result) {
char *endptr; char *endptr;
lua_Number res = lua_str2number(s, &endptr); lua_Number res = lua_str2number(s, &endptr);

View File

@ -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 ** Type definitions for Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -316,8 +316,6 @@ extern const TObject luaO_nilobject;
int luaO_log2 (unsigned int x); 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_rawequalObj (const TObject *t1, const TObject *t2);
int luaO_str2d (const char *s, lua_Number *result); int luaO_str2d (const char *s, lua_Number *result);

View File

@ -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 ** Lua Parser
** See Copyright Notice in lua.h ** 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 LexState lexstate;
struct FuncState funcstate; struct FuncState funcstate;
lexstate.buff = buff;
luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
open_func(&lexstate, &funcstate); open_func(&lexstate, &funcstate);
next(&lexstate); /* read first token */ next(&lexstate); /* read first token */

View File

@ -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 ** Lua Parser
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -65,7 +65,7 @@ typedef struct FuncState {
} FuncState; } FuncState;
Proto *luaY_parser (lua_State *L, ZIO *z); Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff);
#endif #endif

View File

@ -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 ** Global State
** See Copyright Notice in lua.h ** 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.size = 0;
G(L)->strt.nuse = 0; G(L)->strt.nuse = 0;
G(L)->strt.hash = NULL; G(L)->strt.hash = NULL;
G(L)->Mbuffer = NULL; luaZ_initbuffer(L, &G(L)->buff);
G(L)->Mbuffsize = 0;
G(L)->panic = &default_panic; G(L)->panic = &default_panic;
G(L)->rootgc = NULL; G(L)->rootgc = NULL;
G(L)->rootudata = 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)->rootgc == NULL);
lua_assert(G(L)->rootudata == NULL); lua_assert(G(L)->rootudata == NULL);
luaS_freeall(L); 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); luaM_freelem(NULL, L->l_G);
} }
luaE_closethread(NULL, L); luaE_closethread(NULL, L);

View File

@ -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 ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -11,6 +11,7 @@
#include "lobject.h" #include "lobject.h"
#include "ltm.h" #include "ltm.h"
#include "lzio.h"
/* /*
@ -124,8 +125,7 @@ typedef struct global_State {
GCObject *rootgc; /* list of (almost) all collectable objects */ GCObject *rootgc; /* list of (almost) all collectable objects */
GCObject *rootudata; /* (separated) list of all userdata */ GCObject *rootudata; /* (separated) list of all userdata */
GCObject *tmudata; /* list of userdata to be GC */ GCObject *tmudata; /* list of userdata to be GC */
char *Mbuffer; /* global buffer */ Mbuffer buff; /* temporary buffer for string concatentation */
size_t Mbuffsize; /* size of Mbuffer */
lu_mem GCthreshold; lu_mem GCthreshold;
lu_mem nblocks; /* number of `bytes' currently allocated */ lu_mem nblocks; /* number of `bytes' currently allocated */
lua_CFunction panic; /* to be called in unprotected errors */ lua_CFunction panic; /* to be called in unprotected errors */

View File

@ -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 ** load pre-compiled Lua chunks
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -99,7 +99,7 @@ static TString* LoadString (LoadState* S)
return NULL; return NULL;
else else
{ {
char* s=luaO_openspace(S->L,size); char* s=luaZ_openspace(S->L,&G(S->L)->buff,size);
ezread(S,s,size); ezread(S,s,size);
return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
} }

4
lvm.c
View File

@ -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 ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -303,7 +303,7 @@ void luaV_concat (lua_State *L, int total, int last) {
n++; n++;
} }
if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow"); 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; tl = 0;
for (i=n; i>0; i--) { /* concat all strings */ for (i=n; i>0; i--) { /* concat all strings */
size_t l = tsvalue(top-i)->tsv.len; size_t l = tsvalue(top-i)->tsv.len;

15
lzio.c
View File

@ -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 ** a generic input stream interface
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -10,10 +10,10 @@
#include "lua.h" #include "lua.h"
#include "llimits.h" #include "llimits.h"
#include "lmem.h"
#include "lzio.h" #include "lzio.h"
int luaZ_fill (ZIO *z) { int luaZ_fill (ZIO *z) {
size_t size; size_t size;
const char *buff = z->reader(NULL, z->data, &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; 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;
}

27
lzio.h
View File

@ -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 ** Buffered streams
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -13,7 +13,7 @@
#define EOZ (-1) /* end of stream */ #define EOZ (-1) /* end of stream */
typedef struct zio ZIO; typedef struct Zio ZIO;
#define zgetc(z) (((z)->n--)>0 ? \ #define zgetc(z) (((z)->n--)>0 ? \
cast(int, cast(unsigned char, *(z)->p++)) : \ 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); 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 ------------------ */ /* --------- Private Part ------------------ */
struct zio { struct Zio {
size_t n; /* bytes still unread */ size_t n; /* bytes still unread */
const char *p; /* current position in buffer */ const char *p; /* current position in buffer */
lua_Chunkreader reader; lua_Chunkreader reader;