diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-03-26 17:46:10 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-03-26 17:46:10 -0300 |
commit | 81215cd59f58923ae9807d34f1dd46a51f400e4b (patch) | |
tree | 9317d562ae3ea5d54cd5487b220f6e0a20c259a3 /ldo.c | |
parent | 0b9b53e21c30fff06ae39abc00a3c43ab5a18596 (diff) | |
download | lua-81215cd59f58923ae9807d34f1dd46a51f400e4b.tar.gz lua-81215cd59f58923ae9807d34f1dd46a51f400e4b.tar.bz2 lua-81215cd59f58923ae9807d34f1dd46a51f400e4b.zip |
simpler way to control stack overflow
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 73 |
1 files changed, 37 insertions, 36 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 1.166 2002/03/25 17:47:14 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.167 2002/03/25 19:45:06 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -70,30 +70,51 @@ void luaD_reallocstack (lua_State *L, int newsize) { | |||
70 | } | 70 | } |
71 | 71 | ||
72 | 72 | ||
73 | static void correctCI (lua_State *L, CallInfo *oldci) { | ||
74 | struct lua_longjmp *lj; | ||
75 | for (lj = L->errorJmp; lj != NULL; lj = lj->previous) { | ||
76 | lj->ci = (lj->ci - oldci) + L->base_ci; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | |||
81 | void luaD_reallocCI (lua_State *L, int newsize) { | ||
82 | CallInfo *oldci = L->base_ci; | ||
83 | luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); | ||
84 | L->size_ci = newsize; | ||
85 | L->ci = (L->ci - oldci) + L->base_ci; | ||
86 | L->end_ci = L->base_ci + L->size_ci; | ||
87 | correctCI(L, oldci); | ||
88 | } | ||
89 | |||
90 | |||
73 | static void restore_stack_limit (lua_State *L) { | 91 | static void restore_stack_limit (lua_State *L) { |
74 | if (L->stacksize > LUA_MAXSTACK) { /* there was an overflow? */ | 92 | if (L->size_ci > LUA_MAXCALLS) { /* there was an overflow? */ |
75 | int inuse = (L->top - L->stack); | 93 | int inuse = (L->ci - L->base_ci); |
76 | if (inuse + MAXSTACK < LUA_MAXSTACK) /* can `undo' overflow? */ | 94 | if (inuse + 1 < LUA_MAXCALLS) /* can `undo' overflow? */ |
77 | luaD_reallocstack(L, LUA_MAXSTACK); | 95 | luaD_reallocCI(L, LUA_MAXCALLS); |
78 | } | 96 | } |
79 | } | 97 | } |
80 | 98 | ||
81 | 99 | ||
82 | void luaD_growstack (lua_State *L, int n) { | 100 | void luaD_growstack (lua_State *L, int n) { |
83 | if (L->stacksize > LUA_MAXSTACK) { /* overflow while handling overflow? */ | 101 | if (n <= L->stacksize) /* double size is enough? */ |
102 | luaD_reallocstack(L, 2*L->stacksize); | ||
103 | else | ||
104 | luaD_reallocstack(L, L->stacksize + n + EXTRA_STACK); | ||
105 | } | ||
106 | |||
107 | |||
108 | static void luaD_growCI (lua_State *L) { | ||
109 | L->ci--; | ||
110 | if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ | ||
84 | luaD_breakrun(L, LUA_ERRERR); /* break run without error message */ | 111 | luaD_breakrun(L, LUA_ERRERR); /* break run without error message */ |
85 | } | ||
86 | else { | 112 | else { |
87 | if (n <= L->stacksize && 2*L->stacksize < LUA_MAXSTACK) /* can double? */ | 113 | luaD_reallocCI(L, 2*L->size_ci); |
88 | luaD_reallocstack(L, 2*L->stacksize); | 114 | if (L->size_ci > LUA_MAXCALLS) |
89 | else if ((L->top - L->stack) + n <= LUA_MAXSTACK) /* no overflow? */ | ||
90 | luaD_reallocstack(L, LUA_MAXSTACK); | ||
91 | else { | ||
92 | /* resize to maximum + some extra space to handle error */ | ||
93 | luaD_reallocstack(L, LUA_MAXSTACK+4*LUA_MINSTACK); | ||
94 | luaD_error(L, "stack overflow"); | 115 | luaD_error(L, "stack overflow"); |
95 | } | ||
96 | } | 116 | } |
117 | L->ci++; | ||
97 | } | 118 | } |
98 | 119 | ||
99 | 120 | ||
@@ -145,26 +166,6 @@ static void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) { | |||
145 | } | 166 | } |
146 | 167 | ||
147 | 168 | ||
148 | static void correctCI (lua_State *L, CallInfo *oldci) { | ||
149 | struct lua_longjmp *lj; | ||
150 | for (lj = L->errorJmp; lj != NULL; lj = lj->previous) { | ||
151 | lj->ci = (lj->ci - oldci) + L->base_ci; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | |||
156 | void luaD_reallocCI (lua_State *L, int newsize) { | ||
157 | CallInfo *oldci = L->base_ci; | ||
158 | luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); | ||
159 | L->size_ci = newsize; | ||
160 | if (oldci != L->ci) { | ||
161 | L->ci = (L->ci - oldci) + L->base_ci; | ||
162 | L->end_ci = L->base_ci + L->size_ci; | ||
163 | correctCI(L, oldci); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | |||
168 | static void adjust_varargs (lua_State *L, int nfixargs) { | 169 | static void adjust_varargs (lua_State *L, int nfixargs) { |
169 | int i; | 170 | int i; |
170 | Table *htab; | 171 | Table *htab; |
@@ -205,7 +206,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) { | |||
205 | StkId luaD_precall (lua_State *L, StkId func) { | 206 | StkId luaD_precall (lua_State *L, StkId func) { |
206 | CallInfo *ci; | 207 | CallInfo *ci; |
207 | LClosure *cl; | 208 | LClosure *cl; |
208 | if (++L->ci == L->end_ci) luaD_reallocCI(L, 2*L->size_ci); | 209 | if (++L->ci == L->end_ci) luaD_growCI(L); |
209 | ci = L->ci; | 210 | ci = L->ci; |
210 | ci->base = ci->top = func+1; /* pre-init `top' in case of errors */ | 211 | ci->base = ci->top = func+1; /* pre-init `top' in case of errors */ |
211 | ci->pc = NULL; | 212 | ci->pc = NULL; |