aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-08-31 11:26:28 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-08-31 11:26:28 -0300
commit4a714cebd1783fe6e5beafc2ce602df56a78723b (patch)
tree542cd6c71ea3bb026c2de6fe63f50c4c327908f0 /lapi.c
parent5b6be84106f41752624b9ee66dbd9d21eda7e0ce (diff)
downloadlua-4a714cebd1783fe6e5beafc2ce602df56a78723b.tar.gz
lua-4a714cebd1783fe6e5beafc2ce602df56a78723b.tar.bz2
lua-4a714cebd1783fe6e5beafc2ce602df56a78723b.zip
API checks now have explanatory messages
Diffstat (limited to 'lapi.c')
-rw-r--r--lapi.c49
1 files changed, 26 insertions, 23 deletions
diff --git a/lapi.c b/lapi.c
index eb1f3786..0850d1b8 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.87 2009/07/15 18:37:19 roberto Exp roberto $ 2** $Id: lapi.c,v 2.88 2009/08/07 16:17:41 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*/
@@ -35,21 +35,23 @@ const char lua_ident[] =
35 35
36 36
37 37
38#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func)) 38#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
39 "not enough elements in the stack")
39 40
40#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) 41#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject, \
42 "invalid index")
41 43
42 44
43static TValue *index2addr (lua_State *L, int idx) { 45static TValue *index2addr (lua_State *L, int idx) {
44 CallInfo *ci = L->ci; 46 CallInfo *ci = L->ci;
45 if (idx > 0) { 47 if (idx > 0) {
46 TValue *o = ci->func + idx; 48 TValue *o = ci->func + idx;
47 api_check(L, idx <= ci->top - (ci->func + 1)); 49 api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
48 if (o >= L->top) return cast(TValue *, luaO_nilobject); 50 if (o >= L->top) return cast(TValue *, luaO_nilobject);
49 else return o; 51 else return o;
50 } 52 }
51 else if (idx > LUA_REGISTRYINDEX) { 53 else if (idx > LUA_REGISTRYINDEX) {
52 api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1)); 54 api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
53 return L->top + idx; 55 return L->top + idx;
54 } 56 }
55 else switch (idx) { /* pseudo-indices */ 57 else switch (idx) { /* pseudo-indices */
@@ -63,7 +65,7 @@ static TValue *index2addr (lua_State *L, int idx) {
63 default: { 65 default: {
64 Closure *func = curr_func(L); 66 Closure *func = curr_func(L);
65 idx = LUA_GLOBALSINDEX - idx; 67 idx = LUA_GLOBALSINDEX - idx;
66 api_check(L, idx <= UCHAR_MAX + 1); 68 api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large");
67 return (idx <= func->c.nupvalues) 69 return (idx <= func->c.nupvalues)
68 ? &func->c.upvalue[idx-1] 70 ? &func->c.upvalue[idx-1]
69 : cast(TValue *, luaO_nilobject); 71 : cast(TValue *, luaO_nilobject);
@@ -110,8 +112,8 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
110 if (from == to) return; 112 if (from == to) return;
111 lua_lock(to); 113 lua_lock(to);
112 api_checknelems(from, n); 114 api_checknelems(from, n);
113 api_check(from, G(from) == G(to)); 115 api_check(from, G(from) == G(to), "moving among independent states");
114 api_check(from, to->ci->top - to->top >= n); 116 api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
115 from->top -= n; 117 from->top -= n;
116 for (i = 0; i < n; i++) { 118 for (i = 0; i < n; i++) {
117 setobj2s(to, to->top++, from->top + i); 119 setobj2s(to, to->top++, from->top + i);
@@ -152,13 +154,13 @@ LUA_API void lua_settop (lua_State *L, int idx) {
152 StkId func = L->ci->func; 154 StkId func = L->ci->func;
153 lua_lock(L); 155 lua_lock(L);
154 if (idx >= 0) { 156 if (idx >= 0) {
155 api_check(L, idx <= L->stack_last - (func + 1)); 157 api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
156 while (L->top < (func + 1) + idx) 158 while (L->top < (func + 1) + idx)
157 setnilvalue(L->top++); 159 setnilvalue(L->top++);
158 L->top = (func + 1) + idx; 160 L->top = (func + 1) + idx;
159 } 161 }
160 else { 162 else {
161 api_check(L, -(idx+1) <= (L->top - (func + 1))); 163 api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
162 L->top += idx+1; /* `subtract' index (index is negative) */ 164 L->top += idx+1; /* `subtract' index (index is negative) */
163 } 165 }
164 lua_unlock(L); 166 lua_unlock(L);
@@ -199,7 +201,7 @@ LUA_API void lua_replace (lua_State *L, int idx) {
199 api_checkvalidindex(L, o); 201 api_checkvalidindex(L, o);
200 if (idx == LUA_ENVIRONINDEX) { 202 if (idx == LUA_ENVIRONINDEX) {
201 Closure *func = curr_func(L); 203 Closure *func = curr_func(L);
202 api_check(L, ttistable(L->top - 1)); 204 api_check(L, ttistable(L->top - 1), "table expected");
203 func->c.env = hvalue(L->top - 1); 205 func->c.env = hvalue(L->top - 1);
204 luaC_barrier(L, func, L->top - 1); 206 luaC_barrier(L, func, L->top - 1);
205 } 207 }
@@ -298,7 +300,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
298 case LUA_OPEQ: i = equalobj(L, o1, o2); break; 300 case LUA_OPEQ: i = equalobj(L, o1, o2); break;
299 case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break; 301 case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
300 case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break; 302 case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
301 default: api_check(L, 0); i = 0; 303 default: api_check(L, 0, "invalid option"); i = 0;
302 } 304 }
303 lua_unlock(L); 305 lua_unlock(L);
304 return i; 306 return i;
@@ -480,7 +482,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
480 Closure *cl; 482 Closure *cl;
481 lua_lock(L); 483 lua_lock(L);
482 api_checknelems(L, n); 484 api_checknelems(L, n);
483 api_check(L, n <= UCHAR_MAX); 485 api_check(L, n <= UCHAR_MAX, "upvalue index too large");
484 luaC_checkGC(L); 486 luaC_checkGC(L);
485 cl = luaF_newCclosure(L, n, getcurrenv(L)); 487 cl = luaF_newCclosure(L, n, getcurrenv(L));
486 cl->c.f = fn; 488 cl->c.f = fn;
@@ -551,7 +553,7 @@ LUA_API void lua_rawget (lua_State *L, int idx) {
551 StkId t; 553 StkId t;
552 lua_lock(L); 554 lua_lock(L);
553 t = index2addr(L, idx); 555 t = index2addr(L, idx);
554 api_check(L, ttistable(t)); 556 api_check(L, ttistable(t), "table expected");
555 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); 557 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
556 lua_unlock(L); 558 lua_unlock(L);
557} 559}
@@ -561,7 +563,7 @@ LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
561 StkId o; 563 StkId o;
562 lua_lock(L); 564 lua_lock(L);
563 o = index2addr(L, idx); 565 o = index2addr(L, idx);
564 api_check(L, ttistable(o)); 566 api_check(L, ttistable(o), "table expected");
565 setobj2s(L, L->top, luaH_getint(hvalue(o), n)); 567 setobj2s(L, L->top, luaH_getint(hvalue(o), n));
566 api_incr_top(L); 568 api_incr_top(L);
567 lua_unlock(L); 569 lua_unlock(L);
@@ -669,7 +671,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
669 lua_lock(L); 671 lua_lock(L);
670 api_checknelems(L, 2); 672 api_checknelems(L, 2);
671 t = index2addr(L, idx); 673 t = index2addr(L, idx);
672 api_check(L, ttistable(t)); 674 api_check(L, ttistable(t), "table expected");
673 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); 675 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
674 luaC_barriert(L, hvalue(t), L->top-1); 676 luaC_barriert(L, hvalue(t), L->top-1);
675 L->top -= 2; 677 L->top -= 2;
@@ -682,7 +684,7 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
682 lua_lock(L); 684 lua_lock(L);
683 api_checknelems(L, 1); 685 api_checknelems(L, 1);
684 o = index2addr(L, idx); 686 o = index2addr(L, idx);
685 api_check(L, ttistable(o)); 687 api_check(L, ttistable(o), "table expected");
686 setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1); 688 setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1);
687 luaC_barriert(L, hvalue(o), L->top-1); 689 luaC_barriert(L, hvalue(o), L->top-1);
688 L->top--; 690 L->top--;
@@ -700,7 +702,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
700 if (ttisnil(L->top - 1)) 702 if (ttisnil(L->top - 1))
701 mt = NULL; 703 mt = NULL;
702 else { 704 else {
703 api_check(L, ttistable(L->top - 1)); 705 api_check(L, ttistable(L->top - 1), "table expected");
704 mt = hvalue(L->top - 1); 706 mt = hvalue(L->top - 1);
705 } 707 }
706 switch (ttype(obj)) { 708 switch (ttype(obj)) {
@@ -736,7 +738,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
736 api_checknelems(L, 1); 738 api_checknelems(L, 1);
737 o = index2addr(L, idx); 739 o = index2addr(L, idx);
738 api_checkvalidindex(L, o); 740 api_checkvalidindex(L, o);
739 api_check(L, ttistable(L->top - 1)); 741 api_check(L, ttistable(L->top - 1), "table expected");
740 switch (ttype(o)) { 742 switch (ttype(o)) {
741 case LUA_TFUNCTION: 743 case LUA_TFUNCTION:
742 clvalue(o)->c.env = hvalue(L->top - 1); 744 clvalue(o)->c.env = hvalue(L->top - 1);
@@ -764,7 +766,8 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
764 766
765 767
766#define checkresults(L,na,nr) \ 768#define checkresults(L,na,nr) \
767 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) 769 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
770 "results from function overflow current stack size")
768 771
769 772
770LUA_API int lua_getctx (lua_State *L, int *ctx) { 773LUA_API int lua_getctx (lua_State *L, int *ctx) {
@@ -780,8 +783,8 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
780 lua_CFunction k) { 783 lua_CFunction k) {
781 StkId func; 784 StkId func;
782 lua_lock(L); 785 lua_lock(L);
783 /* cannot use continuations inside hooks */ 786 api_check(L, k == NULL || !isLua(L->ci),
784 api_check(L, k == NULL || !isLua(L->ci)); 787 "cannot use continuations inside hooks");
785 api_checknelems(L, nargs+1); 788 api_checknelems(L, nargs+1);
786 checkresults(L, nargs, nresults); 789 checkresults(L, nargs, nresults);
787 func = L->top - (nargs+1); 790 func = L->top - (nargs+1);
@@ -1006,7 +1009,7 @@ LUA_API int lua_next (lua_State *L, int idx) {
1006 int more; 1009 int more;
1007 lua_lock(L); 1010 lua_lock(L);
1008 t = index2addr(L, idx); 1011 t = index2addr(L, idx);
1009 api_check(L, ttistable(t)); 1012 api_check(L, ttistable(t), "table expected");
1010 more = luaH_next(L, hvalue(t), L->top - 1); 1013 more = luaH_next(L, hvalue(t), L->top - 1);
1011 if (more) { 1014 if (more) {
1012 api_incr_top(L); 1015 api_incr_top(L);