mirror of https://github.com/rusefi/lua.git
Bug: 'Vardesc' array can be reallocated in 'localstat'
A reference to a 'Vardesc*' (as done by 'localstat') can be invalidated by the creation of any new variable.
This commit is contained in:
parent
9a37dc0ce6
commit
e70f275f32
27
lparser.c
27
lparser.c
|
@ -187,9 +187,10 @@ static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Create a new local variable with the given 'name'.
|
** Create a new local variable with the given 'name'. Return its index
|
||||||
|
** in the function.
|
||||||
*/
|
*/
|
||||||
static Vardesc *new_localvar (LexState *ls, TString *name) {
|
static int new_localvar (LexState *ls, TString *name, int kind) {
|
||||||
lua_State *L = ls->L;
|
lua_State *L = ls->L;
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
Dyndata *dyd = ls->dyd;
|
Dyndata *dyd = ls->dyd;
|
||||||
|
@ -199,13 +200,14 @@ static Vardesc *new_localvar (LexState *ls, TString *name) {
|
||||||
luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
|
luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
|
||||||
dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
|
dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
|
||||||
var = &dyd->actvar.arr[dyd->actvar.n++];
|
var = &dyd->actvar.arr[dyd->actvar.n++];
|
||||||
var->vd.kind = VDKREG; /* default is a regular variable */
|
var->vd.kind = kind;
|
||||||
var->vd.name = name;
|
var->vd.name = name;
|
||||||
return var;
|
return dyd->actvar.n - 1 - fs->firstlocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define new_localvarliteral(ls,v) \
|
#define new_localvarliteral(ls,v) \
|
||||||
new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));
|
new_localvar(ls, \
|
||||||
|
luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1), VDKREG);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -945,7 +947,7 @@ static void parlist (LexState *ls) {
|
||||||
do {
|
do {
|
||||||
switch (ls->t.token) {
|
switch (ls->t.token) {
|
||||||
case TK_NAME: { /* param -> NAME */
|
case TK_NAME: { /* param -> NAME */
|
||||||
new_localvar(ls, str_checkname(ls));
|
new_localvar(ls, str_checkname(ls), VDKREG);
|
||||||
nparams++;
|
nparams++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1551,7 +1553,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
|
||||||
new_localvarliteral(ls, "(for state)");
|
new_localvarliteral(ls, "(for state)");
|
||||||
new_localvarliteral(ls, "(for state)");
|
new_localvarliteral(ls, "(for state)");
|
||||||
new_localvarliteral(ls, "(for state)");
|
new_localvarliteral(ls, "(for state)");
|
||||||
new_localvar(ls, varname);
|
new_localvar(ls, varname, VDKREG);
|
||||||
checknext(ls, '=');
|
checknext(ls, '=');
|
||||||
exp1(ls); /* initial value */
|
exp1(ls); /* initial value */
|
||||||
checknext(ls, ',');
|
checknext(ls, ',');
|
||||||
|
@ -1580,9 +1582,9 @@ static void forlist (LexState *ls, TString *indexname) {
|
||||||
new_localvarliteral(ls, "(for state)");
|
new_localvarliteral(ls, "(for state)");
|
||||||
new_localvarliteral(ls, "(for state)");
|
new_localvarliteral(ls, "(for state)");
|
||||||
/* create declared variables */
|
/* create declared variables */
|
||||||
new_localvar(ls, indexname);
|
new_localvar(ls, indexname, VDKREG);
|
||||||
while (testnext(ls, ',')) {
|
while (testnext(ls, ',')) {
|
||||||
new_localvar(ls, str_checkname(ls));
|
new_localvar(ls, str_checkname(ls), VDKREG);
|
||||||
nvars++;
|
nvars++;
|
||||||
}
|
}
|
||||||
checknext(ls, TK_IN);
|
checknext(ls, TK_IN);
|
||||||
|
@ -1706,7 +1708,7 @@ static void localfunc (LexState *ls) {
|
||||||
expdesc b;
|
expdesc b;
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
int fvar = fs->nactvar; /* function's variable index */
|
int fvar = fs->nactvar; /* function's variable index */
|
||||||
new_localvar(ls, str_checkname(ls)); /* new local variable */
|
new_localvar(ls, str_checkname(ls), VDKREG); /* new local variable */
|
||||||
adjustlocalvars(ls, 1); /* enter its scope */
|
adjustlocalvars(ls, 1); /* enter its scope */
|
||||||
body(ls, &b, 0, ls->linenumber); /* function created in next register */
|
body(ls, &b, 0, ls->linenumber); /* function created in next register */
|
||||||
/* debug information will only see the variable after this point! */
|
/* debug information will only see the variable after this point! */
|
||||||
|
@ -1746,13 +1748,13 @@ static void localstat (LexState *ls) {
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
int toclose = -1; /* index of to-be-closed variable (if any) */
|
int toclose = -1; /* index of to-be-closed variable (if any) */
|
||||||
Vardesc *var; /* last variable */
|
Vardesc *var; /* last variable */
|
||||||
|
int ivar; /* index of last variable */
|
||||||
int nvars = 0;
|
int nvars = 0;
|
||||||
int nexps;
|
int nexps;
|
||||||
expdesc e;
|
expdesc e;
|
||||||
do {
|
do {
|
||||||
int kind = getlocalattribute(ls);
|
int kind = getlocalattribute(ls);
|
||||||
var = new_localvar(ls, str_checkname(ls));
|
ivar = new_localvar(ls, str_checkname(ls), kind);
|
||||||
var->vd.kind = kind;
|
|
||||||
if (kind == RDKTOCLOSE) { /* to-be-closed? */
|
if (kind == RDKTOCLOSE) { /* to-be-closed? */
|
||||||
if (toclose != -1) /* one already present? */
|
if (toclose != -1) /* one already present? */
|
||||||
luaK_semerror(ls, "multiple to-be-closed variables in local list");
|
luaK_semerror(ls, "multiple to-be-closed variables in local list");
|
||||||
|
@ -1766,6 +1768,7 @@ static void localstat (LexState *ls) {
|
||||||
e.k = VVOID;
|
e.k = VVOID;
|
||||||
nexps = 0;
|
nexps = 0;
|
||||||
}
|
}
|
||||||
|
var = getlocalvardesc(fs, ivar); /* get last variable */
|
||||||
if (nvars == nexps && /* no adjustments? */
|
if (nvars == nexps && /* no adjustments? */
|
||||||
var->vd.kind == RDKCONST && /* last variable is const? */
|
var->vd.kind == RDKCONST && /* last variable is const? */
|
||||||
luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */
|
luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */
|
||||||
|
|
Loading…
Reference in New Issue