aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c94
1 files changed, 52 insertions, 42 deletions
diff --git a/ldo.c b/ldo.c
index 92da2991..2d922078 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.80 2000/06/26 19:28:31 roberto Exp roberto $ 2** $Id: ldo.c,v 1.81 2000/06/28 20:20:36 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*/
@@ -237,17 +237,41 @@ static void message (lua_State *L, const char *s) {
237 } 237 }
238} 238}
239 239
240
241void luaD_breakrun (lua_State *L, int errcode) {
242 if (L->errorJmp) {
243 L->errorJmp->status = errcode;
244 longjmp(L->errorJmp->b, 1);
245 }
246 else {
247 if (errcode != LUA_ERRMEM)
248 message(L, "unable to recover; exiting\n");
249 exit(1);
250 }
251}
252
240/* 253/*
241** Reports an error, and jumps up to the available recovery label 254** Reports an error, and jumps up to the available recovery label
242*/ 255*/
243void lua_error (lua_State *L, const char *s) { 256void lua_error (lua_State *L, const char *s) {
244 if (s) message(L, s); 257 if (s) message(L, s);
245 if (L->errorJmp) 258 luaD_breakrun(L, LUA_ERRRUN);
246 longjmp(L->errorJmp->b, 1); 259}
247 else { 260
248 message(L, "unable to recover; exiting\n"); 261
249 exit(1); 262static void chain_longjmp (lua_State *L, struct lua_longjmp *lj) {
250 } 263 lj->base = L->Cstack.base;
264 lj->numCblocks = L->numCblocks;
265 lj->previous = L->errorJmp;
266 L->errorJmp = lj;
267}
268
269
270static void restore_longjmp (lua_State *L, struct lua_longjmp *lj) {
271 L->Cstack.num = 0; /* no results */
272 L->top = L->Cstack.base = L->Cstack.lua2C = lj->base;
273 L->numCblocks = lj->numCblocks;
274 L->errorJmp = lj->previous;
251} 275}
252 276
253 277
@@ -257,58 +281,44 @@ void lua_error (lua_State *L, const char *s) {
257*/ 281*/
258int luaD_protectedrun (lua_State *L) { 282int luaD_protectedrun (lua_State *L) {
259 struct lua_longjmp myErrorJmp; 283 struct lua_longjmp myErrorJmp;
260 StkId base = L->Cstack.base; 284 chain_longjmp(L, &myErrorJmp);
261 int numCblocks = L->numCblocks;
262 int status;
263 struct lua_longjmp *volatile oldErr = L->errorJmp;
264 L->errorJmp = &myErrorJmp;
265 if (setjmp(myErrorJmp.b) == 0) { 285 if (setjmp(myErrorJmp.b) == 0) {
286 StkId base = L->Cstack.base;
266 luaD_call(L, base, MULT_RET); 287 luaD_call(L, base, MULT_RET);
267 L->Cstack.lua2C = base; /* position of the new results */ 288 L->Cstack.lua2C = base; /* position of the new results */
268 L->Cstack.num = L->top - base; 289 L->Cstack.num = L->top - base;
269 L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */ 290 L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
270 status = 0; 291 L->errorJmp = myErrorJmp.previous;
292 return 0;
271 } 293 }
272 else { /* an error occurred: restore the stack */ 294 else { /* an error occurred: restore the stack */
273 L->Cstack.num = 0; /* no results */ 295 restore_longjmp(L, &myErrorJmp);
274 L->top = L->Cstack.base = L->Cstack.lua2C = base;
275 L->numCblocks = numCblocks;
276 restore_stack_limit(L); 296 restore_stack_limit(L);
277 status = 1; 297 return myErrorJmp.status;
278 } 298 }
279 L->errorJmp = oldErr;
280 return status;
281} 299}
282 300
283 301
284/* 302/*
285** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load 303** returns 0 = chunk loaded; >0 : error; -1 = no more chunks to load
286*/ 304*/
287static int protectedparser (lua_State *L, ZIO *z, int bin) { 305static int protectedparser (lua_State *L, ZIO *z, int bin) {
288 struct lua_longjmp myErrorJmp; 306 struct lua_longjmp myErrorJmp;
289 StkId base = L->Cstack.base; 307 chain_longjmp(L, &myErrorJmp);
290 int numCblocks = L->numCblocks; 308 L->top = L->Cstack.base; /* clear C2Lua */
291 int status;
292 Proto *volatile tf;
293 struct lua_longjmp *volatile oldErr = L->errorJmp;
294 L->errorJmp = &myErrorJmp;
295 L->top = base; /* clear C2Lua */
296 if (setjmp(myErrorJmp.b) == 0) { 309 if (setjmp(myErrorJmp.b) == 0) {
297 tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z); 310 Proto *tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
298 status = 0; 311 L->errorJmp = myErrorJmp.previous;
312 if (tf == NULL) return -1; /* `natural' end */
313 luaV_Lclosure(L, tf, 0);
314 return 0;
299 } 315 }
300 else { /* an error occurred: restore Cstack and top */ 316 else { /* an error occurred */
301 L->Cstack.num = 0; /* no results */ 317 restore_longjmp(L, &myErrorJmp);
302 L->top = L->Cstack.base = L->Cstack.lua2C = base; 318 if (myErrorJmp.status == LUA_ERRRUN)
303 L->numCblocks = numCblocks; 319 myErrorJmp.status = LUA_ERRSYNTAX;
304 tf = NULL; 320 return myErrorJmp.status; /* error code */
305 status = 1;
306 } 321 }
307 L->errorJmp = oldErr;
308 if (status) return 1; /* error code */
309 if (tf == NULL) return 2; /* `natural' end */
310 luaV_Lclosure(L, tf, 0);
311 return 0;
312} 322}
313 323
314 324
@@ -320,8 +330,8 @@ static int do_main (lua_State *L, ZIO *z, int bin) {
320 luaC_checkGC(L); 330 luaC_checkGC(L);
321 old_blocks = L->nblocks; 331 old_blocks = L->nblocks;
322 status = protectedparser(L, z, bin); 332 status = protectedparser(L, z, bin);
323 if (status == 1) return 1; /* error */ 333 if (status > 0) return status; /* error */
324 else if (status == 2) return 0; /* `natural' end */ 334 else if (status < 0) return 0; /* `natural' end */
325 else { 335 else {
326 unsigned long newelems2 = 2*(L->nblocks-old_blocks); 336 unsigned long newelems2 = 2*(L->nblocks-old_blocks);
327 L->GCthreshold += newelems2; 337 L->GCthreshold += newelems2;