mirror of
https://github.com/lua/lua
synced 2025-04-16 01:42:48 +03:00
new way to store local-variable information.
This commit is contained in:
parent
bd39db46ed
commit
c85162be27
23
lfunc.c
23
lfunc.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lfunc.c,v 1.28 2000/08/08 20:42:07 roberto Exp roberto $
|
** $Id: lfunc.c,v 1.29 2000/08/09 19:16:57 roberto Exp roberto $
|
||||||
** Auxiliary functions to manipulate prototypes and closures
|
** Auxiliary functions to manipulate prototypes and closures
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -43,6 +43,7 @@ Proto *luaF_newproto (lua_State *L) {
|
|||||||
f->kproto = NULL;
|
f->kproto = NULL;
|
||||||
f->nkproto = 0;
|
f->nkproto = 0;
|
||||||
f->locvars = NULL;
|
f->locvars = NULL;
|
||||||
|
f->nlocvars = 0;
|
||||||
f->next = L->rootproto;
|
f->next = L->rootproto;
|
||||||
L->rootproto = f;
|
L->rootproto = f;
|
||||||
f->marked = 0;
|
f->marked = 0;
|
||||||
@ -73,19 +74,15 @@ void luaF_freeclosure (lua_State *L, Closure *c) {
|
|||||||
** Look for n-th local variable at line `line' in function `func'.
|
** Look for n-th local variable at line `line' in function `func'.
|
||||||
** Returns NULL if not found.
|
** Returns NULL if not found.
|
||||||
*/
|
*/
|
||||||
const char *luaF_getlocalname (const Proto *func, int local_number, int pc) {
|
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
|
||||||
int count = 0;
|
int i;
|
||||||
const char *varname = NULL;
|
for (i = 0; i<f->nlocvars && f->locvars[i].startpc <= pc; i++) {
|
||||||
LocVar *lv = func->locvars;
|
if (pc < f->locvars[i].endpc) { /* is variable active? */
|
||||||
for (; lv->pc != -1 && lv->pc <= pc; lv++) {
|
local_number--;
|
||||||
if (lv->varname) { /* register */
|
if (local_number == 0)
|
||||||
if (++count == local_number)
|
return f->locvars[i].varname->str;
|
||||||
varname = lv->varname->str;
|
|
||||||
}
|
}
|
||||||
else /* unregister */
|
|
||||||
if (--count < local_number)
|
|
||||||
varname = NULL;
|
|
||||||
}
|
}
|
||||||
return varname;
|
return NULL; /* not found */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
lgc.c
7
lgc.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 1.61 2000/08/08 20:42:07 roberto Exp roberto $
|
** $Id: lgc.c,v 1.62 2000/08/09 19:16:57 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -42,9 +42,8 @@ static void protomark (Proto *f) {
|
|||||||
strmark(f->kstr[i]);
|
strmark(f->kstr[i]);
|
||||||
for (i=0; i<f->nkproto; i++)
|
for (i=0; i<f->nkproto; i++)
|
||||||
protomark(f->kproto[i]);
|
protomark(f->kproto[i]);
|
||||||
for (i=0; f->locvars[i].pc != -1; i++) /* mark local-variable names */
|
for (i=0; i<f->nlocvars; i++) /* mark local-variable names */
|
||||||
if (f->locvars[i].varname)
|
strmark(f->locvars[i].varname);
|
||||||
strmark(f->locvars[i].varname);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
lobject.h
10
lobject.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 1.72 2000/08/08 18:26:05 roberto Exp roberto $
|
** $Id: lobject.h,v 1.73 2000/08/21 14:34:43 roberto Exp roberto $
|
||||||
** Type definitions for Lua objects
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -124,15 +124,17 @@ typedef struct Proto {
|
|||||||
int marked;
|
int marked;
|
||||||
/* debug information */
|
/* debug information */
|
||||||
int *lineinfo; /* map from opcodes to source lines */
|
int *lineinfo; /* map from opcodes to source lines */
|
||||||
|
int nlocvars;
|
||||||
|
struct LocVar *locvars; /* information about local variables */
|
||||||
int lineDefined;
|
int lineDefined;
|
||||||
TString *source;
|
TString *source;
|
||||||
struct LocVar *locvars; /* ends with line = -1 */
|
|
||||||
} Proto;
|
} Proto;
|
||||||
|
|
||||||
|
|
||||||
typedef struct LocVar {
|
typedef struct LocVar {
|
||||||
TString *varname; /* NULL signals end of scope */
|
TString *varname;
|
||||||
int pc;
|
int startpc; /* first point where variable is active */
|
||||||
|
int endpc; /* first point where variable is dead */
|
||||||
} LocVar;
|
} LocVar;
|
||||||
|
|
||||||
|
|
||||||
|
63
lparser.c
63
lparser.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 1.108 2000/08/14 17:46:27 roberto Exp roberto $
|
** $Id: lparser.c,v 1.109 2000/08/15 13:18:28 roberto Exp roberto $
|
||||||
** LL(1) Parser and code generator for Lua
|
** LL(1) Parser and code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -150,40 +150,32 @@ static int checkname (LexState *ls) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void luaI_registerlocalvar (LexState *ls, TString *varname, int pc) {
|
static int luaI_registerlocalvar (LexState *ls, TString *varname) {
|
||||||
FuncState *fs = ls->fs;
|
Proto *f = ls->fs->f;
|
||||||
Proto *f = fs->f;
|
luaM_growvector(ls->L, f->locvars, f->nlocvars, 1, LocVar, "", MAX_INT);
|
||||||
luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT);
|
f->locvars[f->nlocvars].varname = varname;
|
||||||
f->locvars[fs->nvars].varname = varname;
|
return f->nlocvars++;
|
||||||
f->locvars[fs->nvars].pc = pc;
|
|
||||||
fs->nvars++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void new_localvar (LexState *ls, TString *name, int n) {
|
static void new_localvar (LexState *ls, TString *name, int n) {
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
luaX_checklimit(ls, fs->nlocalvar+n+1, MAXLOCALS, "local variables");
|
luaX_checklimit(ls, fs->nactloc+n+1, MAXLOCALS, "local variables");
|
||||||
fs->localvar[fs->nlocalvar+n] = name;
|
fs->actloc[fs->nactloc+n] = luaI_registerlocalvar(ls, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void adjustlocalvars (LexState *ls, int nvars) {
|
static void adjustlocalvars (LexState *ls, int nvars) {
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
int i;
|
while (nvars--)
|
||||||
/* `pc' is first opcode where variable is already active */
|
fs->f->locvars[fs->actloc[fs->nactloc++]].startpc = fs->pc;
|
||||||
for (i=fs->nlocalvar; i<fs->nlocalvar+nvars; i++)
|
|
||||||
luaI_registerlocalvar(ls, fs->localvar[i], fs->pc);
|
|
||||||
fs->nlocalvar += nvars;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void removelocalvars (LexState *ls, int nvars) {
|
static void removelocalvars (LexState *ls, int nvars) {
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
int i;
|
while (nvars--)
|
||||||
/* `pc' is first opcode where variable is already dead */
|
fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc;
|
||||||
for (i=0;i<nvars;i++)
|
|
||||||
luaI_registerlocalvar(ls, NULL, fs->pc);
|
|
||||||
fs->nlocalvar -= nvars;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -197,8 +189,8 @@ static int search_local (LexState *ls, TString *n, expdesc *var) {
|
|||||||
int level = 0;
|
int level = 0;
|
||||||
for (fs=ls->fs; fs; fs=fs->prev) {
|
for (fs=ls->fs; fs; fs=fs->prev) {
|
||||||
int i;
|
int i;
|
||||||
for (i=fs->nlocalvar-1; i >= 0; i--) {
|
for (i=fs->nactloc-1; i >= 0; i--) {
|
||||||
if (n == fs->localvar[i]) {
|
if (n == fs->f->locvars[fs->actloc[i]].varname) {
|
||||||
var->k = VLOCAL;
|
var->k = VLOCAL;
|
||||||
var->u.index = i;
|
var->u.index = i;
|
||||||
return level;
|
return level;
|
||||||
@ -270,14 +262,14 @@ static void adjust_mult_assign (LexState *ls, int nvars, int nexps) {
|
|||||||
static void code_params (LexState *ls, int nparams, int dots) {
|
static void code_params (LexState *ls, int nparams, int dots) {
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
adjustlocalvars(ls, nparams);
|
adjustlocalvars(ls, nparams);
|
||||||
luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters");
|
luaX_checklimit(ls, fs->nactloc, MAXPARAMS, "parameters");
|
||||||
fs->f->numparams = fs->nlocalvar; /* `self' could be there already */
|
fs->f->numparams = fs->nactloc; /* `self' could be there already */
|
||||||
fs->f->is_vararg = dots;
|
fs->f->is_vararg = dots;
|
||||||
if (dots) {
|
if (dots) {
|
||||||
new_localvarstr(ls, "arg", 0);
|
new_localvarstr(ls, "arg", 0);
|
||||||
adjustlocalvars(ls, 1);
|
adjustlocalvars(ls, 1);
|
||||||
}
|
}
|
||||||
luaK_deltastack(fs, fs->nlocalvar); /* count parameters in the stack */
|
luaK_deltastack(fs, fs->nactloc); /* count parameters in the stack */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -316,7 +308,7 @@ static void open_func (LexState *ls, FuncState *fs) {
|
|||||||
fs->L = ls->L;
|
fs->L = ls->L;
|
||||||
ls->fs = fs;
|
ls->fs = fs;
|
||||||
fs->stacklevel = 0;
|
fs->stacklevel = 0;
|
||||||
fs->nlocalvar = 0;
|
fs->nactloc = 0;
|
||||||
fs->nupvalues = 0;
|
fs->nupvalues = 0;
|
||||||
fs->bl = NULL;
|
fs->bl = NULL;
|
||||||
fs->f = f;
|
fs->f = f;
|
||||||
@ -330,7 +322,6 @@ static void open_func (LexState *ls, FuncState *fs) {
|
|||||||
f->maxstacksize = 0;
|
f->maxstacksize = 0;
|
||||||
f->numparams = 0; /* default for main chunk */
|
f->numparams = 0; /* default for main chunk */
|
||||||
f->is_vararg = 0; /* default for main chunk */
|
f->is_vararg = 0; /* default for main chunk */
|
||||||
fs->nvars = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -344,8 +335,8 @@ static void close_func (LexState *ls) {
|
|||||||
luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
|
luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
|
||||||
luaM_reallocvector(L, f->knum, f->nknum, Number);
|
luaM_reallocvector(L, f->knum, f->nknum, Number);
|
||||||
luaM_reallocvector(L, f->kproto, f->nkproto, Proto *);
|
luaM_reallocvector(L, f->kproto, f->nkproto, Proto *);
|
||||||
luaI_registerlocalvar(ls, NULL, -1); /* flag end of vector */
|
removelocalvars(ls, fs->nactloc);
|
||||||
luaM_reallocvector(L, f->locvars, fs->nvars, LocVar);
|
luaM_reallocvector(L, f->locvars, f->nlocvars, LocVar);
|
||||||
luaM_reallocvector(L, f->lineinfo, fs->nlineinfo+1, int);
|
luaM_reallocvector(L, f->lineinfo, fs->nlineinfo+1, int);
|
||||||
f->lineinfo[fs->nlineinfo] = MAX_INT; /* end flag */
|
f->lineinfo[fs->nlineinfo] = MAX_INT; /* end flag */
|
||||||
ls->fs = fs->prev;
|
ls->fs = fs->prev;
|
||||||
@ -370,7 +361,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) {
|
|||||||
|
|
||||||
|
|
||||||
/*============================================================*/
|
/*============================================================*/
|
||||||
/* GRAMAR RULES */
|
/* GRAMMAR RULES */
|
||||||
/*============================================================*/
|
/*============================================================*/
|
||||||
|
|
||||||
|
|
||||||
@ -768,10 +759,10 @@ static int block_follow (int token) {
|
|||||||
static void block (LexState *ls) {
|
static void block (LexState *ls) {
|
||||||
/* block -> chunk */
|
/* block -> chunk */
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
int nlocalvar = fs->nlocalvar;
|
int nactloc = fs->nactloc;
|
||||||
chunk(ls);
|
chunk(ls);
|
||||||
luaK_adjuststack(fs, fs->nlocalvar - nlocalvar); /* remove local variables */
|
luaK_adjuststack(fs, fs->nactloc - nactloc); /* remove local variables */
|
||||||
removelocalvars(ls, fs->nlocalvar - nlocalvar);
|
removelocalvars(ls, fs->nactloc - nactloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1009,8 +1000,8 @@ static void retstat (LexState *ls) {
|
|||||||
next(ls); /* skip RETURN */
|
next(ls); /* skip RETURN */
|
||||||
if (!block_follow(ls->t.token))
|
if (!block_follow(ls->t.token))
|
||||||
explist1(ls); /* optional return values */
|
explist1(ls); /* optional return values */
|
||||||
luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar);
|
luaK_code1(fs, OP_RETURN, ls->fs->nactloc);
|
||||||
fs->stacklevel = fs->nlocalvar; /* removes all temp values */
|
fs->stacklevel = fs->nactloc; /* removes all temp values */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1127,7 +1118,7 @@ static void chunk (LexState *ls) {
|
|||||||
while (!islast && !block_follow(ls->t.token)) {
|
while (!islast && !block_follow(ls->t.token)) {
|
||||||
islast = stat(ls);
|
islast = stat(ls);
|
||||||
optional(ls, ';');
|
optional(ls, ';');
|
||||||
LUA_ASSERT(ls->fs->stacklevel == ls->fs->nlocalvar,
|
LUA_ASSERT(ls->fs->stacklevel == ls->fs->nactloc,
|
||||||
"stack size != # local vars");
|
"stack size != # local vars");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.h,v 1.21 2000/08/08 18:26:05 roberto Exp roberto $
|
** $Id: lparser.h,v 1.22 2000/08/08 20:42:07 roberto Exp roberto $
|
||||||
** LL(1) Parser and code generator for Lua
|
** LL(1) Parser and code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -45,14 +45,13 @@ typedef struct FuncState {
|
|||||||
int lasttarget; /* `pc' of last `jump target' */
|
int lasttarget; /* `pc' of last `jump target' */
|
||||||
int jlt; /* list of jumps to `lasttarged' */
|
int jlt; /* list of jumps to `lasttarged' */
|
||||||
int stacklevel; /* number of values on activation register */
|
int stacklevel; /* number of values on activation register */
|
||||||
int nlocalvar; /* number of active local variables */
|
int nactloc; /* number of active local variables */
|
||||||
int nupvalues; /* number of upvalues */
|
int nupvalues; /* number of upvalues */
|
||||||
int nvars; /* number of entries in f->locvars */
|
|
||||||
int lastline; /* line where last `lineinfo' was generated */
|
int lastline; /* line where last `lineinfo' was generated */
|
||||||
int nlineinfo; /* index of next `lineinfo' to be generated */
|
int nlineinfo; /* index of next `lineinfo' to be generated */
|
||||||
struct Breaklabel *bl; /* chain of breakable blocks */
|
struct Breaklabel *bl; /* chain of breakable blocks */
|
||||||
expdesc upvalues[MAXUPVALUES]; /* upvalues */
|
expdesc upvalues[MAXUPVALUES]; /* upvalues */
|
||||||
TString *localvar[MAXLOCALS]; /* store local variable names */
|
int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */
|
||||||
} FuncState;
|
} FuncState;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user