Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R_tryEval implementation #523

Open
david-bouyssie opened this issue Nov 16, 2020 · 3 comments
Open

R_tryEval implementation #523

david-bouyssie opened this issue Nov 16, 2020 · 3 comments

Comments

@david-bouyssie
Copy link

R_tryEval is currently not supported:
https://github.com/bedatadriven/renjin/blob/master/tools/gnur-runtime/src/main/java/org/renjin/gnur/api/Rinternals.java#L2256

Can we hope any workaround in the future?

@akbertram
Copy link
Member

Pull requests welcome!

The implementation should be fairly simple, but I'm not sure what is expected in the event of error. See the implementation fo Rf_eval:

public static SEXP Rf_eval(SEXP e, SEXP rho) {

@david-bouyssie
Copy link
Author

If fear I'm not enough skilled to submit a PR on this topic, sorry.
I reported this issue because I have seen packages complaining for this missing function.

@perNyfelt
Copy link
Contributor

The documentation for how this should behave is a bit sparse but the following snippet from the embedded guide says the following:

Handling Errors
An application that embeds R must be careful to take care of handling errors that occur within the R engine appropriately. In the stand-alone version of R, an error will (after other on.error() activities in each evaluation frame) return control to the main input-eval-print loop. In general, this is not what is desired within another application. Instead, we want to trap such R errors and handle them from where the application passed control to the R engine.
This can be done most readily using the C routine R_tryEval to evaluate the S expression. This does exactly what we want by guaranteeing to return to this point in the calling code whether an error occurred or not in evaluating the expression. This routine is similar to eval, taking both the expression to evaluate and an environment in which to perform the evaluation. It takes a third argument which is the address of an integer. If this is non-NULL, when the call returns, this contains a flag indicating whether there was an error or not.

Example

int
callFoo()
{
 SEXP e, val;
 int errorOccurred;
 int result = -1;

 PROTECT(e = allocVector(LANGSXP, 1));
 SETCAR(e, Rf_install("foo"));

 val = R_tryEval(e, R_GlobalEnv, &errorOccurred);

 if(!errorOccurred) {
   PROTECT(val);
   result = INTEGER(val)[0];
   UNPROTECT(1);
 } else {
   fprintf(stderr, "An error occurred when calling foo\n");
   fflush(stderr);
 }

    /* Assume we have an INTSXP here. */

 UNPROTECT(1); /* e */

return(result);
}

Note that this will, by default, take care of handling all types of errors that R would usually handle including signals. So if the user sends an interrupt to a computation (e.g. using Ctrl-C) while an R expression is being evaluated, R_tryEval will return and report an error. If the host application however changes the signal mask and/or handlers from R's own ones, of course this will not necessarily happen. In other words, the host application can control the signal handling differently

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants