[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Strange change in load/loadstring in Lua-5.4.4
- From: Domingo Alvarez Duarte <mingodad@...>
- Date: Mon, 22 Aug 2022 12:30:28 +0200
Hello !
While trying to change Lua-5.4.4 to LJS
(https://github.com/mingodad/ljs) I found an intriguing change in
behavior/bug between Lua-5.3.6 and Lua-5.4.4, in LJS I decided to forbid
shadowing variables in the same scope and it works as intended in LJS
from LjsJit, Lua-(5.1.5 .. 5.3.6) but applying a similar check to
Lua-5.4.4 find a duplicated variable name where it shouldn't (see code
shown bellow).
Somehow this line 'local res = loadstring("a=1")' brings the 'a'
variable name to visibility for the parser in Lua-5.4.4 but not for
previous Lua versions.
It seems like the parser is parsing the string passed to 'load' when
parsing the script instead of at runtime, or something else that I'm not
seeing through the code.
Can someone shed some light on this issue ?
====
if loadstring == null then
loadstring = load;
end
function bug()
do
local a = 2;
end
print(a);
local res = loadstring("a=1"); --somehow this brings 'a' visible
internally
--res();
print(a);
--Lua-5.4.4 find the next 'a' declaration as duplicated
--local a = 3; -- but if we comment this line 'a' is printed as
'nil' bellow
print(res, a);
end
print(a);
bug();
print(a);
====
====
/*
** Create a new local variable with the given 'name'. Return its index
** in the function.
*/
static int new_localvar (LexState *ls, TString *name) {
lua_State *L = ls->L;
FuncState *fs = ls->fs;
Dyndata *dyd = ls->dyd;
Vardesc *var;
/* START Check for duplicated varibale names in local scope */
int vidx, nactvar_n;
vidx = fs->bl ? fs->bl->nactvar + fs->firstlocal : fs->firstlocal;
//nactvar_n = dyd->actvar.n;
nactvar_n = fs->nactvar;
if(nactvar_n > fs->ndebugvars) nactvar_n = fs->ndebugvars;
for (; vidx < nactvar_n; ++vidx) {
Vardesc *vd = dyd->actvar.arr+vidx;
LocVar *lv = &fs->f->locvars[vd->vd.ridx];
if (lv && name == lv->varname) {
/* allow '_' duplicates */
const char *sname = getstr(name);
if(tsslen(name) == 1 && sname[0] == '_') break;
luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
"Name [%s] already declared", sname));
}
}
/* END Check for duplicated varibale names in local scope */
checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
MAXVARS, "local variables");
luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
var = &dyd->actvar.arr[dyd->actvar.n++];
var->vd.kind = VDKREG; /* default */
var->vd.name = name;
return dyd->actvar.n - 1 - fs->firstlocal;
}
====
Cheers !