[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Backport of Lua 5.2 "in" scoping #2
- From: Mike Pall <mikelu-1001@...>
- Date: Fri, 8 Jan 2010 19:11:04 +0100
Now includes the inheritance of the scoped environment for created
closures. It doesn't survive bytecode save/load, but it should be
good enough for experimentation.
The following example works now:
local env = { myprint = print }
in env do
function foo()
myprint("hello")
end
end
env.foo()
--Mike
--- lua-5.1.4/src/lparser.h 2007-12-27 14:02:25 +0100
+++ lua-5.1.4-in2/src/lparser.h 2010-01-08 19:07:19 +0100
@@ -70,6 +70,7 @@
int np; /* number of elements in `p' */
short nlocvars; /* number of elements in `locvars' */
lu_byte nactvar; /* number of active local variables */
+ lu_byte globalvar; /* global scope variable or NO_REG */
upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
} FuncState;
--- lua-5.1.4/src/lobject.h 2008-08-06 15:29:48 +0200
+++ lua-5.1.4-in2/src/lobject.h 2010-01-08 19:07:19 +0100
@@ -230,6 +230,7 @@
*/
typedef struct Proto {
CommonHeader;
+ lu_byte envslot;
TValue *k; /* constants used by the function */
Instruction *code;
struct Proto **p; /* functions defined inside the function */
--- lua-5.1.4/src/lparser.c 2007-12-28 16:32:23 +0100
+++ lua-5.1.4-in2/src/lparser.c 2010-01-08 19:07:19 +0100
@@ -248,8 +248,16 @@
static void singlevar (LexState *ls, expdesc *var) {
TString *varname = str_checkname(ls);
FuncState *fs = ls->fs;
- if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
- var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
+ if (singlevaraux(fs, varname, var, 1) == VGLOBAL) {
+ if (fs->globalvar == NO_REG)
+ var->u.s.info = luaK_stringK(fs, varname); /* info has global name */
+ else {
+ expdesc key;
+ var->u.s.info = fs->globalvar;
+ codestring(ls, &key, varname);
+ luaK_indexed(fs, var, &key);
+ }
+ }
}
@@ -329,6 +337,7 @@
lua_State *L = ls->L;
Proto *f = luaF_newproto(L);
fs->f = f;
+ f->envslot = ls->fs ? ls->fs->globalvar : NO_REG;
fs->prev = ls->fs; /* linked list of funcstates */
fs->ls = ls;
fs->L = L;
@@ -342,6 +351,7 @@
fs->nlocvars = 0;
fs->nactvar = 0;
fs->bl = NULL;
+ fs->globalvar = NO_REG;
f->source = ls->source;
f->maxstacksize = 2; /* registers 0/1 are always valid */
fs->h = luaH_new(L, 0, 0);
@@ -1268,6 +1278,24 @@
}
+static void instat (LexState *ls, int line) {
+ /* stat -> IN exp1 DO block END */
+ FuncState *fs = ls->fs;
+ int oldglobal = fs->globalvar;
+ BlockCnt bl;
+ enterblock(fs, &bl, 0);
+ new_localvarliteral(ls, "(env)", 0);
+ exp1(ls);
+ fs->globalvar = fs->nactvar;
+ adjustlocalvars(ls, 1);
+ checknext(ls, TK_DO);
+ chunk(ls);
+ check_match(ls, TK_END, TK_DO, line);
+ leaveblock(fs);
+ fs->globalvar = oldglobal;
+}
+
+
static int statement (LexState *ls) {
int line = ls->linenumber; /* may be needed for error messages */
switch (ls->t.token) {
@@ -1314,6 +1342,11 @@
breakstat(ls);
return 1; /* must be last statement */
}
+ case TK_IN: { /* stat -> instat */
+ luaX_next(ls); /* skip IN */
+ instat(ls, line);
+ return 0;
+ }
default: {
exprstat(ls);
return 0; /* to avoid warnings */
--- lua-5.1.4/src/lvm.c 2007-12-28 16:32:23 +0100
+++ lua-5.1.4-in2/src/lvm.c 2010-01-08 19:07:19 +0100
@@ -720,9 +720,17 @@
Proto *p;
Closure *ncl;
int nup, j;
+ Table *clenv;
p = cl->p->p[GETARG_Bx(i)];
+ if (p->envslot == NO_REG)
+ clenv = cl->env;
+ else {
+ if (!ttistable(base+p->envslot))
+ luaG_runerror(L, "environment must be a table");
+ clenv = hvalue(base+p->envslot);
+ }
nup = p->nups;
- ncl = luaF_newLclosure(L, nup, cl->env);
+ ncl = luaF_newLclosure(L, nup, clenv);
ncl->l.p = p;
for (j=0; j<nup; j++, pc++) {
if (GET_OPCODE(*pc) == OP_GETUPVAL)
--- lua-5.1.4/src/loadlib.c 2008-08-06 15:29:28 +0200
+++ lua-5.1.4-in2/src/loadlib.c 2010-01-08 19:07:19 +0100
@@ -565,7 +565,7 @@
lua_pushvalue(L, -1);
setfenv(L);
dooptions(L, loaded - 1);
- return 0;
+ return 1;
}
- References:
- Re: Lua registry, environment, and threads., Patrick Donnelly
- Re: Lua registry, environment, and threads., Roberto Ierusalimschy
- Re: Lua registry, environment, and threads., Christian Tellefsen
- Re: Lua registry, environment, and threads., Roberto Ierusalimschy
- Re: Lua registry, environment, and threads., Mark Hamburg
- Re: Lua registry, environment, and threads., Patrick Donnelly
- Re: Lua registry, environment, and threads., Roberto Ierusalimschy
- Re: Lua registry, environment, and threads., Enrico Colombini
- Re: Lua registry, environment, and threads., Roberto Ierusalimschy
- Backport of Lua 5.2 "in" scoping (was Re: Lua registry, environment, and threads.), Mike Pall