Rcpp Version 1.0.14
Loading...
Searching...
No Matches
Rcpp_eval.h
Go to the documentation of this file.
1// Copyright (C) 2013 Romain Francois
2//
3// This file is part of Rcpp.
4//
5// Rcpp is free software: you can redistribute it and/or modify it
6// under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 2 of the License, or
8// (at your option) any later version.
9//
10// Rcpp is distributed in the hope that it will be useful, but
11// WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
17
18#ifndef Rcpp_api_meat_Rcpp_eval_h
19#define Rcpp_api_meat_Rcpp_eval_h
20
21#include <Rcpp/Interrupt.h>
22#include <Rversion.h>
23
24
25namespace Rcpp { namespace internal {
26
27#ifdef RCPP_USING_UNWIND_PROTECT
28
29struct EvalData {
30 SEXP expr;
31 SEXP env;
32 EvalData(SEXP expr_, SEXP env_) : expr(expr_), env(env_) { }
33};
34
36 EvalData* data = static_cast<EvalData*>(eval_data);
37 return ::Rf_eval(data->expr, data->env);
38}
39
40// This is used internally instead of Rf_eval() to make evaluation safer
41inline SEXP Rcpp_eval_impl(SEXP expr, SEXP env) {
42 return Rcpp_fast_eval(expr, env);
43}
44
45#else // R < 3.5.0
46
47// Fall back to Rf_eval() when the protect-unwind API is unavailable
49 return ::Rf_eval(expr, env);
50}
51
52#endif
53
54}} // namespace Rcpp::internal
55
56
57namespace Rcpp {
58
59#ifdef RCPP_USING_UNWIND_PROTECT
60
61inline SEXP Rcpp_fast_eval(SEXP expr, SEXP env) {
62 internal::EvalData data(expr, env);
64}
65
66#else
67
69 return Rcpp_eval(expr, env);
70}
71
72#endif
73
74
75inline SEXP Rcpp_eval(SEXP expr, SEXP env) {
76
77 // 'identity' function used to capture errors, interrupts
79
80 if (identity == R_UnboundValue) {
81 stop("Failed to find 'base::identity()'");
82 }
83
84 // define the evalq call -- the actual R evaluation we want to execute
86
87 // define the call -- enclose with `tryCatch` so we can record and forward error messages
88 Shield<SEXP> call(Rf_lang4(::Rf_install("tryCatch"), evalqCall, identity, identity));
89 SET_TAG(CDDR(call), ::Rf_install("error"));
90 SET_TAG(CDDR(CDR(call)), ::Rf_install("interrupt"));
91
93
94 // check for condition results (errors, interrupts)
95 if (Rf_inherits(res, "condition")) {
96
97 if (Rf_inherits(res, "error")) {
98
100
103 }
104
105 // check for interrupt
106 if (Rf_inherits(res, "interrupt")) {
108 }
109
110 }
111
112 return res;
113}
114
115} // namespace Rcpp
116
117#endif
T as(SEXP x, ::Rcpp::traits::r_type_primitive_tag)
Definition as.h:43
SEXP Rcpp_eval_impl(SEXP expr, SEXP env)
Definition Rcpp_eval.h:48
Rcpp API.
Definition algo.h:28
void NORET stop(const std::string &message)
Definition exceptions.h:117
SEXP Rcpp_fast_eval(SEXP expr, SEXP env)
Definition Rcpp_eval.h:68
SEXP Rcpp_eval(SEXP expr, SEXP env)
Definition Rcpp_eval.h:75
SEXP unwindProtect(SEXP(*callback)(void *data), void *data)
T as(SEXP x)
Definition as.h:151