diff options
Diffstat (limited to 'lstate.c')
-rw-r--r-- | lstate.c | 28 |
1 files changed, 26 insertions, 2 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 2.146 2017/11/07 13:25:26 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.147 2017/11/13 15:36:52 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -97,8 +97,28 @@ void luaE_setdebt (global_State *g, l_mem debt) { | |||
97 | } | 97 | } |
98 | 98 | ||
99 | 99 | ||
100 | /* | ||
101 | ** Increment count of "C calls" and check for overflows. In case of | ||
102 | ** a stack overflow, check appropriate error ("regular" overflow or | ||
103 | ** overflow while handling stack overflow). If 'nCalls' is larger than | ||
104 | ** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but | ||
105 | ** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to | ||
106 | ** allow overflow handling to work) | ||
107 | */ | ||
108 | void luaE_incCcalls (lua_State *L) { | ||
109 | if (++L->nCcalls >= LUAI_MAXCCALLS) { | ||
110 | if (L->nCcalls == LUAI_MAXCCALLS) | ||
111 | luaG_runerror(L, "C stack overflow"); | ||
112 | else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) | ||
113 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ | ||
114 | } | ||
115 | } | ||
116 | |||
117 | |||
100 | CallInfo *luaE_extendCI (lua_State *L) { | 118 | CallInfo *luaE_extendCI (lua_State *L) { |
101 | CallInfo *ci = luaM_new(L, CallInfo); | 119 | CallInfo *ci; |
120 | luaE_incCcalls(L); | ||
121 | ci = luaM_new(L, CallInfo); | ||
102 | lua_assert(L->ci->next == NULL); | 122 | lua_assert(L->ci->next == NULL); |
103 | L->ci->next = ci; | 123 | L->ci->next = ci; |
104 | ci->previous = L->ci; | 124 | ci->previous = L->ci; |
@@ -116,11 +136,13 @@ void luaE_freeCI (lua_State *L) { | |||
116 | CallInfo *ci = L->ci; | 136 | CallInfo *ci = L->ci; |
117 | CallInfo *next = ci->next; | 137 | CallInfo *next = ci->next; |
118 | ci->next = NULL; | 138 | ci->next = NULL; |
139 | L->nCcalls -= L->nci; /* to subtract removed elements from 'nCcalls' */ | ||
119 | while ((ci = next) != NULL) { | 140 | while ((ci = next) != NULL) { |
120 | next = ci->next; | 141 | next = ci->next; |
121 | luaM_free(L, ci); | 142 | luaM_free(L, ci); |
122 | L->nci--; | 143 | L->nci--; |
123 | } | 144 | } |
145 | L->nCcalls += L->nci; /* to subtract removed elements from 'nCcalls' */ | ||
124 | } | 146 | } |
125 | 147 | ||
126 | 148 | ||
@@ -130,6 +152,7 @@ void luaE_freeCI (lua_State *L) { | |||
130 | void luaE_shrinkCI (lua_State *L) { | 152 | void luaE_shrinkCI (lua_State *L) { |
131 | CallInfo *ci = L->ci; | 153 | CallInfo *ci = L->ci; |
132 | CallInfo *next2; /* next's next */ | 154 | CallInfo *next2; /* next's next */ |
155 | L->nCcalls -= L->nci; /* to subtract removed elements from 'nCcalls' */ | ||
133 | /* while there are two nexts */ | 156 | /* while there are two nexts */ |
134 | while (ci->next != NULL && (next2 = ci->next->next) != NULL) { | 157 | while (ci->next != NULL && (next2 = ci->next->next) != NULL) { |
135 | luaM_free(L, ci->next); /* free next */ | 158 | luaM_free(L, ci->next); /* free next */ |
@@ -138,6 +161,7 @@ void luaE_shrinkCI (lua_State *L) { | |||
138 | next2->previous = ci; | 161 | next2->previous = ci; |
139 | ci = next2; /* keep next's next */ | 162 | ci = next2; /* keep next's next */ |
140 | } | 163 | } |
164 | L->nCcalls += L->nci; /* to subtract removed elements from 'nCcalls' */ | ||
141 | } | 165 | } |
142 | 166 | ||
143 | 167 | ||