From 1c328a191a8b86b7ad601cb9a935f1da5373fdf7 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 14 May 2002 14:52:22 -0300 Subject: [PATCH] no more `global' declarations --- lcode.c | 6 +- ldebug.c | 7 +-- lparser.c | 180 +++++++++++++----------------------------------------- lparser.h | 21 ++----- 4 files changed, 53 insertions(+), 161 deletions(-) diff --git a/lcode.c b/lcode.c index f057da2b..8a0ef0d9 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.102 2002/05/10 19:22:11 roberto Exp roberto $ +** $Id: lcode.c,v 1.103 2002/05/13 13:07:48 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -191,7 +191,7 @@ void luaK_reserveregs (FuncState *fs, int n) { static void freereg (FuncState *fs, int reg) { - if (reg >= fs->nactloc && reg < MAXSTACK) { + if (reg >= fs->nactvar && reg < MAXSTACK) { fs->freereg--; lua_assert(reg == fs->freereg); } @@ -375,7 +375,7 @@ int luaK_exp2anyreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); if (e->k == VNONRELOC) { if (!hasjumps(e)) return e->info; /* exp is already in a register */ - if (e->info >= fs->nactloc) { /* reg. is not a local? */ + if (e->info >= fs->nactvar) { /* reg. is not a local? */ luaK_exp2reg(fs, e, e->info); /* put value on it */ return e->info; } diff --git a/ldebug.c b/ldebug.c index 82c636bf..601190e7 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 1.113 2002/05/09 14:14:34 roberto Exp roberto $ +** $Id: ldebug.c,v 1.114 2002/05/13 13:09:00 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -432,11 +432,6 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, break; } case OP_GETTABLE: { - *name = luaF_getlocalname(p, GETARG_B(i)+1, pc); - if (*name && *name[0] == '*') { - *name = kname(p, GETARG_C(i)); - return "global"; - } *name = kname(p, GETARG_C(i)); return "field"; break; diff --git a/lparser.c b/lparser.c index 19b605bd..af9d0f6e 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.181 2002/05/10 19:22:11 roberto Exp roberto $ +** $Id: lparser.c,v 1.182 2002/05/13 13:09:00 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -23,15 +23,18 @@ + +#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) + + + /* ** nodes for block list (list of active blocks) */ typedef struct BlockCnt { struct BlockCnt *previous; /* chain */ int breaklist; /* list of jumps out of this loop */ - int nactloc; /* # active local variables outside the breakable structure */ - int nactvar; - int defaultglob; + int nactvar; /* # active local variables outside the breakable structure */ int upval; /* true if some variable in the block is an upvalue */ int isbreakable; /* true if `block' is a loop */ } BlockCnt; @@ -138,51 +141,26 @@ static int luaI_registerlocalvar (LexState *ls, TString *varname) { } -static vardesc *new_var (LexState *ls, int n) { - FuncState *fs = ls->fs; - luaX_checklimit(ls, fs->nactvar+n+1, MAXVARS, "variables"); - return &fs->actvar[fs->nactvar+n]; -} - - static void new_localvar (LexState *ls, TString *name, int n) { - vardesc *v = new_var(ls, n); - v->k = VLOCAL; - v->i = luaI_registerlocalvar(ls, name); - v->level = ls->fs->nactloc + n; + FuncState *fs = ls->fs; + luaX_checklimit(ls, fs->nactvar+n+1, MAXVARS, "local variables"); + fs->actvar[fs->nactvar+n] = luaI_registerlocalvar(ls, name); } static void adjustlocalvars (LexState *ls, int nvars) { FuncState *fs = ls->fs; - while (nvars--) { - lua_assert(fs->actvar[fs->nactvar].k == VLOCAL); - fs->f->locvars[fs->actvar[fs->nactvar].i].startpc = fs->pc; - fs->nactvar++; - fs->nactloc++; - } -} - - -static void adjustglobalvars (LexState *ls, int nvars, int level) { - FuncState *fs = ls->fs; - while (nvars--) { - fs->actvar[fs->nactvar].k = VGLOBAL; - fs->actvar[fs->nactvar].level = level; - fs->nactvar++; + fs->nactvar += nvars; + for (; nvars; nvars--) { + getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; } } static void removevars (LexState *ls, int tolevel) { FuncState *fs = ls->fs; - while (fs->nactvar > tolevel) { - fs->nactvar--; - if (fs->actvar[fs->nactvar].k == VLOCAL) { - fs->nactloc--; - fs->f->locvars[fs->actvar[fs->nactvar].i].endpc = fs->pc; - } - } + while (fs->nactvar > tolevel) + getlocvar(fs, --fs->nactvar).endpc = fs->pc; } @@ -210,80 +188,48 @@ static int indexupvalue (FuncState *fs, expdesc *v) { } -static vardesc *searchvar (FuncState *fs, TString *n) { +static int searchvar (FuncState *fs, TString *n) { int i; for (i=fs->nactvar-1; i >= 0; i--) { - vardesc *v = &fs->actvar[i]; - if (v->k == VLOCAL ? n == fs->f->locvars[v->i].varname - : n == tsvalue(&fs->f->k[v->i])) - return v; + if (n == getlocvar(fs, i).varname) + return i; } - return NULL; /* not found */ + return -1; /* not found */ } static void markupval (FuncState *fs, int level) { BlockCnt *bl = fs->bl; - while (bl && bl->nactloc > level) bl = bl->previous; + while (bl && bl->nactvar > level) bl = bl->previous; if (bl) bl->upval = 1; } -static int singlevar_aux (FuncState *fs, TString *n, expdesc *var, int nd) { - if (fs == NULL) { /* no more levels? */ - init_exp(var, VGLOBAL, NO_REG); /* default is free global */ - return VNIL; /* not found */ - } +static void singlevar (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) /* no more levels? */ + init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ else { - vardesc *v = searchvar(fs, n); /* look up at current level */ - if (v) { - if (v->level == NO_REG) { /* free global? */ - lua_assert(v->k == VGLOBAL); - init_exp(var, VGLOBAL, NO_REG); - } - else - init_exp(var, VLOCAL, v->level); - return v->k; + int v = searchvar(fs, n); /* look up at current level */ + if (v >= 0) { + init_exp(var, VLOCAL, v); + if (!base) + markupval(fs, v); /* local will be used as an upval */ } else { /* not found at current level; try upper one */ - int k = singlevar_aux(fs->prev, n, var, nd && fs->defaultglob == NO_REG); + singlevar(fs->prev, n, var, 0); if (var->k == VGLOBAL) { - if (k == VNIL && nd && fs->defaultglob != NO_REG) { - if (fs->defaultglob == NO_REG1) - luaX_syntaxerror(fs->ls, "undeclared global"); - init_exp(var, VLOCAL, fs->defaultglob); - k = VGLOBAL; /* now there is a declaration */ - } + if (base) + var->info = luaK_stringK(fs, n); /* info points to global name */ } else { /* LOCAL or UPVAL */ - if (var->k == VLOCAL) - markupval(fs->prev, var->info); /* local will be used as an upval */ var->info = indexupvalue(fs, var); var->k = VUPVAL; /* upvalue in this level */ } - return k; } } } -static void singlevar (FuncState *fs, TString *n, expdesc *var) { - int k = singlevar_aux(fs, n, var, 1); - if (k == VNIL || k == VGLOBAL) { /* global? */ - if (var->k == VGLOBAL) /* free global? */ - var->info = luaK_stringK(fs, n); - else { /* `indexed' global */ - expdesc e; - codestring(fs->ls, &e, n); - luaK_exp2anyreg(fs, var); - var->aux = luaK_exp2RK(fs, &e); - var->k = VINDEXED; - } - } -} - - - static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { FuncState *fs = ls->fs; int extra = nvars - nexps; @@ -308,24 +254,22 @@ static void code_params (LexState *ls, int nparams, int dots) { FuncState *fs = ls->fs; adjustlocalvars(ls, nparams); luaX_checklimit(ls, fs->nactvar, MAXPARAMS, "parameters"); - fs->f->numparams = cast(lu_byte, fs->nactloc); + fs->f->numparams = cast(lu_byte, fs->nactvar); fs->f->is_vararg = cast(lu_byte, dots); if (dots) create_local(ls, "arg"); - luaK_reserveregs(fs, fs->nactloc); /* reserve register for parameters */ + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ } static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) { bl->breaklist = NO_JUMP; bl->isbreakable = isbreakable; - bl->nactloc = fs->nactloc; bl->nactvar = fs->nactvar; - bl->defaultglob = fs->defaultglob; bl->upval = 0; bl->previous = fs->bl; fs->bl = bl; - lua_assert(fs->freereg == fs->nactloc); + lua_assert(fs->freereg == fs->nactvar); } @@ -334,11 +278,9 @@ static void leaveblock (FuncState *fs) { fs->bl = bl->previous; removevars(fs->ls, bl->nactvar); if (bl->upval) - luaK_codeABC(fs, OP_CLOSE, bl->nactloc, 0, 0); - lua_assert(bl->nactloc == fs->nactloc); + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); lua_assert(bl->nactvar == fs->nactvar); - fs->freereg = fs->nactloc; /* free registers */ - fs->defaultglob = bl->defaultglob; + fs->freereg = fs->nactvar; /* free registers */ luaK_patchtohere(fs, bl->breaklist); } @@ -373,9 +315,7 @@ static void open_func (LexState *ls, FuncState *fs) { fs->h = luaH_new(ls->L, 0, 0); fs->np = 0; fs->nlocvars = 0; - fs->nactloc = 0; fs->nactvar = 0; - fs->defaultglob = NO_REG; /* default is free globals */ fs->bl = NULL; f->code = NULL; f->source = ls->source; @@ -658,13 +598,13 @@ static void prefixexp (LexState *ls, expdesc *v) { return; } case TK_NAME: { - singlevar(ls->fs, str_checkname(ls), v); + singlevar(ls->fs, str_checkname(ls), v, 1); next(ls); return; } case '%': { /* for compatibility only */ next(ls); /* skip `%' */ - singlevar(ls->fs, str_checkname(ls), v); + singlevar(ls->fs, str_checkname(ls), v, 1); check_condition(ls, v->k == VUPVAL, "global upvalues are obsolete"); next(ls); return; @@ -1173,38 +1113,10 @@ static void localstat (LexState *ls) { } -static void globalstat (LexState *ls) { - /* stat -> GLOBAL NAME {`,' NAME} [IN exp] | GLOBAL IN exp */ - FuncState *fs = ls->fs; - int nvars = 0; - next(ls); /* skip GLOBAL */ - if (ls->t.token == TK_NAME) { - do { - vardesc *v = new_var(ls, nvars++); - v->i = luaK_stringK(ls->fs, str_checkname(ls)); - next(ls); /* skip name */ - } while (optional(ls, ',')); - } - if (!optional(ls, TK_IN)) { /* free globals? */ - if (nvars == 0) /* default - free is invalid */ - error_expected(ls, TK_IN); - adjustglobalvars(ls, nvars, NO_REG); /* mark globals as free */ - } - else { - int baselocal = fs->freereg; - int k = exp1(ls); - if (nvars == 0) - fs->defaultglob = (k == VNIL) ? NO_REG1 : baselocal; - adjustglobalvars(ls, nvars, baselocal); - create_local(ls, "*"); - } -} - - static int funcname (LexState *ls, expdesc *v) { /* funcname -> NAME {field} [`:' NAME] */ int needself = 0; - singlevar(ls->fs, str_checkname(ls), v); + singlevar(ls->fs, str_checkname(ls), v, 1); next(ls); /* skip var name */ while (ls->t.token == '.') { luaY_field(ls, v); @@ -1259,7 +1171,7 @@ static void retstat (LexState *ls) { return; } luaK_setcallreturns(fs, &e, LUA_MULTRET); - first = fs->nactloc; + first = fs->nactvar; nret = LUA_MULTRET; /* return all values */ } else { @@ -1267,7 +1179,7 @@ static void retstat (LexState *ls) { first = luaK_exp2anyreg(fs, &e); else { luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ - first = fs->nactloc; /* return all `active' values */ + first = fs->nactvar; /* return all `active' values */ lua_assert(nret == fs->freereg - first); } } @@ -1289,7 +1201,7 @@ static void breakstat (LexState *ls) { if (!bl) luaX_syntaxerror(ls, "no loop to break"); if (upval) - luaK_codeABC(fs, OP_CLOSE, bl->nactloc, 0, 0); + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); } @@ -1327,10 +1239,6 @@ static int statement (LexState *ls) { localstat(ls); return 0; } - case TK_GLOBAL: { /* stat -> globalstat */ - globalstat(ls); - return 0; - } case TK_RETURN: { /* stat -> retstat */ retstat(ls); return 1; /* must be last statement */ @@ -1391,8 +1299,8 @@ static void chunk (LexState *ls) { while (!islast && !block_follow(ls->t.token)) { islast = statement(ls); optional(ls, ';'); - lua_assert(ls->fs->freereg >= ls->fs->nactloc); - ls->fs->freereg = ls->fs->nactloc; /* free registers */ + lua_assert(ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ } } diff --git a/lparser.h b/lparser.h index 51ceb895..2b9c64d4 100644 --- a/lparser.h +++ b/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.42 2002/05/09 18:00:38 roberto Exp roberto $ +** $Id: lparser.h,v 1.43 2002/05/10 19:22:11 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -41,18 +41,9 @@ typedef struct expdesc { } expdesc; -/* describe declared variables */ -typedef struct vardesc { - int i; /* if local, its index in `locvars'; - if global, its name index in `k' */ - lu_byte k; - lu_byte level; /* if local, stack level; - if global, corresponding local (NO_REG for free globals) */ -} vardesc; - - struct BlockCnt; /* defined in lparser.c */ + /* state needed to generate code for a given function */ typedef struct FuncState { Proto *f; /* current function header */ @@ -63,16 +54,14 @@ typedef struct FuncState { struct BlockCnt *bl; /* chain of current blocks */ int pc; /* next position to code (equivalent to `ncode') */ int lasttarget; /* `pc' of last `jump target' */ - int jpc; /* list of jumps to `pc' */ + int jpc; /* list of pending jumps to `pc' */ int freereg; /* first free register */ - int defaultglob; /* where to look for non-declared globals */ int nk; /* number of elements in `k' */ int np; /* number of elements in `p' */ int nlocvars; /* number of elements in `locvars' */ - int nactloc; /* number of active local variables */ - int nactvar; /* number of elements in array `actvar' */ + int nactvar; /* number of active local variables */ expdesc upvalues[MAXUPVALUES]; /* upvalues */ - vardesc actvar[MAXVARS]; /* declared-variable stack */ + int actvar[MAXVARS]; /* declared-variable stack */ } FuncState;