diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-07 11:25:26 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-07 11:25:26 -0200 |
commit | ad0704e40cc7b3135fedc6d40a522addb039e090 (patch) | |
tree | 4bcd104de4941239e09316efcee5e5e3566b8b81 /lapi.c | |
parent | 5a3f26f85558bedfa439027919d928abfdd00b6d (diff) | |
download | lua-ad0704e40cc7b3135fedc6d40a522addb039e090.tar.gz lua-ad0704e40cc7b3135fedc6d40a522addb039e090.tar.bz2 lua-ad0704e40cc7b3135fedc6d40a522addb039e090.zip |
back to 'CallInfo' (no gains with its removal)
Diffstat (limited to 'lapi.c')
-rw-r--r-- | lapi.c | 81 |
1 files changed, 39 insertions, 42 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 2.274 2017/11/03 12:12:30 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.273 2017/11/02 11:28:56 roberto Exp $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -10,7 +10,6 @@ | |||
10 | #include "lprefix.h" | 10 | #include "lprefix.h" |
11 | 11 | ||
12 | 12 | ||
13 | #include <limits.h> | ||
14 | #include <stdarg.h> | 13 | #include <stdarg.h> |
15 | #include <string.h> | 14 | #include <string.h> |
16 | 15 | ||
@@ -59,14 +58,15 @@ const char lua_ident[] = | |||
59 | 58 | ||
60 | 59 | ||
61 | static TValue *index2value (lua_State *L, int idx) { | 60 | static TValue *index2value (lua_State *L, int idx) { |
61 | CallInfo *ci = L->ci; | ||
62 | if (idx > 0) { | 62 | if (idx > 0) { |
63 | StkId o = L->func + idx; | 63 | StkId o = ci->func + idx; |
64 | api_check(L, idx < L->func->stkci.framesize, "unacceptable index"); | 64 | api_check(L, idx <= L->ci->top - (ci->func + 1), "unacceptable index"); |
65 | if (o >= L->top) return NONVALIDVALUE; | 65 | if (o >= L->top) return NONVALIDVALUE; |
66 | else return s2v(o); | 66 | else return s2v(o); |
67 | } | 67 | } |
68 | else if (!ispseudo(idx)) { /* negative index */ | 68 | else if (!ispseudo(idx)) { /* negative index */ |
69 | api_check(L, idx != 0 && -idx < L->func->stkci.framesize, "invalid index"); | 69 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); |
70 | return s2v(L->top + idx); | 70 | return s2v(L->top + idx); |
71 | } | 71 | } |
72 | else if (idx == LUA_REGISTRYINDEX) | 72 | else if (idx == LUA_REGISTRYINDEX) |
@@ -74,10 +74,10 @@ static TValue *index2value (lua_State *L, int idx) { | |||
74 | else { /* upvalues */ | 74 | else { /* upvalues */ |
75 | idx = LUA_REGISTRYINDEX - idx; | 75 | idx = LUA_REGISTRYINDEX - idx; |
76 | api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); | 76 | api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); |
77 | if (ttislcf(s2v(L->func))) /* light C function? */ | 77 | if (ttislcf(s2v(ci->func))) /* light C function? */ |
78 | return NONVALIDVALUE; /* it has no upvalues */ | 78 | return NONVALIDVALUE; /* it has no upvalues */ |
79 | else { | 79 | else { |
80 | CClosure *func = clCvalue(s2v(L->func)); | 80 | CClosure *func = clCvalue(s2v(ci->func)); |
81 | return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE; | 81 | return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE; |
82 | } | 82 | } |
83 | } | 83 | } |
@@ -85,13 +85,14 @@ static TValue *index2value (lua_State *L, int idx) { | |||
85 | 85 | ||
86 | 86 | ||
87 | static StkId index2stack (lua_State *L, int idx) { | 87 | static StkId index2stack (lua_State *L, int idx) { |
88 | CallInfo *ci = L->ci; | ||
88 | if (idx > 0) { | 89 | if (idx > 0) { |
89 | StkId o = L->func + idx; | 90 | StkId o = ci->func + idx; |
90 | api_check(L, o < L->top, "unacceptable index"); | 91 | api_check(L, o < L->top, "unacceptable index"); |
91 | return o; | 92 | return o; |
92 | } | 93 | } |
93 | else { /* non-positive index */ | 94 | else { /* non-positive index */ |
94 | api_check(L, idx != 0 && -idx <= L->top - (L->func + 1), "invalid index"); | 95 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); |
95 | api_check(L, !ispseudo(idx), "invalid index"); | 96 | api_check(L, !ispseudo(idx), "invalid index"); |
96 | return L->top + idx; | 97 | return L->top + idx; |
97 | } | 98 | } |
@@ -110,12 +111,10 @@ static void growstack (lua_State *L, void *ud) { | |||
110 | 111 | ||
111 | LUA_API int lua_checkstack (lua_State *L, int n) { | 112 | LUA_API int lua_checkstack (lua_State *L, int n) { |
112 | int res; | 113 | int res; |
113 | int frameuse = L->top - L->func; | 114 | CallInfo *ci = L->ci; |
114 | lua_lock(L); | 115 | lua_lock(L); |
115 | api_check(L, n >= 0, "negative 'n'"); | 116 | api_check(L, n >= 0, "negative 'n'"); |
116 | if (n >= USHRT_MAX - frameuse) | 117 | if (L->stack_last - L->top > n) /* stack large enough? */ |
117 | res = 0; /* frame size overflow */ | ||
118 | else if (L->stack_last - L->top > n) /* stack large enough? */ | ||
119 | res = 1; /* yes; check is OK */ | 118 | res = 1; /* yes; check is OK */ |
120 | else { /* no; need to grow stack */ | 119 | else { /* no; need to grow stack */ |
121 | int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; | 120 | int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; |
@@ -124,8 +123,8 @@ LUA_API int lua_checkstack (lua_State *L, int n) { | |||
124 | else /* try to grow stack */ | 123 | else /* try to grow stack */ |
125 | res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK); | 124 | res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK); |
126 | } | 125 | } |
127 | if (res && L->func->stkci.framesize < frameuse + n) | 126 | if (res && ci->top < L->top + n) |
128 | L->func->stkci.framesize = frameuse + n; /* adjust frame size */ | 127 | ci->top = L->top + n; /* adjust frame top */ |
129 | lua_unlock(L); | 128 | lua_unlock(L); |
130 | return res; | 129 | return res; |
131 | } | 130 | } |
@@ -137,7 +136,7 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { | |||
137 | lua_lock(to); | 136 | lua_lock(to); |
138 | api_checknelems(from, n); | 137 | api_checknelems(from, n); |
139 | api_check(from, G(from) == G(to), "moving among independent states"); | 138 | api_check(from, G(from) == G(to), "moving among independent states"); |
140 | api_check(from, functop(to->func) - to->top >= n, "stack overflow"); | 139 | api_check(from, to->ci->top - to->top >= n, "stack overflow"); |
141 | from->top -= n; | 140 | from->top -= n; |
142 | for (i = 0; i < n; i++) { | 141 | for (i = 0; i < n; i++) { |
143 | setobjs2s(to, to->top, from->top + i); | 142 | setobjs2s(to, to->top, from->top + i); |
@@ -176,17 +175,17 @@ LUA_API const lua_Number *lua_version (lua_State *L) { | |||
176 | LUA_API int lua_absindex (lua_State *L, int idx) { | 175 | LUA_API int lua_absindex (lua_State *L, int idx) { |
177 | return (idx > 0 || ispseudo(idx)) | 176 | return (idx > 0 || ispseudo(idx)) |
178 | ? idx | 177 | ? idx |
179 | : cast_int(L->top - L->func) + idx; | 178 | : cast_int(L->top - L->ci->func) + idx; |
180 | } | 179 | } |
181 | 180 | ||
182 | 181 | ||
183 | LUA_API int lua_gettop (lua_State *L) { | 182 | LUA_API int lua_gettop (lua_State *L) { |
184 | return cast_int(L->top - (L->func + 1)); | 183 | return cast_int(L->top - (L->ci->func + 1)); |
185 | } | 184 | } |
186 | 185 | ||
187 | 186 | ||
188 | LUA_API void lua_settop (lua_State *L, int idx) { | 187 | LUA_API void lua_settop (lua_State *L, int idx) { |
189 | StkId func = L->func; | 188 | StkId func = L->ci->func; |
190 | lua_lock(L); | 189 | lua_lock(L); |
191 | if (idx >= 0) { | 190 | if (idx >= 0) { |
192 | api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); | 191 | api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); |
@@ -244,7 +243,7 @@ LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { | |||
244 | api_checkvalidindex(L, to); | 243 | api_checkvalidindex(L, to); |
245 | setobj(L, to, fr); | 244 | setobj(L, to, fr); |
246 | if (isupvalue(toidx)) /* function upvalue? */ | 245 | if (isupvalue(toidx)) /* function upvalue? */ |
247 | luaC_barrier(L, clCvalue(s2v(L->func)), fr); | 246 | luaC_barrier(L, clCvalue(s2v(L->ci->func)), fr); |
248 | /* LUA_REGISTRYINDEX does not need gc barrier | 247 | /* LUA_REGISTRYINDEX does not need gc barrier |
249 | (collector revisits it before finishing collection) */ | 248 | (collector revisits it before finishing collection) */ |
250 | lua_unlock(L); | 249 | lua_unlock(L); |
@@ -932,24 +931,23 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) { | |||
932 | 931 | ||
933 | 932 | ||
934 | #define checkresults(L,na,nr) \ | 933 | #define checkresults(L,na,nr) \ |
935 | api_check(L, (nr) == LUA_MULTRET || \ | 934 | api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ |
936 | (functop(L->func) - L->top >= (nr) - (na)), \ | 935 | "results from function overflow current stack size") |
937 | "results from function overflow current frame size") | ||
938 | 936 | ||
939 | 937 | ||
940 | LUA_API void lua_callk (lua_State *L, int nargs, int nresults, | 938 | LUA_API void lua_callk (lua_State *L, int nargs, int nresults, |
941 | lua_KContext ctx, lua_KFunction k) { | 939 | lua_KContext ctx, lua_KFunction k) { |
942 | StkId func; | 940 | StkId func; |
943 | lua_lock(L); | 941 | lua_lock(L); |
944 | api_check(L, k == NULL || !isLua(L->func), | 942 | api_check(L, k == NULL || !isLua(L->ci), |
945 | "cannot use continuations inside hooks"); | 943 | "cannot use continuations inside hooks"); |
946 | api_checknelems(L, nargs+1); | 944 | api_checknelems(L, nargs+1); |
947 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); | 945 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); |
948 | checkresults(L, nargs, nresults); | 946 | checkresults(L, nargs, nresults); |
949 | func = L->top - (nargs+1); | 947 | func = L->top - (nargs+1); |
950 | if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ | 948 | if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ |
951 | L->func->stkci.u.c.k = k; /* save continuation */ | 949 | L->ci->u.c.k = k; /* save continuation */ |
952 | L->func->stkci.u.c.ctx = ctx; /* save context */ | 950 | L->ci->u.c.ctx = ctx; /* save context */ |
953 | luaD_call(L, func, nresults); /* do the call */ | 951 | luaD_call(L, func, nresults); /* do the call */ |
954 | } | 952 | } |
955 | else /* no continuation or no yieldable */ | 953 | else /* no continuation or no yieldable */ |
@@ -980,38 +978,37 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, | |||
980 | lua_KContext ctx, lua_KFunction k) { | 978 | lua_KContext ctx, lua_KFunction k) { |
981 | struct CallS c; | 979 | struct CallS c; |
982 | int status; | 980 | int status; |
983 | ptrdiff_t efunc; | 981 | ptrdiff_t func; |
984 | lua_lock(L); | 982 | lua_lock(L); |
985 | api_check(L, k == NULL || !isLua(L->func), | 983 | api_check(L, k == NULL || !isLua(L->ci), |
986 | "cannot use continuations inside hooks"); | 984 | "cannot use continuations inside hooks"); |
987 | api_checknelems(L, nargs+1); | 985 | api_checknelems(L, nargs+1); |
988 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); | 986 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); |
989 | checkresults(L, nargs, nresults); | 987 | checkresults(L, nargs, nresults); |
990 | if (errfunc == 0) | 988 | if (errfunc == 0) |
991 | efunc = 0; | 989 | func = 0; |
992 | else { | 990 | else { |
993 | StkId o = index2stack(L, errfunc); | 991 | StkId o = index2stack(L, errfunc); |
994 | efunc = savestack(L, o); | 992 | func = savestack(L, o); |
995 | } | 993 | } |
996 | c.func = L->top - (nargs+1); /* function to be called */ | 994 | c.func = L->top - (nargs+1); /* function to be called */ |
997 | if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */ | 995 | if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */ |
998 | c.nresults = nresults; /* do a 'conventional' protected call */ | 996 | c.nresults = nresults; /* do a 'conventional' protected call */ |
999 | status = luaD_pcall(L, f_call, &c, savestack(L, c.func), efunc); | 997 | status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); |
1000 | } | 998 | } |
1001 | else { /* prepare continuation (call is already protected by 'resume') */ | 999 | else { /* prepare continuation (call is already protected by 'resume') */ |
1002 | StkId func = L->func; | 1000 | CallInfo *ci = L->ci; |
1003 | func->stkci.u.c.k = k; /* save continuation */ | 1001 | ci->u.c.k = k; /* save continuation */ |
1004 | func->stkci.u.c.ctx = ctx; /* save context */ | 1002 | ci->u.c.ctx = ctx; /* save context */ |
1005 | /* save information for error recovery */ | 1003 | /* save information for error recovery */ |
1006 | func->stkci.u2.funcidx = c.func - func; | 1004 | ci->u2.funcidx = savestack(L, c.func); |
1007 | func->stkci.u.c.old_errfunc = L->errfunc; | 1005 | ci->u.c.old_errfunc = L->errfunc; |
1008 | L->errfunc = efunc; | 1006 | L->errfunc = func; |
1009 | setoah(callstatus(func), L->allowhook); /* save value of 'allowhook' */ | 1007 | setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ |
1010 | callstatus(func) |= CIST_YPCALL; /* function can do error recovery */ | 1008 | ci->callstatus |= CIST_YPCALL; /* function can do error recovery */ |
1011 | luaD_call(L, c.func, nresults); /* do the call */ | 1009 | luaD_call(L, c.func, nresults); /* do the call */ |
1012 | func = L->func; /* previous call can reallocate stack */ | 1010 | ci->callstatus &= ~CIST_YPCALL; |
1013 | callstatus(func) &= ~CIST_YPCALL; | 1011 | L->errfunc = ci->u.c.old_errfunc; |
1014 | L->errfunc = func->stkci.u.c.old_errfunc; | ||
1015 | status = LUA_OK; /* if it is here, there were no errors */ | 1012 | status = LUA_OK; /* if it is here, there were no errors */ |
1016 | } | 1013 | } |
1017 | adjustresults(L, nresults); | 1014 | adjustresults(L, nresults); |