Skip to content

Commit fde283d

Browse files
committed
evaluate R code with R_ToplevelExec
1 parent e47cd95 commit fde283d

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

inst/include/Rcpp/api/meat/Rcpp_eval.h

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,25 @@
1818
#ifndef Rcpp_api_meat_Rcpp_eval_h
1919
#define Rcpp_api_meat_Rcpp_eval_h
2020

21+
#include <R_ext/GraphicsEngine.h>
22+
2123
namespace Rcpp{
2224

23-
inline SEXP Rcpp_eval(SEXP expr_, SEXP env) {
25+
namespace {
26+
struct EvalCall {
27+
SEXP expr_;
28+
SEXP env;
29+
SEXP result;
30+
std::string error_message;
31+
};
32+
} // anonymous namespace
33+
34+
inline void Rcpp_eval(void* data) {
35+
36+
EvalCall* evalCall = (EvalCall*)data;
37+
SEXP expr_ = evalCall->expr_;
38+
SEXP env = evalCall->env;
39+
2440
Shield<SEXP> expr( expr_) ;
2541

2642
reset_current_error() ;
@@ -45,11 +61,21 @@ namespace Rcpp{
4561
Shield<SEXP> current_error ( rcpp_get_current_error() ) ;
4662
Shield<SEXP> conditionMessageCall (::Rf_lang2(conditionMessageSym, current_error)) ;
4763
Shield<SEXP> condition_message (::Rf_eval(conditionMessageCall, R_GlobalEnv)) ;
48-
std::string message(CHAR(::Rf_asChar(condition_message)));
49-
throw eval_error(message) ;
64+
evalCall->error_message = std::string(CHAR(::Rf_asChar(condition_message)));
65+
} else {
66+
evalCall->result = res;
5067
}
68+
}
5169

52-
return res ;
70+
inline SEXP Rcpp_eval(SEXP expr_, SEXP env) {
71+
EvalCall call;
72+
call.expr_ = expr_;
73+
call.env = env;
74+
R_ToplevelExec(Rcpp_eval, (void*)&call);
75+
if (!call.error_message.empty())
76+
throw eval_error(call.error_message);
77+
else
78+
return call.result;
5379
}
5480

5581
}

0 commit comments

Comments
 (0)