@@ -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
138167inline SEXP get_exception_classes ( const std::string& ex_class) {
0 commit comments