From: Guillaume Yziquel <guillaume.yziquel@citycable.ch>
To: OCaml List <caml-list@inria.fr>
Subject: Wrapping sigsetjmps/siglongjmps in OCaml.
Date: Mon, 30 Nov 2009 01:38:15 +0100 [thread overview]
Message-ID: <4B1313F7.8070501@citycable.ch> (raw)
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/
reply other threads:[~2009-11-30 0:38 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4B1313F7.8070501@citycable.ch \
--to=guillaume.yziquel@citycable.ch \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).