aboutsummaryrefslogtreecommitdiff
path: root/lstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'lstate.c')
-rw-r--r--lstate.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/lstate.c b/lstate.c
index 5ee024fc..04a9e064 100644
--- a/lstate.c
+++ b/lstate.c
@@ -99,24 +99,42 @@ void luaE_setdebt (global_State *g, l_mem debt) {
99/* 99/*
100** Increment count of "C calls" and check for overflows. In case of 100** Increment 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). If 'nCalls' is larger than 102** overflow while handling stack overflow).
103** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but 103** If 'nCcalls' is larger than LUAI_MAXCCALLS but smaller than
104** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to 104** LUAI_MAXCCALLS + CSTACKCF (plus 2 to avoid by-one errors), it means
105** allow overflow handling to work) 105** it has just entered the "overflow zone", so the function raises an
106** overflow error.
107** If 'nCcalls' is larger than LUAI_MAXCCALLS + CSTACKCF + 2
108** (which means it is already handling an overflow) but smaller than
109** 9/8 of LUAI_MAXCCALLS, does not report an error (to allow message
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).
106*/ 114*/
107void luaE_incCcalls (lua_State *L) { 115void luaE_enterCcall (lua_State *L) {
108 if (++L->nCcalls >= LUAI_MAXCCALLS) { 116 int ncalls = getCcalls(L);
109 if (L->nCcalls == LUAI_MAXCCALLS) 117 L->nCcalls++;
110 luaG_runerror(L, "C stack overflow"); 118 if (ncalls >= LUAI_MAXCCALLS) { /* possible overflow? */
111 else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) 119 luaE_freeCI(L); /* release unused CIs */
112 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ 120 ncalls = getCcalls(L); /* update call count */
121 if (ncalls >= LUAI_MAXCCALLS) { /* still overflow? */
122 if (ncalls <= LUAI_MAXCCALLS + CSTACKCF + 2) {
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_MAXCCALLS + (LUAI_MAXCCALLS >> 3)))
128 luaD_throw(L, LUA_ERRERR); /* error while handling stack error */
129 }
113 } 130 }
114} 131}
115 132
116 133
117CallInfo *luaE_extendCI (lua_State *L) { 134CallInfo *luaE_extendCI (lua_State *L) {
118 CallInfo *ci; 135 CallInfo *ci;
119 luaE_incCcalls(L); 136 lua_assert(L->ci->next == NULL);
137 luaE_enterCcall(L);
120 ci = luaM_new(L, CallInfo); 138 ci = luaM_new(L, CallInfo);
121 lua_assert(L->ci->next == NULL); 139 lua_assert(L->ci->next == NULL);
122 L->ci->next = ci; 140 L->ci->next = ci;
@@ -135,13 +153,13 @@ void luaE_freeCI (lua_State *L) {
135 CallInfo *ci = L->ci; 153 CallInfo *ci = L->ci;
136 CallInfo *next = ci->next; 154 CallInfo *next = ci->next;
137 ci->next = NULL; 155 ci->next = NULL;
138 L->nCcalls -= L->nci; /* to subtract removed elements from 'nCcalls' */ 156 L->nCcalls -= L->nci; /* subtract removed elements from 'nCcalls' */
139 while ((ci = next) != NULL) { 157 while ((ci = next) != NULL) {
140 next = ci->next; 158 next = ci->next;
141 luaM_free(L, ci); 159 luaM_free(L, ci);
142 L->nci--; 160 L->nci--;
143 } 161 }
144 L->nCcalls += L->nci; /* to subtract removed elements from 'nCcalls' */ 162 L->nCcalls += L->nci; /* adjust result */
145} 163}
146 164
147 165
@@ -151,7 +169,7 @@ void luaE_freeCI (lua_State *L) {
151void luaE_shrinkCI (lua_State *L) { 169void luaE_shrinkCI (lua_State *L) {
152 CallInfo *ci = L->ci; 170 CallInfo *ci = L->ci;
153 CallInfo *next2; /* next's next */ 171 CallInfo *next2; /* next's next */
154 L->nCcalls -= L->nci; /* to subtract removed elements from 'nCcalls' */ 172 L->nCcalls -= L->nci; /* subtract removed elements from 'nCcalls' */
155 /* while there are two nexts */ 173 /* while there are two nexts */
156 while (ci->next != NULL && (next2 = ci->next->next) != NULL) { 174 while (ci->next != NULL && (next2 = ci->next->next) != NULL) {
157 luaM_free(L, ci->next); /* free next */ 175 luaM_free(L, ci->next); /* free next */
@@ -160,7 +178,7 @@ void luaE_shrinkCI (lua_State *L) {
160 next2->previous = ci; 178 next2->previous = ci;
161 ci = next2; /* keep next's next */ 179 ci = next2; /* keep next's next */
162 } 180 }
163 L->nCcalls += L->nci; /* to subtract removed elements from 'nCcalls' */ 181 L->nCcalls += L->nci; /* adjust result */
164} 182}
165 183
166 184
@@ -250,7 +268,6 @@ static void preinit_thread (lua_State *L, global_State *g) {
250 L->allowhook = 1; 268 L->allowhook = 1;
251 resethookcount(L); 269 resethookcount(L);
252 L->openupval = NULL; 270 L->openupval = NULL;
253 L->nny = 1;
254 L->status = LUA_OK; 271 L->status = LUA_OK;
255 L->errfunc = 0; 272 L->errfunc = 0;
256} 273}