Skip to content

Commit bb82bd9

Browse files
committed
Match the Rcpp_eval tryCatch(eval(sys.call(), ...)) call explicitly
1 parent 1f7c623 commit bb82bd9

File tree

1 file changed

+35
-6
lines changed

1 file changed

+35
-6
lines changed

inst/include/Rcpp/exceptions.h

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,42 @@ namespace Rcpp{
126126

127127
} // namespace Rcpp
128128

129-
inline SEXP get_last_call(){
130-
SEXP sys_calls_symbol = Rf_install( "sys.call" ) ;
129+
inline SEXP nth(SEXP s, int n) {
130+
return Rf_length(s) > n ? (n == 0 ? CAR(s) : CAR(Rf_nthcdr(s, n))) : R_NilValue;
131+
}
131132

132-
// -9 Skips the wrapped tryCatch from Rcpp_eval
133-
Rcpp::Shield<SEXP> sys_calls_expr( Rf_lang2(sys_calls_symbol, Rf_ScalarInteger(-9)) );
134-
Rcpp::Shield<SEXP> calls( Rcpp_eval( sys_calls_expr, R_GlobalEnv ) );
135-
return calls;
133+
inline SEXP get_last_call(){
134+
SEXP sys_calls_symbol = Rf_install("sys.calls");
135+
SEXP identity_symbol = Rf_install("identity");
136+
SEXP identity_fun = Rf_findFun(identity_symbol, R_BaseEnv);
137+
SEXP tryCatch_symbol = Rf_install("tryCatch");
138+
SEXP evalq_symbol = Rf_install("evalq");
139+
140+
Rcpp::Shield<SEXP> sys_calls_expr(Rf_lang1(sys_calls_symbol));
141+
Rcpp::Shield<SEXP> calls(Rcpp_eval(sys_calls_expr, R_GlobalEnv));
142+
143+
SEXP cur, prev;
144+
prev = cur = calls;
145+
while(CDR(cur) != R_NilValue) {
146+
SEXP expr = CAR(cur);
147+
148+
// We want the call just prior to the call from Rcpp_eval
149+
// This conditional matches
150+
// tryCatch(evalq(sys.calls(), .GlobalEnv), error = identity, interrupt = identity)
151+
if (TYPEOF(expr) == LANGSXP &&
152+
Rf_length(expr) == 4 &&
153+
nth(expr, 0) == tryCatch_symbol &&
154+
CAR(nth(expr, 1)) == evalq_symbol &&
155+
CAR(nth(nth(expr, 1), 1)) == sys_calls_symbol &&
156+
nth(nth(expr, 1), 2) == R_GlobalEnv &&
157+
nth(expr, 2) == identity_fun &&
158+
nth(expr, 3) == identity_fun) {
159+
break;
160+
}
161+
prev = cur;
162+
cur = CDR(cur);
163+
}
164+
return CAR(prev);
136165
}
137166

138167
inline SEXP get_exception_classes( const std::string& ex_class) {

0 commit comments

Comments
 (0)