diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-01-25 20:14:54 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-01-25 20:14:54 -0200 |
commit | 50e29525936be4891f9db090f293432913b5f7c0 (patch) | |
tree | 8e487b87f82761e15cd096ac345354f57f38fedc /ldo.c | |
parent | b217ae644e3a83def93be2fe742e2cd0970e1a5f (diff) | |
download | lua-50e29525936be4891f9db090f293432913b5f7c0.tar.gz lua-50e29525936be4891f9db090f293432913b5f7c0.tar.bz2 lua-50e29525936be4891f9db090f293432913b5f7c0.zip |
first version of dynamic stack
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 215 |
1 files changed, 132 insertions, 83 deletions
@@ -30,22 +30,72 @@ | |||
30 | 30 | ||
31 | 31 | ||
32 | 32 | ||
33 | /* chain list of long jump buffers */ | ||
34 | struct lua_longjmp { | ||
35 | jmp_buf b; | ||
36 | struct lua_longjmp *previous; | ||
37 | CallInfo *ci; /* index of call info of active function that set protection */ | ||
38 | StkId top; /* top stack when protection was set */ | ||
39 | TObject *stack; /* active stack for this entry */ | ||
40 | int allowhooks; /* `allowhook' state when protection was set */ | ||
41 | volatile int status; /* error code */ | ||
42 | }; | ||
43 | |||
44 | |||
45 | static void correctstack (lua_State *L, TObject *oldstack) { | ||
46 | struct lua_longjmp *lj; | ||
47 | CallInfo *ci; | ||
48 | UpVal *up; | ||
49 | L->top = (L->top - oldstack) + L->stack; | ||
50 | for (lj = L->errorJmp; lj && lj->stack == oldstack; lj = lj->previous) { | ||
51 | lj->top = (lj->top - oldstack) + L->stack; | ||
52 | lj->stack = L->stack; | ||
53 | } | ||
54 | for (up = L->openupval; up != NULL; up = up->next) | ||
55 | up->v = (up->v - oldstack) + L->stack; | ||
56 | for (ci = L->base_ci; ci <= L->ci; ci++) { | ||
57 | ci->base = (ci->base - oldstack) + L->stack; | ||
58 | ci->top = (ci->top - oldstack) + L->stack; | ||
59 | if (ci->pc) { /* entry is of an active Lua function? */ | ||
60 | if (ci->pc != (ci-1)->pc) | ||
61 | *ci->pb = (*ci->pb - oldstack) + L->stack; | ||
62 | } | ||
63 | } | ||
64 | } | ||
65 | |||
66 | |||
67 | void luaD_reallocstack (lua_State *L, int newsize) { | ||
68 | TObject *oldstack = L->stack; | ||
69 | luaM_reallocvector(L, L->stack, L->stacksize, newsize, TObject); | ||
70 | L->stacksize = newsize; | ||
71 | L->stack_last = L->stack+(newsize-EXTRA_STACK)-1; | ||
72 | correctstack(L, oldstack); | ||
73 | } | ||
74 | |||
75 | |||
33 | static void restore_stack_limit (lua_State *L) { | 76 | static void restore_stack_limit (lua_State *L) { |
34 | StkId limit = L->stack+(L->stacksize-EXTRA_STACK)-1; | 77 | if (L->stacksize > L->maxstacksize) { /* there was an overflow? */ |
35 | if (L->top < limit) | 78 | int inuse = (L->top - L->stack); |
36 | L->stack_last = limit; | 79 | if (inuse + MAXSTACK < L->maxstacksize) /* can `undo' overflow? */ |
80 | luaD_reallocstack(L, L->maxstacksize); | ||
81 | } | ||
37 | } | 82 | } |
38 | 83 | ||
39 | 84 | ||
40 | void luaD_stackerror (lua_State *L) { | 85 | void luaD_growstack (lua_State *L, int n) { |
41 | if (L->stack_last == L->stack+L->stacksize-1) { | 86 | if (L->stacksize > L->maxstacksize) { /* overflow while handling overflow? */ |
42 | /* overflow while handling overflow */ | ||
43 | luaD_breakrun(L, LUA_ERRERR); /* break run without error message */ | 87 | luaD_breakrun(L, LUA_ERRERR); /* break run without error message */ |
44 | } | 88 | } |
45 | else { | 89 | else { |
46 | L->stack_last += EXTRA_STACK; /* to be used by error message */ | 90 | if (n <= L->stacksize && 2*L->stacksize < L->maxstacksize) /* can double? */ |
47 | lua_assert(L->stack_last == L->stack+L->stacksize-1); | 91 | luaD_reallocstack(L, 2*L->stacksize); |
48 | luaD_error(L, "stack overflow"); | 92 | else if (L->stacksize+n <= L->maxstacksize) /* no overflow? */ |
93 | luaD_reallocstack(L, L->maxstacksize); | ||
94 | else { | ||
95 | /* resize to maximum + some extra space to handle error */ | ||
96 | luaD_reallocstack(L, L->maxstacksize+4*LUA_MINSTACK); | ||
97 | luaD_error(L, "stack overflow"); | ||
98 | } | ||
49 | } | 99 | } |
50 | } | 100 | } |
51 | 101 | ||
@@ -56,12 +106,12 @@ void luaD_stackerror (lua_State *L) { | |||
56 | static void luaD_openstack (lua_State *L, StkId pos) { | 106 | static void luaD_openstack (lua_State *L, StkId pos) { |
57 | int i = L->top-pos; | 107 | int i = L->top-pos; |
58 | while (i--) setobj(pos+i+1, pos+i); | 108 | while (i--) setobj(pos+i+1, pos+i); |
59 | incr_top; | 109 | incr_top(L); |
60 | } | 110 | } |
61 | 111 | ||
62 | 112 | ||
63 | static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { | 113 | static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { |
64 | StkId old_top = L->top; | 114 | L->ci->top = L->top; |
65 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 115 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
66 | L->allowhooks = 0; /* cannot call hooks inside a hook */ | 116 | L->allowhooks = 0; /* cannot call hooks inside a hook */ |
67 | lua_unlock(L); | 117 | lua_unlock(L); |
@@ -69,7 +119,7 @@ static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { | |||
69 | lua_lock(L); | 119 | lua_lock(L); |
70 | lua_assert(L->allowhooks == 0); | 120 | lua_assert(L->allowhooks == 0); |
71 | L->allowhooks = 1; | 121 | L->allowhooks = 1; |
72 | L->top = old_top; | 122 | L->top = L->ci->top; |
73 | } | 123 | } |
74 | 124 | ||
75 | 125 | ||
@@ -95,66 +145,82 @@ void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) { | |||
95 | } | 145 | } |
96 | 146 | ||
97 | 147 | ||
98 | static CallInfo *growci (lua_State *L) { | 148 | static void correctCI (lua_State *L, CallInfo *oldci) { |
99 | lua_assert(L->ci == L->end_ci); | 149 | struct lua_longjmp *lj; |
100 | luaM_reallocvector(L, L->base_ci, L->size_ci, 2*L->size_ci, CallInfo); | 150 | for (lj = L->errorJmp; lj && lj->stack == L->stack; lj = lj->previous) { |
101 | L->ci = L->base_ci + L->size_ci; | 151 | lj->ci = (lj->ci - oldci) + L->base_ci; |
102 | L->size_ci *= 2; | 152 | } |
103 | L->end_ci = L->base_ci + L->size_ci; | ||
104 | return L->ci; | ||
105 | } | 153 | } |
106 | 154 | ||
107 | 155 | ||
108 | static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { | 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) { | ||
109 | int i; | 169 | int i; |
110 | Table *htab; | 170 | Table *htab; |
111 | TObject n, nname; | 171 | TObject n, nname; |
112 | StkId firstvar = base + nfixargs; /* position of first vararg */ | 172 | int actual = L->top - L->ci->base; /* actual number of arguments */ |
113 | if (L->top < firstvar) { | 173 | if (actual < nfixargs) { |
114 | luaD_checkstack(L, firstvar - L->top); | 174 | luaD_checkstack(L, nfixargs - actual); |
115 | while (L->top < firstvar) | 175 | for (; actual < nfixargs; ++actual) |
116 | setnilvalue(L->top++); | 176 | setnilvalue(L->top++); |
117 | } | 177 | } |
118 | htab = luaH_new(L, 0, 0); | 178 | actual -= nfixargs; /* number of extra arguments */ |
119 | for (i=0; firstvar+i<L->top; i++) | 179 | htab = luaH_new(L, 0, 0); /* create `arg' table */ |
120 | luaH_setnum(L, htab, i+1, firstvar+i); | 180 | for (i=0; i<actual; i++) /* put extra arguments into `arg' table */ |
181 | luaH_setnum(L, htab, i+1, L->top - actual + i); | ||
121 | /* store counter in field `n' */ | 182 | /* store counter in field `n' */ |
122 | setnvalue(&n, i); | 183 | setnvalue(&n, actual); |
123 | setsvalue(&nname, luaS_newliteral(L, "n")); | 184 | setsvalue(&nname, luaS_newliteral(L, "n")); |
124 | luaH_set(L, htab, &nname, &n); | 185 | luaH_set(L, htab, &nname, &n); |
125 | L->top = firstvar; /* remove elements from the stack */ | 186 | L->top -= actual; /* remove extra elements from the stack */ |
126 | sethvalue(L->top, htab); | 187 | sethvalue(L->top, htab); |
127 | incr_top; | 188 | incr_top(L); |
128 | } | 189 | } |
129 | 190 | ||
130 | 191 | ||
131 | StkId luaD_precall (lua_State *L, StkId func) { | 192 | StkId luaD_precall (lua_State *L, StkId func) { |
132 | CallInfo *ci; | 193 | CallInfo *ci; |
133 | LClosure *cl; | 194 | LClosure *cl; |
195 | if (++L->ci == L->end_ci) luaD_reallocCI(L, 2*L->size_ci); | ||
196 | ci = L->ci; | ||
197 | ci->base = func+1; | ||
198 | ci->pc = NULL; | ||
134 | if (ttype(func) != LUA_TFUNCTION) { | 199 | if (ttype(func) != LUA_TFUNCTION) { |
135 | /* `func' is not a function; check the `function' tag method */ | 200 | /* `func' is not a function; check the `function' tag method */ |
136 | const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); | 201 | const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); |
137 | if (ttype(tm) != LUA_TFUNCTION) | 202 | if (ttype(tm) != LUA_TFUNCTION) { |
203 | L->ci--; /* undo increment (no function here) */ | ||
138 | luaG_typeerror(L, func, "call"); | 204 | luaG_typeerror(L, func, "call"); |
205 | } | ||
139 | luaD_openstack(L, func); | 206 | luaD_openstack(L, func); |
207 | func = ci->base - 1; /* previous call may change stack */ | ||
140 | setobj(func, tm); /* tag method is the new function to be called */ | 208 | setobj(func, tm); /* tag method is the new function to be called */ |
141 | } | 209 | } |
142 | ci = ++L->ci; | ||
143 | if (L->ci == L->end_ci) ci = growci(L); | ||
144 | ci->base = func+1; | ||
145 | if (L->callhook) | ||
146 | luaD_callHook(L, L->callhook, "call"); | ||
147 | cl = &clvalue(func)->l; | 210 | cl = &clvalue(func)->l; |
211 | if (L->callhook) { | ||
212 | luaD_callHook(L, L->callhook, "call"); | ||
213 | ci = L->ci; /* previous call may realocate `ci' */ | ||
214 | } | ||
148 | if (!cl->isC) { /* Lua function? prepare its call */ | 215 | if (!cl->isC) { /* Lua function? prepare its call */ |
149 | StkId base = func+1; | ||
150 | Proto *p = cl->p; | 216 | Proto *p = cl->p; |
151 | ci->savedpc = p->code; /* starting point */ | 217 | ci->savedpc = p->code; /* starting point */ |
152 | if (p->is_vararg) /* varargs? */ | 218 | if (p->is_vararg) /* varargs? */ |
153 | adjust_varargs(L, base, p->numparams); | 219 | adjust_varargs(L, p->numparams); |
154 | if (base > L->stack_last - p->maxstacksize) | 220 | if (ci->base > L->stack_last - p->maxstacksize) |
155 | luaD_stackerror(L); | 221 | luaD_growstack(L, p->maxstacksize); |
156 | ci->line = 0; | 222 | ci->line = 0; |
157 | ci->top = base + p->maxstacksize; | 223 | ci->top = ci->base + p->maxstacksize; |
158 | while (L->top < ci->top) | 224 | while (L->top < ci->top) |
159 | setnilvalue(L->top++); | 225 | setnilvalue(L->top++); |
160 | L->top = ci->top; | 226 | L->top = ci->top; |
@@ -162,13 +228,12 @@ StkId luaD_precall (lua_State *L, StkId func) { | |||
162 | } | 228 | } |
163 | else { /* if is a C function, call it */ | 229 | else { /* if is a C function, call it */ |
164 | int n; | 230 | int n; |
165 | ci->savedpc = NULL; | ||
166 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 231 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
167 | lua_unlock(L); | 232 | lua_unlock(L); |
168 | #if LUA_COMPATUPVALUES | 233 | #if LUA_COMPATUPVALUES |
169 | lua_pushupvalues(L); | 234 | lua_pushupvalues(L); |
170 | #endif | 235 | #endif |
171 | n = (*clvalue(func)->c.f)(L); /* do the actual call */ | 236 | n = (*clvalue(ci->base-1)->c.f)(L); /* do the actual call */ |
172 | lua_lock(L); | 237 | lua_lock(L); |
173 | return L->top - n; | 238 | return L->top - n; |
174 | } | 239 | } |
@@ -177,9 +242,12 @@ StkId luaD_precall (lua_State *L, StkId func) { | |||
177 | 242 | ||
178 | void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { | 243 | void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { |
179 | StkId res; | 244 | StkId res; |
180 | if (L->callhook) | 245 | if (L->callhook) { |
246 | StkId stack = L->stack; /* next call may change stack */ | ||
181 | luaD_callHook(L, L->callhook, "return"); | 247 | luaD_callHook(L, L->callhook, "return"); |
182 | res = L->ci->base - 1; /* `func' = final position of 1st result */ | 248 | firstResult = (firstResult - stack) + L->stack; |
249 | } | ||
250 | res = L->ci->base - 1; /* func == final position of 1st result */ | ||
183 | L->ci--; | 251 | L->ci--; |
184 | /* move results to correct place */ | 252 | /* move results to correct place */ |
185 | while (wanted != 0 && firstResult < L->top) { | 253 | while (wanted != 0 && firstResult < L->top) { |
@@ -223,7 +291,7 @@ static void resume_results (lua_State *L, lua_State *from, int numresults) { | |||
223 | while (numresults) { | 291 | while (numresults) { |
224 | setobj(L->top, from->top - numresults); | 292 | setobj(L->top, from->top - numresults); |
225 | numresults--; | 293 | numresults--; |
226 | incr_top; | 294 | incr_top(L); |
227 | } | 295 | } |
228 | } | 296 | } |
229 | 297 | ||
@@ -231,7 +299,7 @@ static void resume_results (lua_State *L, lua_State *from, int numresults) { | |||
231 | LUA_API void lua_resume (lua_State *L, lua_State *co) { | 299 | LUA_API void lua_resume (lua_State *L, lua_State *co) { |
232 | StkId firstResult; | 300 | StkId firstResult; |
233 | lua_lock(L); | 301 | lua_lock(L); |
234 | if (co->ci->savedpc == NULL) /* no activation record? */ | 302 | if (co->ci == co->base_ci) /* no activation record? ?? */ |
235 | luaD_error(L, "thread is dead - cannot be resumed"); | 303 | luaD_error(L, "thread is dead - cannot be resumed"); |
236 | lua_assert(co->errorJmp == NULL); | 304 | lua_assert(co->errorJmp == NULL); |
237 | co->errorJmp = L->errorJmp; | 305 | co->errorJmp = L->errorJmp; |
@@ -253,15 +321,13 @@ LUA_API void lua_resume (lua_State *L, lua_State *co) { | |||
253 | 321 | ||
254 | LUA_API int lua_yield (lua_State *L, int nresults) { | 322 | LUA_API int lua_yield (lua_State *L, int nresults) { |
255 | CallInfo *ci; | 323 | CallInfo *ci; |
256 | int ibase; | ||
257 | lua_lock(L); | 324 | lua_lock(L); |
258 | ci = L->ci; | 325 | ci = L->ci; |
259 | if (ci_func(ci-1)->c.isC) | 326 | if (ci_func(ci-1)->c.isC) |
260 | luaD_error(L, "cannot `yield' a C function"); | 327 | luaD_error(L, "cannot `yield' a C function"); |
261 | ci->yield_results = nresults; /* very dirty trick! */ | 328 | ci->yield_results = nresults; |
262 | ibase = L->top - (ci-1)->base; | ||
263 | lua_unlock(L); | 329 | lua_unlock(L); |
264 | return ibase; | 330 | return -1; |
265 | } | 331 | } |
266 | 332 | ||
267 | 333 | ||
@@ -280,16 +346,15 @@ static void f_call (lua_State *L, void *ud) { | |||
280 | 346 | ||
281 | 347 | ||
282 | LUA_API int lua_call (lua_State *L, int nargs, int nresults) { | 348 | LUA_API int lua_call (lua_State *L, int nargs, int nresults) { |
283 | StkId func; | ||
284 | struct CallS c; | 349 | struct CallS c; |
285 | int status; | 350 | int status; |
286 | lua_lock(L); | 351 | lua_lock(L); |
287 | func = L->top - (nargs+1); /* function to be called */ | 352 | c.func = L->top - (nargs+1); /* function to be called */ |
288 | c.func = func; c.nresults = nresults; | 353 | c.nresults = nresults; |
289 | status = luaD_runprotected(L, f_call, &c); | 354 | status = luaD_runprotected(L, f_call, &c); |
290 | if (status != 0) { /* an error occurred? */ | 355 | if (status != 0) { /* an error occurred? */ |
291 | luaF_close(L, func); /* close eventual pending closures */ | 356 | L->top -= nargs+1; /* remove parameters and func from the stack */ |
292 | L->top = func; /* remove parameters from the stack */ | 357 | luaF_close(L, L->top); /* close eventual pending closures */ |
293 | } | 358 | } |
294 | lua_unlock(L); | 359 | lua_unlock(L); |
295 | return status; | 360 | return status; |
@@ -310,7 +375,7 @@ static void f_parser (lua_State *L, void *ud) { | |||
310 | Closure *cl = luaF_newLclosure(L, 0); | 375 | Closure *cl = luaF_newLclosure(L, 0); |
311 | cl->l.p = tf; | 376 | cl->l.p = tf; |
312 | setclvalue(L->top, cl); | 377 | setclvalue(L->top, cl); |
313 | incr_top; | 378 | incr_top(L); |
314 | } | 379 | } |
315 | 380 | ||
316 | 381 | ||
@@ -351,7 +416,7 @@ LUA_API int lua_loadfile (lua_State *L, const char *filename) { | |||
351 | if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */ | 416 | if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */ |
352 | } | 417 | } |
353 | lua_pushliteral(L, "@"); | 418 | lua_pushliteral(L, "@"); |
354 | lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename); | 419 | lua_pushstring(L, (filename == NULL) ? "=stdin" : filename); |
355 | lua_concat(L, 2); | 420 | lua_concat(L, 2); |
356 | nlevel = lua_gettop(L); | 421 | nlevel = lua_gettop(L); |
357 | filename = lua_tostring(L, -1); /* filename = `@'..filename */ | 422 | filename = lua_tostring(L, -1); /* filename = `@'..filename */ |
@@ -380,28 +445,17 @@ LUA_API int lua_loadbuffer (lua_State *L, const char *buff, size_t size, | |||
380 | ** ======================================================= | 445 | ** ======================================================= |
381 | */ | 446 | */ |
382 | 447 | ||
383 | /* chain list of long jump buffers */ | ||
384 | struct lua_longjmp { | ||
385 | jmp_buf b; | ||
386 | struct lua_longjmp *previous; | ||
387 | volatile int status; /* error code */ | ||
388 | int ci; /* index of call info of active function that set protection */ | ||
389 | StkId top; /* top stack when protection was set */ | ||
390 | int allowhooks; /* `allowhook' state when protection was set */ | ||
391 | }; | ||
392 | |||
393 | 448 | ||
394 | static void message (lua_State *L, const char *s) { | 449 | static void message (lua_State *L, const char *s) { |
395 | TObject o, m; | 450 | TObject o, m; |
396 | setsvalue(&o, luaS_newliteral(L, LUA_ERRORMESSAGE)); | 451 | setsvalue(&o, luaS_newliteral(L, LUA_ERRORMESSAGE)); |
397 | luaV_gettable(L, gt(L), &o, &m); | 452 | luaV_gettable(L, gt(L), &o, &m); |
398 | if (ttype(&m) == LUA_TFUNCTION) { | 453 | if (ttype(&m) == LUA_TFUNCTION) { |
399 | StkId top = L->top; | 454 | setobj(L->top, &m); |
400 | setobj(top, &m); | 455 | incr_top(L); |
401 | incr_top; | 456 | setsvalue(L->top, luaS_new(L, s)); |
402 | setsvalue(top+1, luaS_new(L, s)); | 457 | incr_top(L); |
403 | incr_top; | 458 | luaD_call(L, L->top-2, 0); |
404 | luaD_call(L, top, 0); | ||
405 | } | 459 | } |
406 | } | 460 | } |
407 | 461 | ||
@@ -410,13 +464,7 @@ static void message (lua_State *L, const char *s) { | |||
410 | ** Reports an error, and jumps up to the available recovery label | 464 | ** Reports an error, and jumps up to the available recovery label |
411 | */ | 465 | */ |
412 | void luaD_error (lua_State *L, const char *s) { | 466 | void luaD_error (lua_State *L, const char *s) { |
413 | if (s) { | 467 | if (s) message(L, s); |
414 | if (L->ci->savedpc) { /* error in Lua function preamble? */ | ||
415 | L->ci->savedpc = NULL; /* pretend function was already running */ | ||
416 | L->ci->pc = NULL; | ||
417 | } | ||
418 | message(L, s); | ||
419 | } | ||
420 | luaD_breakrun(L, LUA_ERRRUN); | 468 | luaD_breakrun(L, LUA_ERRRUN); |
421 | } | 469 | } |
422 | 470 | ||
@@ -436,8 +484,9 @@ void luaD_breakrun (lua_State *L, int errcode) { | |||
436 | 484 | ||
437 | int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { | 485 | int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { |
438 | struct lua_longjmp lj; | 486 | struct lua_longjmp lj; |
439 | lj.ci = L->ci - L->base_ci; | 487 | lj.ci = L->ci; |
440 | lj.top = L->top; | 488 | lj.top = L->top; |
489 | lj.stack = L->stack; | ||
441 | lj.allowhooks = L->allowhooks; | 490 | lj.allowhooks = L->allowhooks; |
442 | lj.status = 0; | 491 | lj.status = 0; |
443 | lj.previous = L->errorJmp; /* chain new error handler */ | 492 | lj.previous = L->errorJmp; /* chain new error handler */ |
@@ -445,7 +494,7 @@ int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { | |||
445 | if (setjmp(lj.b) == 0) | 494 | if (setjmp(lj.b) == 0) |
446 | (*f)(L, ud); | 495 | (*f)(L, ud); |
447 | else { /* an error occurred: restore the state */ | 496 | else { /* an error occurred: restore the state */ |
448 | L->ci = L->base_ci + lj.ci; | 497 | L->ci = lj.ci; |
449 | L->top = lj.top; | 498 | L->top = lj.top; |
450 | L->allowhooks = lj.allowhooks; | 499 | L->allowhooks = lj.allowhooks; |
451 | restore_stack_limit(L); | 500 | restore_stack_limit(L); |