diff options
Diffstat (limited to 'ldo.c')
| -rw-r--r-- | ldo.c | 94 |
1 files changed, 52 insertions, 42 deletions
| @@ -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 | |||
| 241 | void 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 | */ |
| 243 | void lua_error (lua_State *L, const char *s) { | 256 | void 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); | 262 | static 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 | |||
| 270 | static 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 | */ |
| 258 | int luaD_protectedrun (lua_State *L) { | 282 | int 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 | */ |
| 287 | static int protectedparser (lua_State *L, ZIO *z, int bin) { | 305 | static 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; |
