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 | |
parent | 0b9b53e21c30fff06ae39abc00a3c43ab5a18596 (diff) | |
download | lua-81215cd59f58923ae9807d34f1dd46a51f400e4b.tar.gz lua-81215cd59f58923ae9807d34f1dd46a51f400e4b.tar.bz2 lua-81215cd59f58923ae9807d34f1dd46a51f400e4b.zip |
simpler way to control stack overflow
-rw-r--r-- | lapi.c | 4 | ||||
-rw-r--r-- | ldo.c | 73 | ||||
-rw-r--r-- | llimits.h | 14 | ||||
-rw-r--r-- | lstate.h | 4 |
4 files changed, 51 insertions, 44 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 1.178 2002/03/18 20:11:52 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.179 2002/03/20 12:51:29 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 | */ |
@@ -85,7 +85,7 @@ void luaA_pushobject (lua_State *L, const TObject *o) { | |||
85 | LUA_API int lua_checkstack (lua_State *L, int size) { | 85 | LUA_API int lua_checkstack (lua_State *L, int size) { |
86 | int res; | 86 | int res; |
87 | lua_lock(L); | 87 | lua_lock(L); |
88 | if ((L->top - L->stack) >= LUA_MAXSTACK - size) | 88 | if ((L->top - L->ci->base + size) > LUA_MAXCSTACK) |
89 | res = 0; /* stack overflow */ | 89 | res = 0; /* stack overflow */ |
90 | else { | 90 | else { |
91 | luaD_checkstack(L, size); | 91 | luaD_checkstack(L, size); |
@@ -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; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llimits.h,v 1.40 2002/03/14 18:01:52 roberto Exp roberto $ | 2 | ** $Id: llimits.h,v 1.41 2002/03/18 18:16:16 roberto Exp roberto $ |
3 | ** Limits, basic types, and some other `installation-dependent' definitions | 3 | ** Limits, basic types, and some other `installation-dependent' definitions |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -101,9 +101,15 @@ union L_Umaxalign { LUSER_ALIGNMENT_T u; void *s; long l; }; | |||
101 | typedef unsigned long Instruction; | 101 | typedef unsigned long Instruction; |
102 | 102 | ||
103 | 103 | ||
104 | /* maximum size for the Lua stack */ | 104 | /* maximum depth for calls */ |
105 | #ifndef LUA_MAXSTACK | 105 | #ifndef LUA_MAXCALLS |
106 | #define LUA_MAXSTACK 14000 | 106 | #define LUA_MAXCALLS 2048 |
107 | #endif | ||
108 | |||
109 | |||
110 | /* maximum size for the C stack */ | ||
111 | #ifndef LUA_MAXCSTACK | ||
112 | #define LUA_MAXCSTACK 2048 | ||
107 | #endif | 113 | #endif |
108 | 114 | ||
109 | 115 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 1.79 2002/03/11 12:45:00 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.80 2002/03/25 17:47:14 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 | */ |
@@ -69,7 +69,7 @@ struct lua_longjmp; /* defined in ldo.c */ | |||
69 | #define EXTRA_STACK 4 | 69 | #define EXTRA_STACK 4 |
70 | 70 | ||
71 | 71 | ||
72 | #define BASIC_CI_SIZE 6 | 72 | #define BASIC_CI_SIZE 8 |
73 | 73 | ||
74 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) | 74 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) |
75 | 75 | ||