diff options
Diffstat (limited to 'lstate.c')
-rw-r--r-- | lstate.c | 53 |
1 files changed, 26 insertions, 27 deletions
@@ -97,35 +97,34 @@ void luaE_setdebt (global_State *g, l_mem debt) { | |||
97 | 97 | ||
98 | 98 | ||
99 | /* | 99 | /* |
100 | ** Increment count of "C calls" and check for overflows. In case of | 100 | ** Decrement count of "C calls" and check for overflows. In case of |
101 | ** a stack overflow, check appropriate error ("regular" overflow or | 101 | ** a stack overflow, check appropriate error ("regular" overflow or |
102 | ** overflow while handling stack overflow). | 102 | ** overflow while handling stack overflow). If 'nCcalls' is smaller |
103 | ** If 'nCcalls' is larger than LUAI_MAXCSTACK but smaller than | 103 | ** than CSTACKERR but larger than CSTACKMARK, it means it has just |
104 | ** LUAI_MAXCSTACK + CSTACKCF (plus 2 to avoid by-one errors), it means | 104 | ** entered the "overflow zone", so the function raises an overflow |
105 | ** it has just entered the "overflow zone", so the function raises an | 105 | ** error. If 'nCcalls' is smaller than CSTACKMARK (which means it is |
106 | ** overflow error. | 106 | ** already handling an overflow) but larger than CSTACKERRMARK, does |
107 | ** If 'nCcalls' is larger than LUAI_MAXCSTACK + CSTACKCF + 2 | 107 | ** not report an error (to allow message handling to work). Otherwise, |
108 | ** (which means it is already handling an overflow) but smaller than | 108 | ** report a stack overflow while handling a stack overflow (probably |
109 | ** 9/8 of LUAI_MAXCSTACK, does not report an error (to allow message | 109 | ** caused by a repeating error in the message handling function). |
110 | ** handling to work). | ||
111 | ** Otherwise, report a stack overflow while handling a stack overflow | ||
112 | ** (probably caused by a repeating error in the message handling | ||
113 | ** function). | ||
114 | */ | 110 | */ |
111 | |||
115 | void luaE_enterCcall (lua_State *L) { | 112 | void luaE_enterCcall (lua_State *L) { |
116 | int ncalls = getCcalls(L); | 113 | int ncalls = getCcalls(L); |
117 | L->nCcalls++; | 114 | L->nCcalls--; |
118 | if (ncalls >= LUAI_MAXCSTACK) { /* possible overflow? */ | 115 | if (ncalls <= CSTACKERR) { /* possible overflow? */ |
119 | luaE_freeCI(L); /* release unused CIs */ | 116 | luaE_freeCI(L); /* release unused CIs */ |
120 | ncalls = getCcalls(L); /* update call count */ | 117 | ncalls = getCcalls(L); /* update call count */ |
121 | if (ncalls >= LUAI_MAXCSTACK) { /* still overflow? */ | 118 | if (ncalls <= CSTACKERR) { /* still overflow? */ |
122 | if (ncalls <= LUAI_MAXCSTACK + CSTACKCF + 2) { | 119 | if (ncalls <= CSTACKERRMARK) /* below error-handling zone? */ |
123 | /* no error before increments; raise the error now */ | ||
124 | L->nCcalls += (CSTACKCF + 4); /* avoid raising it again */ | ||
125 | luaG_runerror(L, "C stack overflow"); | ||
126 | } | ||
127 | else if (ncalls >= (LUAI_MAXCSTACK + (LUAI_MAXCSTACK >> 3))) | ||
128 | luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ | 120 | luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ |
121 | else if (ncalls >= CSTACKMARK) { | ||
122 | /* not in error-handling zone; raise the error now */ | ||
123 | L->nCcalls = (CSTACKMARK - 1); /* enter error-handling zone */ | ||
124 | luaG_runerror(L, "C stack overflow1"); | ||
125 | } | ||
126 | /* else stack is in the error-handling zone; | ||
127 | allow message handler to work */ | ||
129 | } | 128 | } |
130 | } | 129 | } |
131 | } | 130 | } |
@@ -153,13 +152,13 @@ void luaE_freeCI (lua_State *L) { | |||
153 | CallInfo *ci = L->ci; | 152 | CallInfo *ci = L->ci; |
154 | CallInfo *next = ci->next; | 153 | CallInfo *next = ci->next; |
155 | ci->next = NULL; | 154 | ci->next = NULL; |
156 | L->nCcalls -= L->nci; /* subtract removed elements from 'nCcalls' */ | 155 | L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ |
157 | while ((ci = next) != NULL) { | 156 | while ((ci = next) != NULL) { |
158 | next = ci->next; | 157 | next = ci->next; |
159 | luaM_free(L, ci); | 158 | luaM_free(L, ci); |
160 | L->nci--; | 159 | L->nci--; |
161 | } | 160 | } |
162 | L->nCcalls += L->nci; /* adjust result */ | 161 | L->nCcalls -= L->nci; /* adjust result */ |
163 | } | 162 | } |
164 | 163 | ||
165 | 164 | ||
@@ -169,7 +168,7 @@ void luaE_freeCI (lua_State *L) { | |||
169 | void luaE_shrinkCI (lua_State *L) { | 168 | void luaE_shrinkCI (lua_State *L) { |
170 | CallInfo *ci = L->ci; | 169 | CallInfo *ci = L->ci; |
171 | CallInfo *next2; /* next's next */ | 170 | CallInfo *next2; /* next's next */ |
172 | L->nCcalls -= L->nci; /* subtract removed elements from 'nCcalls' */ | 171 | L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ |
173 | /* while there are two nexts */ | 172 | /* while there are two nexts */ |
174 | while (ci->next != NULL && (next2 = ci->next->next) != NULL) { | 173 | while (ci->next != NULL && (next2 = ci->next->next) != NULL) { |
175 | luaM_free(L, ci->next); /* free next */ | 174 | luaM_free(L, ci->next); /* free next */ |
@@ -178,7 +177,7 @@ void luaE_shrinkCI (lua_State *L) { | |||
178 | next2->previous = ci; | 177 | next2->previous = ci; |
179 | ci = next2; /* keep next's next */ | 178 | ci = next2; /* keep next's next */ |
180 | } | 179 | } |
181 | L->nCcalls += L->nci; /* adjust result */ | 180 | L->nCcalls -= L->nci; /* adjust result */ |
182 | } | 181 | } |
183 | 182 | ||
184 | 183 | ||
@@ -264,7 +263,7 @@ static void preinit_thread (lua_State *L, global_State *g) { | |||
264 | L->stacksize = 0; | 263 | L->stacksize = 0; |
265 | L->twups = L; /* thread has no upvalues */ | 264 | L->twups = L; /* thread has no upvalues */ |
266 | L->errorJmp = NULL; | 265 | L->errorJmp = NULL; |
267 | L->nCcalls = 0; | 266 | L->nCcalls = LUAI_MAXCSTACK + CSTACKERR; |
268 | L->hook = NULL; | 267 | L->hook = NULL; |
269 | L->hookmask = 0; | 268 | L->hookmask = 0; |
270 | L->basehookcount = 0; | 269 | L->basehookcount = 0; |