Rcpp Version 1.1.2
Loading...
Searching...
No Matches
Rcpp_eval.h
Go to the documentation of this file.
1// Copyright (C) 2013 - 2025 Romain Francois
2// Copyright (C) 2026 Romain Francois, Dirk Eddelbuettel and IƱaki Ucar
3//
4// This file is part of Rcpp.
5//
6// Rcpp is free software: you can redistribute it and/or modify it
7// under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 2 of the License, or
9// (at your option) any later version.
10//
11// Rcpp is distributed in the hope that it will be useful, but
12// WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
18
19#ifndef Rcpp_api_meat_Rcpp_eval_h
20#define Rcpp_api_meat_Rcpp_eval_h
21
22#include <Rcpp/Interrupt.h>
23#include <Rversion.h>
24
25
26namespace Rcpp { namespace internal {
27
28struct EvalData {
29 SEXP expr;
30 SEXP env;
31 EvalData(SEXP expr_, SEXP env_) : expr(expr_), env(env_) { }
32};
33
34inline SEXP Rcpp_protected_eval(void* eval_data) {
35 EvalData* data = static_cast<EvalData*>(eval_data);
36 return ::Rf_eval(data->expr, data->env);
37}
38
39// This is used internally instead of Rf_eval() to make evaluation safer
40inline SEXP Rcpp_eval_impl(SEXP expr, SEXP env) { // #nocov
41 return Rcpp_fast_eval(expr, env); // #nocov
42}
43
44}} // namespace Rcpp::internal
45
46
47namespace Rcpp {
48
49inline SEXP Rcpp_fast_eval(SEXP expr, SEXP env) {
50 internal::EvalData data(expr, env);
52}
53
54inline SEXP Rcpp_eval(SEXP expr, SEXP env) {
55
56 // 'identity' function used to capture errors, interrupts
57 Shield<SEXP> identity(Rf_findFun(::Rf_install("identity"), R_BaseNamespace));
58
59 // define the evalq call -- the actual R evaluation we want to execute
60 Shield<SEXP> evalqCall(Rf_lang3(::Rf_install("evalq"), expr, env));
61
62 // define the call -- enclose with `tryCatch` so we can record and forward error messages
63 Shield<SEXP> call(Rf_lang4(::Rf_install("tryCatch"), evalqCall, identity, identity));
64 SET_TAG(CDDR(call), ::Rf_install("error"));
65 SET_TAG(CDDR(CDR(call)), ::Rf_install("interrupt"));
66
67 Shield<SEXP> res(internal::Rcpp_eval_impl(call, R_BaseEnv));
68
69 // check for condition results (errors, interrupts)
70 if (Rf_inherits(res, "condition")) {
71
72 if (Rf_inherits(res, "error")) {
73
74 Shield<SEXP> conditionMessageCall(::Rf_lang2(::Rf_install("conditionMessage"), res));
75
76 Shield<SEXP> conditionMessage(internal::Rcpp_eval_impl(conditionMessageCall, R_BaseEnv));
77 throw eval_error(CHAR(STRING_ELT(conditionMessage, 0)));
78 }
79
80 // check for interrupt
81 if (Rf_inherits(res, "interrupt")) {
83 }
84
85 }
86
87 return res;
88}
89
90} // namespace Rcpp
91
92#endif
internal implementation details
Definition Date.h:43
SEXP Rcpp_protected_eval(void *eval_data)
Definition Rcpp_eval.h:34
SEXP Rcpp_eval_impl(SEXP expr, SEXP env)
Definition Rcpp_eval.h:40
Rcpp API.
Definition algo.h:28
SEXP Rcpp_fast_eval(SEXP expr, SEXP env)
Definition Rcpp_eval.h:49
SEXP Rcpp_eval(SEXP expr, SEXP env)
Definition Rcpp_eval.h:54
SEXP unwindProtect(SEXP(*callback)(void *data), void *data)
EvalData(SEXP expr_, SEXP env_)
Definition Rcpp_eval.h:31