Skip to content

Commit

Permalink
Wrap each compiled code evaluation in a catchframe for safe resumable…
Browse files Browse the repository at this point in the history
… error handling
  • Loading branch information
Affonso-Gui committed Oct 31, 2022
1 parent 1a3d141 commit b896e81
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
9 changes: 8 additions & 1 deletion lisp/c/eus.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ va_dcl
register struct callframe *vf;
pointer msg,form,callstack;
pointer errobj;
pointer result;

#ifdef USE_STDARG
va_start(args,ec);
Expand Down Expand Up @@ -435,7 +436,13 @@ va_dcl
Spevalof(QEVALHOOK)=NIL; /* reset eval hook */
if (errhandler!=NIL) {
vpush(errobj);
ufuncall(ctx,errhandler,errhandler,(pointer)(ctx->vsp-1),ctx->bindfp,1);}
result=ufuncall(ctx,errhandler,errhandler,(pointer)(ctx->vsp-1),ctx->bindfp,1);}
else {
result=NIL;
}
// the NULL catcher is introduced by catchfuncode, in order to ensure
// that errors follow the termination semantics in the C lang level
throw(ctx,NULL,result);
}

#ifdef USE_STDARG
Expand Down
24 changes: 23 additions & 1 deletion lisp/c/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -1450,6 +1450,28 @@ pointer args[];
#endif /* IRIX */
#endif /* IRIX6 */

pointer catchfuncode(ctx,func,args,noarg)
register context *ctx;
register pointer func,args;
register int noarg;
{
// create a NULL catcher around each evaluation of compiled code
// this ensures that no continuations are allowed in the C lang level,
// even if the user locally overwrites the error handler
pointer tag,val;
jmp_buf catchbuf;
mkcatchframe(ctx,NULL,&catchbuf);
if ((val=(pointer)eussetjmp(catchbuf))==0) {
val=funcode(ctx,func,args,noarg);}
else if ((eusinteger_t)val==1) {
val=NIL;
}

ctx->vsp=(pointer *)ctx->catchfp;
ctx->catchfp=(struct catchframe *)*ctx->vsp;
return(val);
}

pointer funcode(ctx,func,args,noarg)
register context *ctx;
register pointer func,args;
Expand Down Expand Up @@ -1610,7 +1632,7 @@ int noarg;

else if (piscode(func)) { /*call subr*/
GC_POINT;
result=funcode(ctx,func,args,noarg);
result=catchfuncode(ctx,func,args,noarg);
ctx->vsp=(pointer *)vf;
ctx->callfp= vf->vlink;
ctx->fletfp=oldfletfp;
Expand Down
5 changes: 3 additions & 2 deletions lisp/c/sysfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,8 +752,9 @@ pointer *argv;
struct catchframe *cfp=ctx->catchfp;
int i=0;
while (cfp) {
vpush(cfp->label);
i++;
if (cfp->label) {
vpush(cfp->label);
i++;}
cfp=cfp->nextcatch;}
return(stacknlist(ctx,i));}

Expand Down

0 comments on commit b896e81

Please sign in to comment.