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); |
