* Wrapping sigsetjmps/siglongjmps in OCaml.
@ 2009-11-30 0:38 Guillaume Yziquel
0 siblings, 0 replies; only message in thread
From: Guillaume Yziquel @ 2009-11-30 0:38 UTC (permalink / raw)
To: OCaml List
Hello.
I'm having some problems wrapping up the API for the R interpreter,
namely because R seems to be using sigsetjmps and siglongjmps
everywhere: that's how looping is implemented, for instance. (At least
that's how I understand the source code).
So I was wondering: what's the "best" way to wrap up such jumps in OCaml
code? It may be that the jumps would happen in one single C function. Or
it may be, due to a rather restrictive API for R, that I may have to
reimplement some C code entirely in OCaml. In which case, the jumps
would go over OCaml code.
How would you deal with that?
Here's the LONGJMP:
SETJMP and LONGJMP are just macros to sigsetjmp and siglongjmp.
> /* jumpfun - jump to the named context */
>
> static void jumpfun(RCNTXT * cptr, int mask, SEXP val)
> {
> Rboolean savevis = R_Visible;
>
> /* run onexit/cend code for all contexts down to but not including
> the jump target */
> PROTECT(val);
> R_run_onexits(cptr);
> UNPROTECT(1);
> R_Visible = savevis;
>
> R_ReturnedValue = val;
> R_GlobalContext = cptr; /* this used to be set to
> cptr->nextcontext for non-toplevel
> jumps (with the context set back at the
> SETJMP for restarts). Changing this to
> always using cptr as the new global
> context should simplify some code and
> perhaps allow loops to be handled with
> fewer SETJMP's. LT */
> R_restore_globals(R_GlobalContext);
>
> LONGJMP(cptr->cjmpbuf, mask);
> }
Here's the SETJMP
> SEXP applyClosure(SEXP call, SEXP op, SEXP arglist, SEXP rho, SEXP suppliedenv)
> {
> SEXP body, formals, actuals, savedrho;
> volatile SEXP newrho;
> SEXP f, a, tmp;
> RCNTXT cntxt;
>
> /* formals = list of formal parameters */
> /* actuals = values to be bound to formals */
> /* arglist = the tagged list of arguments */
>
> formals = FORMALS(op);
> body = BODY(op);
> savedrho = CLOENV(op);
>
> [...]
>
> /* Set a longjmp target which will catch any explicit returns
> from the function body. */
>
> if ((SETJMP(cntxt.cjmpbuf))) {
> if (R_ReturnedValue == R_RestartToken) {
> cntxt.callflag = CTXT_RETURN; /* turn restart off */
> R_ReturnedValue = R_NilValue; /* remove restart token */
> PROTECT(tmp = eval(body, newrho));
> }
> else
> PROTECT(tmp = R_ReturnedValue);
> }
> else {
> PROTECT(tmp = eval(body, newrho));
> }
>
> endcontext(&cntxt);
>
> if (RDEBUG(op)) {
> Rprintf("exiting from: ");
> PrintValueRec(call, rho);
> }
> UNPROTECT(3);
> return (tmp);
> }
All the best,
--
Guillaume Yziquel
http://yziquel.homelinux.org/
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-11-30 0:38 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-30 0:38 Wrapping sigsetjmps/siglongjmps in OCaml Guillaume Yziquel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).