Of course one problem is that R hides things that I need for this, such as 
R_HandlerStack and R_ReturnedValue. 

I understand they have to be hidden, in which case can we have an exposed 
mechanism similar to what R_ToplevelExec does, but with the added functionality 
of giving access to the condition where R_ToplevelExec would return TRUE. 

Would someone be willing to review a patch to R with this added functionality. 
Please. 

In any case, I still would like some comments about my initial question about 
R_NilValue use in gotoExitingHandler(R_NilValue, call, entry);

Romain

Le 26 févr. 2014 à 09:41, Romain François <rom...@r-enthusiasts.com> a écrit :

> Hello, 
> 
> I’m trying to leverage R_ToplevelExec to implement C level try/catch. 
> 
> The way it is implemented allows for running a function in a top level 
> context. This context gets an empty handler stack, so either the function 
> runs correctly or it jumps. When it jumps, it does not find a handler, so it 
> jumps to the top level context. 
> 
> R does not allow me to call begin context and end context directly, so 
> instead what I do is call R_ToplevelExec, grab the global context inside the 
> function, install my own handler that I don’t set to be a calling one, 
> pretend this context is a CTXT_FUNCTION. 
> 
> Eventually I get to jump fun, so that I can later on grab the condition from 
> R_ReturnedValue. 
> 
> This works well in the « not simple error » case, i.e. if I call stop( 
> simpleError(...) ), but with simple errors, i.e. calls to Rf_error internally 
> or bare calls to stop( "vvzvz" ) I can’t access the error. 
> 
> And this boils down to this call: 
> 
> gotoExitingHandler(R_NilValue, call, entry);
> 
> inside vsignalError : 
> 
> static void vsignalError(SEXP call, const char *format, va_list ap)
> {
>    char localbuf[BUFSIZE];
>    SEXP list, oldstack;
> 
>    oldstack = R_HandlerStack;
>    Rvsnprintf(localbuf, BUFSIZE - 1, format, ap);
>    while ((list = findSimpleErrorHandler()) != R_NilValue) {
>       char *buf = errbuf;
>       SEXP entry = CAR(list);
>       R_HandlerStack = CDR(list);
>       strncpy(buf, localbuf, BUFSIZE - 1);
>       /*      Rvsnprintf(buf, BUFSIZE - 1, format, ap);*/
>       buf[BUFSIZE - 1] = 0;
>       if (IS_CALLING_ENTRY(entry)) {
>           if (ENTRY_HANDLER(entry) == R_RestartToken)
>               return; /* go to default error handling; do not reset stack */
>           else {
>               SEXP hooksym, hcall, qcall;
>               /* protect oldstack here, not outside loop, so handler
>                  stack gets unwound in case error is protect stack
>                  overflow */
>               PROTECT(oldstack);
>               hooksym = install(".handleSimpleError");
>               PROTECT(qcall = LCONS(R_QuoteSymbol,
>                                     LCONS(call, R_NilValue)));
>               PROTECT(hcall = LCONS(qcall, R_NilValue));
>               hcall = LCONS(mkString(buf), hcall);
>               hcall = LCONS(ENTRY_HANDLER(entry), hcall);
>               PROTECT(hcall = LCONS(hooksym, hcall));
>               eval(hcall, R_GlobalEnv);
>               UNPROTECT(4);
>           }
>       }
>       else gotoExitingHandler(R_NilValue, call, entry);   // <<<  HERE
>    }
>    R_HandlerStack = oldstack;
> }
> 
> Would it be possible to construct a simple condition instead of passing down 
> R_NilValue so that I can grab this error and deal with it. 
> 
> The alternative is to set the handler to be a calling one, but I’d like to 
> avoid that as much as possible as this means going back to the R side of 
> things just to get access to the condition. 
> 
> My code is here: https://gist.github.com/romainfrancois/9225811
> 
> I have only tested this on OSX with R-devel. The code only uses R internal 
> api (not Rcpp*). 
> 
> So down to what I’d like you to consider please if you are still reading 
> here. Can we feed gotoExitingHandler with something more interesting than 
> NULL. please. 
> 
> 
> 
> The end game is to add one layer of abstraction, e.g. pass to R_ToplevelExec 
> a function that first deals with contexts, then calls an actual function. 
> Combining this with lambda functions in C++ will make quite a nice and 
> elegant way to handle error handling at the C++ level. 
> 
> I can provide the code that would create the simpleError, this is just making 
> a simple VECSXP with names and classes, no big trouble here. 
> 
> Romain
> 
> ______________________________________________
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to