summaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-04-22 11:40:50 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-04-22 11:40:50 -0300
commitee4859b3e3db6c1a3223669d15538b3852ca4791 (patch)
treea9a9532c03f0a9bc58599e34457cb618aa5f11f2 /ldo.c
parentf388ee4a822b3d8027ed7c28aa21e9406e4a11eb (diff)
downloadlua-ee4859b3e3db6c1a3223669d15538b3852ca4791.tar.gz
lua-ee4859b3e3db6c1a3223669d15538b3852ca4791.tar.bz2
lua-ee4859b3e3db6c1a3223669d15538b3852ca4791.zip
new way to handle errors (temporary version)
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c107
1 files changed, 36 insertions, 71 deletions
diff --git a/ldo.c b/ldo.c
index 29276f1b..c89d3a3c 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.170 2002/04/15 19:34:42 roberto Exp roberto $ 2** $Id: ldo.c,v 1.171 2002/04/16 17:08:28 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*/
@@ -38,9 +38,11 @@ struct lua_longjmp {
38 jmp_buf b; 38 jmp_buf b;
39 int allowhooks; /* `allowhook' state when protection was set */ 39 int allowhooks; /* `allowhook' state when protection was set */
40 volatile int status; /* error code */ 40 volatile int status; /* error code */
41 TObject err; /* function to be called in case of errors */
41}; 42};
42 43
43 44
45
44static void correctstack (lua_State *L, TObject *oldstack) { 46static void correctstack (lua_State *L, TObject *oldstack) {
45 struct lua_longjmp *lj; 47 struct lua_longjmp *lj;
46 CallInfo *ci; 48 CallInfo *ci;
@@ -108,11 +110,11 @@ void luaD_growstack (lua_State *L, int n) {
108static void luaD_growCI (lua_State *L) { 110static void luaD_growCI (lua_State *L) {
109 L->ci--; 111 L->ci--;
110 if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ 112 if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */
111 luaD_breakrun(L, LUA_ERRERR); /* break run without error message */ 113 luaD_error(L, NULL, LUA_ERRERR); /* break run without error message */
112 else { 114 else {
113 luaD_reallocCI(L, 2*L->size_ci); 115 luaD_reallocCI(L, 2*L->size_ci);
114 if (L->size_ci > LUA_MAXCALLS) 116 if (L->size_ci > LUA_MAXCALLS)
115 luaD_error(L, "stack overflow"); 117 luaD_runerror(L, "stack overflow");
116 } 118 }
117 L->ci++; 119 L->ci++;
118} 120}
@@ -278,7 +280,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
278 firstResult = luaV_execute(L); /* call it */ 280 firstResult = luaV_execute(L); /* call it */
279 if (firstResult == NULL) { 281 if (firstResult == NULL) {
280 luaD_poscall(L, 0, L->top); 282 luaD_poscall(L, 0, L->top);
281 luaD_error(L, "attempt to `yield' across tag-method/C-call boundary"); 283 luaD_runerror(L, "attempt to `yield' across tag-method/C-call boundary");
282 } 284 }
283 } 285 }
284 luaD_poscall(L, nResults, firstResult); 286 luaD_poscall(L, nResults, firstResult);
@@ -325,14 +327,17 @@ static void resume (lua_State *L, void *numres) {
325LUA_API int lua_resume (lua_State *L, lua_State *co) { 327LUA_API int lua_resume (lua_State *L, lua_State *co) {
326 CallInfo *ci; 328 CallInfo *ci;
327 int numres; 329 int numres;
330 TObject o;
328 int status; 331 int status;
329 lua_lock(L); 332 lua_lock(L);
330 ci = co->ci; 333 ci = co->ci;
331 if (ci == co->base_ci) /* no activation record? ?? */ 334 if (ci == co->base_ci) /* no activation record? ?? */
332 luaD_error(L, "thread is dead - cannot be resumed"); 335 luaD_runerror(L, "thread is dead - cannot be resumed");
333 if (co->errorJmp != NULL) /* ?? */ 336 if (co->errorJmp != NULL) /* ?? */
334 luaD_error(L, "thread is active - cannot be resumed"); 337 luaD_runerror(L, "thread is active - cannot be resumed");
335 status = luaD_runprotected(co, resume, &numres); 338 setsvalue(&o, luaS_newliteral(L, "_ERRORMESSAGE"));
339 luaV_gettable(L, gt(L), &o, &o);
340 status = luaD_runprotected(co, resume, &o, &numres);
336 if (status == 0) 341 if (status == 0)
337 move_results(L, co->top - numres, co->top); 342 move_results(L, co->top - numres, co->top);
338 lua_unlock(L); 343 lua_unlock(L);
@@ -345,7 +350,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
345 lua_lock(L); 350 lua_lock(L);
346 ci = L->ci; 351 ci = L->ci;
347 if (ci_func(ci-1)->c.isC) 352 if (ci_func(ci-1)->c.isC)
348 luaD_error(L, "cannot `yield' a C function"); 353 luaD_runerror(L, "cannot `yield' a C function");
349 ci->yield_results = nresults; 354 ci->yield_results = nresults;
350 lua_unlock(L); 355 lua_unlock(L);
351 return -1; 356 return -1;
@@ -360,24 +365,23 @@ struct CallS { /* data to `f_call' */
360 int nresults; 365 int nresults;
361}; 366};
362 367
368
363static void f_call (lua_State *L, void *ud) { 369static void f_call (lua_State *L, void *ud) {
364 struct CallS *c = cast(struct CallS *, ud); 370 struct CallS *c = cast(struct CallS *, ud);
365 luaD_call(L, c->func, c->nresults); 371 luaD_call(L, c->func, c->nresults);
366} 372}
367 373
368 374
369LUA_API int lua_call (lua_State *L, int nargs, int nresults) { 375int luaD_pcall (lua_State *L, int nargs, int nresults, const TObject *err) {
370 struct CallS c; 376 struct CallS c;
371 int status; 377 int status;
372 lua_lock(L);
373 c.func = L->top - (nargs+1); /* function to be called */ 378 c.func = L->top - (nargs+1); /* function to be called */
374 c.nresults = nresults; 379 c.nresults = nresults;
375 status = luaD_runprotected(L, f_call, &c); 380 status = luaD_runprotected(L, &f_call, err, &c);
376 if (status != 0) { /* an error occurred? */ 381 if (status != 0) { /* an error occurred? */
377 L->top -= nargs+1; /* remove parameters and func from the stack */ 382 L->top -= nargs+1; /* remove parameters and func from the stack */
378 luaF_close(L, L->top); /* close eventual pending closures */ 383 luaF_close(L, L->top); /* close eventual pending closures */
379 } 384 }
380 lua_unlock(L);
381 return status; 385 return status;
382} 386}
383 387
@@ -400,8 +404,9 @@ static void f_parser (lua_State *L, void *ud) {
400} 404}
401 405
402 406
403static int protectedparser (lua_State *L, ZIO *z, int bin) { 407int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
404 struct SParser p; 408 struct SParser p;
409 TObject o;
405 lu_mem old_blocks; 410 lu_mem old_blocks;
406 int status; 411 int status;
407 lua_lock(L); 412 lua_lock(L);
@@ -410,7 +415,9 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) {
410 if (G(L)->nblocks/8 >= G(L)->GCthreshold/10) 415 if (G(L)->nblocks/8 >= G(L)->GCthreshold/10)
411 luaC_collectgarbage(L); 416 luaC_collectgarbage(L);
412 old_blocks = G(L)->nblocks; 417 old_blocks = G(L)->nblocks;
413 status = luaD_runprotected(L, f_parser, &p); 418 setsvalue(&o, luaS_newliteral(L, "_ERRORMESSAGE"));
419 luaV_gettable(L, gt(L), &o, &o);
420 status = luaD_runprotected(L, f_parser, &o, &p);
414 if (status == 0) { 421 if (status == 0) {
415 /* add new memory to threshold (as it probably will stay) */ 422 /* add new memory to threshold (as it probably will stay) */
416 lua_assert(G(L)->nblocks >= old_blocks); 423 lua_assert(G(L)->nblocks >= old_blocks);
@@ -423,47 +430,6 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) {
423} 430}
424 431
425 432
426LUA_API int lua_loadfile (lua_State *L, const char *filename) {
427 ZIO z;
428 int status;
429 int bin; /* flag for file mode */
430 int nlevel; /* level on the stack of filename */
431 FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
432 if (f == NULL) return LUA_ERRFILE; /* unable to open file */
433 bin = (ungetc(getc(f), f) == LUA_SIGNATURE[0]);
434 if (bin && f != stdin) {
435 fclose(f);
436 f = fopen(filename, "rb"); /* reopen in binary mode */
437 if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */
438 }
439 if (filename == NULL)
440 lua_pushstring(L, "=stdin");
441 else {
442 lua_pushliteral(L, "@");
443 lua_pushstring(L, filename);
444 lua_concat(L, 2);
445 }
446 nlevel = lua_gettop(L);
447 filename = lua_tostring(L, -1); /* filename = `@'..filename */
448 luaZ_Fopen(&z, f, filename);
449 status = protectedparser(L, &z, bin);
450 if (ferror(f)) status = LUA_ERRFILE;
451 lua_remove(L, nlevel); /* remove filename */
452 if (f != stdin)
453 fclose(f);
454 return status;
455}
456
457
458LUA_API int lua_loadbuffer (lua_State *L, const char *buff, size_t size,
459 const char *name) {
460 ZIO z;
461 if (!name) name = "?";
462 luaZ_mopen(&z, buff, size, name);
463 return protectedparser(L, &z, buff[0]==LUA_SIGNATURE[0]);
464}
465
466
467 433
468/* 434/*
469** {====================================================== 435** {======================================================
@@ -472,16 +438,14 @@ LUA_API int lua_loadbuffer (lua_State *L, const char *buff, size_t size,
472*/ 438*/
473 439
474 440
475static void message (lua_State *L, const char *s) { 441static void message (lua_State *L, const char *msg) {
476 TObject o, m; 442 TObject *m = &L->errorJmp->err;
477 setsvalue(&o, luaS_newliteral(L, LUA_ERRORMESSAGE)); 443 if (ttype(m) == LUA_TFUNCTION) {
478 luaV_gettable(L, gt(L), &o, &m); 444 setobj(L->top, m);
479 if (ttype(&m) == LUA_TFUNCTION) {
480 setobj(L->top, &m);
481 incr_top(L); 445 incr_top(L);
482 setsvalue(L->top, luaS_new(L, s)); 446 setsvalue(L->top, luaS_new(L, msg));
483 incr_top(L); 447 incr_top(L);
484 luaD_call(L, L->top-2, 0); 448 luaD_call(L, L->top - 2, 0);
485 } 449 }
486} 450}
487 451
@@ -489,15 +453,10 @@ static void message (lua_State *L, const char *s) {
489/* 453/*
490** Reports an error, and jumps up to the available recovery label 454** Reports an error, and jumps up to the available recovery label
491*/ 455*/
492void luaD_error (lua_State *L, const char *s) { 456void luaD_error (lua_State *L, const char *s, int errcode) {
493 if (s) message(L, s);
494 luaD_breakrun(L, LUA_ERRRUN);
495}
496
497
498void luaD_breakrun (lua_State *L, int errcode) {
499 if (L->errorJmp) { 457 if (L->errorJmp) {
500 L->errorJmp->status = errcode; 458 L->errorJmp->status = errcode;
459 if (s) message(L, s);
501 longjmp(L->errorJmp->b, 1); 460 longjmp(L->errorJmp->b, 1);
502 } 461 }
503 else { 462 else {
@@ -507,12 +466,18 @@ void luaD_breakrun (lua_State *L, int errcode) {
507} 466}
508 467
509 468
510int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { 469void luaD_runerror (lua_State *L, const char *s) {
470 luaD_error(L, s, LUA_ERRRUN);
471}
472
473
474int luaD_runprotected (lua_State *L, Pfunc f, const TObject *err, void *ud) {
511 struct lua_longjmp lj; 475 struct lua_longjmp lj;
512 lj.ci = L->ci; 476 lj.ci = L->ci;
513 lj.top = L->top; 477 lj.top = L->top;
514 lj.allowhooks = L->allowhooks; 478 lj.allowhooks = L->allowhooks;
515 lj.status = 0; 479 lj.status = 0;
480 lj.err = *err;
516 lj.previous = L->errorJmp; /* chain new error handler */ 481 lj.previous = L->errorJmp; /* chain new error handler */
517 L->errorJmp = &lj; 482 L->errorJmp = &lj;
518 if (setjmp(lj.b) == 0) 483 if (setjmp(lj.b) == 0)