diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-03-26 17:58:11 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-03-26 17:58:11 -0300 |
commit | 064e406f67c0153999a5246deb1d616b06ee9bb0 (patch) | |
tree | f4483ab6ad6d55484829a0d8a27b8afa1768a36e /lapi.c | |
parent | 5c87f61e6b1567400d2bd8f452939bb948f16dda (diff) | |
download | lua-064e406f67c0153999a5246deb1d616b06ee9bb0.tar.gz lua-064e406f67c0153999a5246deb1d616b06ee9bb0.tar.bz2 lua-064e406f67c0153999a5246deb1d616b06ee9bb0.zip |
no more fenvs!
Diffstat (limited to 'lapi.c')
-rw-r--r-- | lapi.c | 97 |
1 files changed, 29 insertions, 68 deletions
@@ -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 | ||
42 | static 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 | |||
52 | static TValue *index2addr (lua_State *L, int idx) { | 42 | static 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) { | |||
195 | static void moveto (lua_State *L, TValue *fr, int idx) { | 180 | static 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 | ||
214 | LUA_API void lua_replace (lua_State *L, int idx) { | 191 | LUA_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 | ||
634 | LUA_API void lua_getfenv (lua_State *L, int idx) { | 608 | LUA_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 | ||
750 | LUA_API int lua_setfenv (lua_State *L, int idx) { | 718 | LUA_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); |