aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-03-26 17:58:11 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-03-26 17:58:11 -0300
commit064e406f67c0153999a5246deb1d616b06ee9bb0 (patch)
treef4483ab6ad6d55484829a0d8a27b8afa1768a36e /lapi.c
parent5c87f61e6b1567400d2bd8f452939bb948f16dda (diff)
downloadlua-064e406f67c0153999a5246deb1d616b06ee9bb0.tar.gz
lua-064e406f67c0153999a5246deb1d616b06ee9bb0.tar.bz2
lua-064e406f67c0153999a5246deb1d616b06ee9bb0.zip
no more fenvs!
Diffstat (limited to 'lapi.c')
-rw-r--r--lapi.c97
1 files changed, 29 insertions, 68 deletions
diff --git a/lapi.c b/lapi.c
index 3a0dbdae..adae47b8 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.115 2010/03/22 18:28:03 roberto Exp roberto $ 2** $Id: lapi.c,v 2.116 2010/03/25 19:37:23 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -39,16 +39,6 @@ const char lua_ident[] =
39 "invalid index") 39 "invalid index")
40 40
41 41
42static Table *getcurrenv (lua_State *L) {
43 if (L->ci->previous == NULL) /* no enclosing function? */
44 return G(L)->l_gt; /* use global table as environment */
45 else {
46 Closure *func = curr_func(L);
47 return func->c.env;
48 }
49}
50
51
52static TValue *index2addr (lua_State *L, int idx) { 42static TValue *index2addr (lua_State *L, int idx) {
53 CallInfo *ci = L->ci; 43 CallInfo *ci = L->ci;
54 if (idx > 0) { 44 if (idx > 0) {
@@ -61,20 +51,15 @@ static TValue *index2addr (lua_State *L, int idx) {
61 api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); 51 api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
62 return L->top + idx; 52 return L->top + idx;
63 } 53 }
64 else switch (idx) { /* pseudo-indices */ 54 else if (idx == LUA_REGISTRYINDEX)
65 case LUA_REGISTRYINDEX: return &G(L)->l_registry; 55 return &G(L)->l_registry;
66 case LUA_ENVIRONINDEX: { 56 else { /* upvalues */
67 sethvalue(L, &L->env, getcurrenv(L)); 57 Closure *func = curr_func(L);
68 return &L->env; 58 idx = LUA_REGISTRYINDEX - idx;
69 } 59 api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large");
70 default: { 60 return (idx <= func->c.nupvalues)
71 Closure *func = curr_func(L); 61 ? &func->c.upvalue[idx-1]
72 idx = LUA_ENVIRONINDEX - idx; 62 : cast(TValue *, luaO_nilobject);
73 api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large");
74 return (idx <= func->c.nupvalues)
75 ? &func->c.upvalue[idx-1]
76 : cast(TValue *, luaO_nilobject);
77 }
78 } 63 }
79} 64}
80 65
@@ -195,17 +180,9 @@ LUA_API void lua_insert (lua_State *L, int idx) {
195static void moveto (lua_State *L, TValue *fr, int idx) { 180static void moveto (lua_State *L, TValue *fr, int idx) {
196 TValue *to = index2addr(L, idx); 181 TValue *to = index2addr(L, idx);
197 api_checkvalidindex(L, to); 182 api_checkvalidindex(L, to);
198 if (idx == LUA_ENVIRONINDEX) { 183 setobj(L, to, fr);
199 Closure *func = curr_func(L); 184 if (idx < LUA_REGISTRYINDEX) /* function upvalue? */
200 api_check(L, ttistable(fr), "table expected"); 185 luaC_barrier(L, curr_func(L), fr);
201 func->c.env = hvalue(fr);
202 luaC_barrier(L, func, fr);
203 }
204 else {
205 setobj(L, to, fr);
206 if (idx < LUA_ENVIRONINDEX) /* function upvalue? */
207 luaC_barrier(L, curr_func(L), fr);
208 }
209 /* LUA_REGISTRYINDEX does not need gc barrier 186 /* LUA_REGISTRYINDEX does not need gc barrier
210 (collector revisits it before finishing collection) */ 187 (collector revisits it before finishing collection) */
211} 188}
@@ -213,9 +190,6 @@ static void moveto (lua_State *L, TValue *fr, int idx) {
213 190
214LUA_API void lua_replace (lua_State *L, int idx) { 191LUA_API void lua_replace (lua_State *L, int idx) {
215 lua_lock(L); 192 lua_lock(L);
216 /* explicit test for incompatible code */
217 if (idx == LUA_ENVIRONINDEX && L->ci->previous == NULL)
218 luaG_runerror(L, "no calling environment");
219 api_checknelems(L, 1); 193 api_checknelems(L, 1);
220 moveto(L, L->top - 1, idx); 194 moveto(L, L->top - 1, idx);
221 L->top--; 195 L->top--;
@@ -503,7 +477,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
503 api_checknelems(L, n); 477 api_checknelems(L, n);
504 api_check(L, n <= UCHAR_MAX, "upvalue index too large"); 478 api_check(L, n <= UCHAR_MAX, "upvalue index too large");
505 luaC_checkGC(L); 479 luaC_checkGC(L);
506 cl = luaF_newCclosure(L, n, getcurrenv(L)); 480 cl = luaF_newCclosure(L, n);
507 cl->c.f = fn; 481 cl->c.f = fn;
508 L->top -= n; 482 L->top -= n;
509 while (n--) 483 while (n--)
@@ -631,22 +605,16 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
631} 605}
632 606
633 607
634LUA_API void lua_getfenv (lua_State *L, int idx) { 608LUA_API void lua_getenv (lua_State *L, int idx) {
635 StkId o; 609 StkId o;
636 lua_lock(L); 610 lua_lock(L);
637 o = index2addr(L, idx); 611 o = index2addr(L, idx);
638 api_checkvalidindex(L, o); 612 api_checkvalidindex(L, o);
639 switch (ttype(o)) { 613 api_check(L, ttisuserdata(o), "userdata expected");
640 case LUA_TFUNCTION: 614 if (uvalue(o)->env) {
641 sethvalue(L, L->top, clvalue(o)->c.env); 615 sethvalue(L, L->top, uvalue(o)->env);
642 break; 616 } else
643 case LUA_TUSERDATA: 617 setnilvalue(L->top);
644 sethvalue(L, L->top, uvalue(o)->env);
645 break;
646 default:
647 setnilvalue(L->top);
648 break;
649 }
650 api_incr_top(L); 618 api_incr_top(L);
651 lua_unlock(L); 619 lua_unlock(L);
652} 620}
@@ -747,29 +715,22 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
747} 715}
748 716
749 717
750LUA_API int lua_setfenv (lua_State *L, int idx) { 718LUA_API void lua_setenv (lua_State *L, int idx) {
751 StkId o; 719 StkId o;
752 int res = 1;
753 lua_lock(L); 720 lua_lock(L);
754 api_checknelems(L, 1); 721 api_checknelems(L, 1);
755 o = index2addr(L, idx); 722 o = index2addr(L, idx);
756 api_checkvalidindex(L, o); 723 api_checkvalidindex(L, o);
757 api_check(L, ttistable(L->top - 1), "table expected"); 724 api_check(L, ttisuserdata(o), "userdata expected");
758 switch (ttype(o)) { 725 if (ttisnil(L->top - 1))
759 case LUA_TFUNCTION: 726 uvalue(o)->env = NULL;
760 clvalue(o)->c.env = hvalue(L->top - 1); 727 else {
761 break; 728 api_check(L, ttistable(L->top - 1), "table expected");
762 case LUA_TUSERDATA: 729 uvalue(o)->env = hvalue(L->top - 1);
763 uvalue(o)->env = hvalue(L->top - 1); 730 luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
764 break;
765 default:
766 res = 0;
767 break;
768 } 731 }
769 if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
770 L->top--; 732 L->top--;
771 lua_unlock(L); 733 lua_unlock(L);
772 return res;
773} 734}
774 735
775 736
@@ -1072,7 +1033,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1072 Udata *u; 1033 Udata *u;
1073 lua_lock(L); 1034 lua_lock(L);
1074 luaC_checkGC(L); 1035 luaC_checkGC(L);
1075 u = luaS_newudata(L, size, getcurrenv(L)); 1036 u = luaS_newudata(L, size, NULL);
1076 setuvalue(L, L->top, u); 1037 setuvalue(L, L->top, u);
1077 api_incr_top(L); 1038 api_incr_top(L);
1078 lua_unlock(L); 1039 lua_unlock(L);