[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Multiple functions: was the gc
- From: Andrew Teirney <andrew@...>
- Date: Fri, 25 Aug 2006 02:54:29 +1200
D Burgess wrote:
> lua_getfenv() and getfenv() need to handle the case when
> c.env == NULL
>
Also, getcurrenv() in lapi.c needs a little thought.
I have attached another patch which i feel is a lot nicer in its
implementation than the previous 5 minute job i threw together.
The lua_getfenv has been resolved to return nil should the function not
have an environment. I have removed the lua_clearfenv()/clearfenv()
functions in favour of using lua_setfenv/setfenv() with nil as the
special value that indicates the environment should be the "dynamic
environment". By that meaning use the environment of the current thread
as opposed to the inherited environment at creation time.
With regards to the getcurrenv(), it does depend on what one wants
really. My understanding, the lua implementors can correct me if i am
wrong, but the environments are inherited from the enclosing closure,
this is for both closures and userdata. If one considers this nil
environment to be a dynamic environment then it would make sense that
new objects inherit the dynamic environment, this is represented as no
environment.
Naturally i cannot guarantee that this works and is bug free ;-)
Andrew
diff -r lua-5.1.1/src/lapi.c lua-5.1.1.patched/src/lapi.c
64c64
< sethvalue(L, &L->env, func->c.env);
---
> sethvalue(L, &L->env, func->c.env ? func->c.env : hvalue(gt(L)));
616a617
> setnilvalue(L->top);
619c620,621
< sethvalue(L, L->top, clvalue(o)->c.env);
---
> if (clvalue(o)->c.env)
> sethvalue(L, L->top, clvalue(o)->c.env);
622c624,625
< sethvalue(L, L->top, uvalue(o)->env);
---
> if (uvalue(o)->env)
> sethvalue(L, L->top, uvalue(o)->env);
627,629d629
< default:
< setnilvalue(L->top);
< break;
737d736
< api_check(L, ttistable(L->top - 1));
740c739,740
< clvalue(o)->c.env = hvalue(L->top - 1);
---
> api_check(L, ttistable(L->top - 1) || ttisnil(L->top - 1));
> clvalue(o)->c.env = ttisnil(L->top - 1) ? NULL : hvalue(L->top - 1);
742a743
> api_check(L, ttistable(L->top - 1));
745a747
> api_check(L, ttistable(L->top - 1));
diff -r lua-5.1.1/src/lbaselib.c lua-5.1.1.patched/src/lbaselib.c
144c144
< luaL_checktype(L, 2, LUA_TTABLE);
---
> int t = lua_type(L, 2);
145a146,150
> if (lua_isfunction(L, -1))
> luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
> "nil or table expected");
> else
> luaL_checktype(L, 2, LUA_TTABLE);
diff -r lua-5.1.1/src/lgc.c lua-5.1.1.patched/src/lgc.c
225c225,226
< markobject(g, cl->c.env);
---
> if (cl->c.env)
> markobject(g, cl->c.env);
diff -r lua-5.1.1/src/lvm.c lua-5.1.1.patched/src/lvm.c
433c433
< Protect(luaV_gettable(L, &g, rb, ra));
---
> Protect(luaV_gettable(L, cl->env ? &g : gt(L), rb, ra));
444c444
< Protect(luaV_settable(L, &g, KBx(i), ra));
---
> Protect(luaV_settable(L, cl->env ? &g : gt(L), KBx(i), ra));