@@ -126,13 +126,42 @@ namespace Rcpp{
126
126
127
127
} // namespace Rcpp
128
128
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
+ }
131
132
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);
136
165
}
137
166
138
167
inline SEXP get_exception_classes ( const std::string& ex_class) {
0 commit comments