@ -212,27 +212,28 @@ static int new_localvar (LexState *ls, TString *name) {
/*
/*
* * Return the " variable description " ( Vardesc ) of a given
* * Return the " variable description " ( Vardesc ) of a given variable .
* * variable
* * ( Unless noted otherwise , all variables are referred to by their
* * compiler indices . )
*/
*/
static Vardesc * getlocalvardesc ( FuncState * fs , int i ) {
static Vardesc * getlocalvardesc ( FuncState * fs , int v idx ) {
return & fs - > ls - > dyd - > actvar . arr [ fs - > firstlocal + i ] ;
return & fs - > ls - > dyd - > actvar . arr [ fs - > firstlocal + v idx ] ;
}
}
/*
/*
* * Convert ' nvar ' ( number of active variables at some point ) to
* * Convert ' nvar ' , a compiler index level , to it corresponding
* * number of variables in the stack at that point .
* * stack index level . For that , search for the highest variable
* * below that level that is in the stack and uses its stack
* * index ( ' sidx ' ) .
*/
*/
static int stacklevel ( FuncState * fs , int nvar ) {
static int stacklevel ( FuncState * fs , int nvar ) {
while ( nvar > 0 ) {
while ( nvar - - > 0 ) {
Vardesc * vd = getlocalvardesc ( fs , nvar - 1 ) ;
Vardesc * vd = getlocalvardesc ( fs , nvar ) ; /* get variable */
if ( vd - > vd . kind ! = RDKCTC ) /* is in the stack? */
if ( vd - > vd . kind ! = RDKCTC ) /* is in the stack? */
return vd - > vd . sidx + 1 ;
return vd - > vd . sidx + 1 ;
else
nvar - - ; /* try previous variable */
}
}
return 0 ; /* no variables */
return 0 ; /* no variables in the stack */
}
}
@ -245,10 +246,10 @@ int luaY_nvarstack (FuncState *fs) {
/*
/*
* * Get the debug - information entry for current variable ' i ' .
* * Get the debug - information entry for current variable ' vidx ' .
*/
*/
static LocVar * localdebuginfo ( FuncState * fs , int i ) {
static LocVar * localdebuginfo ( FuncState * fs , int v idx ) {
Vardesc * vd = getlocalvardesc ( fs , i ) ;
Vardesc * vd = getlocalvardesc ( fs , v idx ) ;
if ( vd - > vd . kind = = RDKCTC )
if ( vd - > vd . kind = = RDKCTC )
return NULL ; /* no debug info. for constants */
return NULL ; /* no debug info. for constants */
else {
else {
@ -259,14 +260,20 @@ static LocVar *localdebuginfo (FuncState *fs, int i) {
}
}
static void init_var ( FuncState * fs , expdesc * e , int i ) {
/*
* * Create an expression representing variable ' vidx '
*/
static void init_var ( FuncState * fs , expdesc * e , int vidx ) {
e - > f = e - > t = NO_JUMP ;
e - > f = e - > t = NO_JUMP ;
e - > k = VLOCAL ;
e - > k = VLOCAL ;
e - > u . var . vidx = i ;
e - > u . var . vidx = v idx ;
e - > u . var . sidx = getlocalvardesc ( fs , i ) - > vd . sidx ;
e - > u . var . sidx = getlocalvardesc ( fs , v idx ) - > vd . sidx ;
}
}
/*
* * Raises an error if variable described by ' e ' is read only
*/
static void check_readonly ( LexState * ls , expdesc * e ) {
static void check_readonly ( LexState * ls , expdesc * e ) {
FuncState * fs = ls - > fs ;
FuncState * fs = ls - > fs ;
TString * varname = NULL ; /* to be set if variable is const */
TString * varname = NULL ; /* to be set if variable is const */
@ -306,8 +313,8 @@ static void adjustlocalvars (LexState *ls, int nvars) {
int stklevel = luaY_nvarstack ( fs ) ;
int stklevel = luaY_nvarstack ( fs ) ;
int i ;
int i ;
for ( i = 0 ; i < nvars ; i + + ) {
for ( i = 0 ; i < nvars ; i + + ) {
int var idx = fs - > nactvar + + ;
int vidx = fs - > nactvar + + ;
Vardesc * var = getlocalvardesc ( fs , var idx ) ;
Vardesc * var = getlocalvardesc ( fs , vidx ) ;
var - > vd . sidx = stklevel + + ;
var - > vd . sidx = stklevel + + ;
var - > vd . pidx = registerlocalvar ( ls , fs , var - > vd . name ) ;
var - > vd . pidx = registerlocalvar ( ls , fs , var - > vd . name ) ;
}
}
@ -377,7 +384,8 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
/*
/*
* * Look for an active local variable with the name ' n ' in the
* * Look for an active local variable with the name ' n ' in the
* * function ' fs ' .
* * function ' fs ' . If found , initialize ' var ' with it and return
* * its expression kind ; otherwise return - 1.
*/
*/
static int searchvar ( FuncState * fs , TString * n , expdesc * var ) {
static int searchvar ( FuncState * fs , TString * n , expdesc * var ) {
int i ;
int i ;
@ -1592,7 +1600,7 @@ static void forlist (LexState *ls, TString *indexname) {
line = ls - > linenumber ;
line = ls - > linenumber ;
adjust_assign ( ls , 4 , explist ( ls , & e ) , & e ) ;
adjust_assign ( ls , 4 , explist ( ls , & e ) , & e ) ;
adjustlocalvars ( ls , 4 ) ; /* control variables */
adjustlocalvars ( ls , 4 ) ; /* control variables */
markupval ( fs , luaY_nvarstack ( fs ) ) ; /* state may create an upvalue */
markupval ( fs , fs - > nactvar ) ; /* last control var. must be closed */
luaK_checkstack ( fs , 3 ) ; /* extra space to call generator */
luaK_checkstack ( fs , 3 ) ; /* extra space to call generator */
forbody ( ls , base , line , nvars - 4 , 1 ) ;
forbody ( ls , base , line , nvars - 4 , 1 ) ;
}
}
@ -1730,7 +1738,7 @@ static int getlocalattribute (LexState *ls) {
luaK_semerror ( ls ,
luaK_semerror ( ls ,
luaO_pushfstring ( ls - > L , " unknown attribute '%s' " , attr ) ) ;
luaO_pushfstring ( ls - > L , " unknown attribute '%s' " , attr ) ) ;
}
}
return VDKREG ;
return VDKREG ; /* regular variable */
}
}
@ -1739,7 +1747,7 @@ static void checktoclose (LexState *ls, int level) {
FuncState * fs = ls - > fs ;
FuncState * fs = ls - > fs ;
markupval ( fs , level + 1 ) ;
markupval ( fs , level + 1 ) ;
fs - > bl - > insidetbc = 1 ; /* in the scope of a to-be-closed variable */
fs - > bl - > insidetbc = 1 ; /* in the scope of a to-be-closed variable */
luaK_codeABC ( fs , OP_TBC , level , 0 , 0 ) ;
luaK_codeABC ( fs , OP_TBC , stack level( fs , level ) , 0 , 0 ) ;
}
}
}
}
@ -1749,18 +1757,18 @@ 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 , kind ; /* index and kind of last variable */
int vidx , kind ; /* index and kind of last variable */
int nvars = 0 ;
int nvars = 0 ;
int nexps ;
int nexps ;
expdesc e ;
expdesc e ;
do {
do {
ivar = new_localvar ( ls , str_checkname ( ls ) ) ;
vidx = new_localvar ( ls , str_checkname ( ls ) ) ;
kind = getlocalattribute ( ls ) ;
kind = getlocalattribute ( ls ) ;
getlocalvardesc ( fs , ivar ) - > vd . kind = kind ;
getlocalvardesc ( fs , vidx ) - > 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 " ) ;
toclose = luaY_nvarstack ( fs ) + nvars ;
toclose = fs - > nactvar + nvars ;
}
}
nvars + + ;
nvars + + ;
} while ( testnext ( ls , ' , ' ) ) ;
} while ( testnext ( ls , ' , ' ) ) ;
@ -1770,7 +1778,7 @@ static void localstat (LexState *ls) {
e . k = VVOID ;
e . k = VVOID ;
nexps = 0 ;
nexps = 0 ;
}
}
var = getlocalvardesc ( fs , ivar ) ; /* get last variable */
var = getlocalvardesc ( fs , vidx ) ; /* 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? */