mirror of
https://github.com/lua/lua.git
synced 2025-07-24 20:52:35 +00:00
Scanner doesn't need to anchor reserved words
This commit is contained in:
parent
abf8b1cd4a
commit
5894ca7b95
2 changed files with 20 additions and 12 deletions
30
llex.c
30
llex.c
|
@ -127,21 +127,20 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Creates a new string and anchors it in scanner's table so that it
|
** Anchors a string in scanner's table so that it will not be collected
|
||||||
** will not be collected until the end of the compilation; by that time
|
** until the end of the compilation; by that time it should be anchored
|
||||||
** it should be anchored somewhere. It also internalizes long strings,
|
** somewhere. It also internalizes long strings, ensuring there is only
|
||||||
** ensuring there is only one copy of each unique string.
|
** one copy of each unique string.
|
||||||
*/
|
*/
|
||||||
TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
|
static TString *anchorstr (LexState *ls, TString *ts) {
|
||||||
lua_State *L = ls->L;
|
lua_State *L = ls->L;
|
||||||
TString *ts = luaS_newlstr(L, str, l); /* create new string */
|
|
||||||
TValue oldts;
|
TValue oldts;
|
||||||
int tag = luaH_getstr(ls->h, ts, &oldts);
|
int tag = luaH_getstr(ls->h, ts, &oldts);
|
||||||
if (!tagisempty(tag)) /* string already present? */
|
if (!tagisempty(tag)) /* string already present? */
|
||||||
return tsvalue(&oldts); /* use stored value */
|
return tsvalue(&oldts); /* use stored value */
|
||||||
else { /* create a new entry */
|
else { /* create a new entry */
|
||||||
TValue *stv = s2v(L->top.p++); /* reserve stack space for string */
|
TValue *stv = s2v(L->top.p++); /* reserve stack space for string */
|
||||||
setsvalue(L, stv, ts); /* temporarily anchor the string */
|
setsvalue(L, stv, ts); /* push (anchor) the string on the stack */
|
||||||
luaH_set(L, ls->h, stv, stv); /* t[string] = string */
|
luaH_set(L, ls->h, stv, stv); /* t[string] = string */
|
||||||
/* table is not a metatable, so it does not need to invalidate cache */
|
/* table is not a metatable, so it does not need to invalidate cache */
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
|
@ -151,6 +150,14 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Creates a new string and anchors it in scanner's table.
|
||||||
|
*/
|
||||||
|
TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
|
||||||
|
return anchorstr(ls, luaS_newlstr(ls->L, str, l));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** increment line number and skips newline sequence (any of
|
** increment line number and skips newline sequence (any of
|
||||||
** \n, \r, \n\r, or \r\n)
|
** \n, \r, \n\r, or \r\n)
|
||||||
|
@ -544,12 +551,13 @@ static int llex (LexState *ls, SemInfo *seminfo) {
|
||||||
do {
|
do {
|
||||||
save_and_next(ls);
|
save_and_next(ls);
|
||||||
} while (lislalnum(ls->current));
|
} while (lislalnum(ls->current));
|
||||||
ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
|
/* find or create string */
|
||||||
luaZ_bufflen(ls->buff));
|
ts = luaS_newlstr(ls->L, luaZ_buffer(ls->buff),
|
||||||
seminfo->ts = ts;
|
luaZ_bufflen(ls->buff));
|
||||||
if (isreserved(ts)) /* reserved word? */
|
if (isreserved(ts)) /* reserved word? */
|
||||||
return ts->extra - 1 + FIRST_RESERVED;
|
return ts->extra - 1 + FIRST_RESERVED;
|
||||||
else {
|
else {
|
||||||
|
seminfo->ts = anchorstr(ls, ts);
|
||||||
return TK_NAME;
|
return TK_NAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
/*
|
/*
|
||||||
** test whether a string is a reserved word
|
** test whether a string is a reserved word
|
||||||
*/
|
*/
|
||||||
#define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0)
|
#define isreserved(s) (strisshr(s) && (s)->extra > 0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue