Never mind. For my initial question, I can just use: R_curErrorBuf My current implementation now only depend on R_FunTab and R_GlobalContext which R does not conceal behind attribute_hidden. https://github.com/romainfrancois/Rcpp11/blob/master/inst/include/Rcpp/Context.h
Romain Le 27 févr. 2014 à 08:13, Romain François <rom...@r-enthusiasts.com> a écrit : > 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 ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel