summaryrefslogtreecommitdiff
path: root/libs/liblua/src/llex.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/liblua/src/llex.c')
-rw-r--r--libs/liblua/src/llex.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/libs/liblua/src/llex.c b/libs/liblua/src/llex.c
index 4b8dec9985..e99151787a 100644
--- a/libs/liblua/src/llex.c
+++ b/libs/liblua/src/llex.c
@@ -122,26 +122,29 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
/*
-** creates a new string and anchors it in scanner's table so that
-** it will not be collected until the end of the compilation
-** (by that time it should be anchored somewhere)
+** Creates a new string and anchors it in scanner's table so that it
+** will not be collected until the end of the compilation; by that time
+** it should be anchored somewhere. It also internalizes long strings,
+** ensuring there is only one copy of each unique string. The table
+** here is used as a set: the string enters as the key, while its value
+** is irrelevant. We use the string itself as the value only because it
+** is a TValue readly available. Later, the code generation can change
+** this value.
*/
TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
lua_State *L = ls->L;
- TValue *o; /* entry for 'str' */
TString *ts = luaS_newlstr(L, str, l); /* create new string */
- setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
- o = luaH_set(L, ls->h, s2v(L->top - 1));
- if (isempty(o)) { /* not in use yet? */
- /* boolean value does not need GC barrier;
- table is not a metatable, so it does not need to invalidate cache */
- setbtvalue(o); /* t[string] = true */
+ const TValue *o = luaH_getstr(ls->h, ts);
+ if (!ttisnil(o)) /* string already present? */
+ ts = keystrval(nodefromval(o)); /* get saved copy */
+ else { /* not in use yet */
+ TValue *stv = s2v(L->top++); /* reserve stack space for string */
+ setsvalue(L, stv, ts); /* temporarily anchor the string */
+ luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */
+ /* table is not a metatable, so it does not need to invalidate cache */
luaC_checkGC(L);
+ L->top--; /* remove string from stack */
}
- else { /* string already present */
- ts = keystrval(nodefromval(o)); /* re-use value previously stored */
- }
- L->top--; /* remove string from stack */
return ts;
}