[Rcpp-commits] r377 - in pkg: R src
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Fri Jan 15 15:20:08 CET 2010
Author: romain
Date: 2010-01-15 15:20:08 +0100 (Fri, 15 Jan 2010)
New Revision: 377
Modified:
pkg/R/exceptions.R
pkg/src/Evaluator.cpp
Log:
revert exception handling to use tryCatch again
Modified: pkg/R/exceptions.R
===================================================================
--- pkg/R/exceptions.R 2010-01-15 09:00:56 UTC (rev 376)
+++ pkg/R/exceptions.R 2010-01-15 14:20:08 UTC (rev 377)
@@ -34,16 +34,19 @@
setErrorOccured(FALSE)
}
getCurrentError <- function() exceptions[["current"]]
-errorOccured <- function() isTRUE( exceptions[["error_occured"]] )
setErrorOccured <- function(error_occured = TRUE) exceptions[["error_occured"]] <- error_occured
+setErrorOccured(FALSE)
+
+# all below are called from Evaluator::run
+# on the C++ side, don't change them unless you also change
+# Evaluator::run
+
+getCurrentErrorMessage <- function() conditionMessage( exceptions[["current"]] )
resetCurrentError()
-protectedEval <- function(expr, env ){
- resetCurrentError()
- tryCatch( eval( expr, envir = env), error = function(e){
- setErrorOccured( TRUE )
- setCurrentError( e )
- invisible( NULL )
- } )
+errorOccured <- function() isTRUE( exceptions[["error_occured"]] )
+.rcpp_error_recorder <- function(e){
+ setErrorOccured( TRUE )
+ setCurrentError( e )
+ invisible( NULL )
}
-setErrorOccured(FALSE)
Modified: pkg/src/Evaluator.cpp
===================================================================
--- pkg/src/Evaluator.cpp 2010-01-15 09:00:56 UTC (rev 376)
+++ pkg/src/Evaluator.cpp 2010-01-15 14:20:08 UTC (rev 377)
@@ -30,21 +30,36 @@
const char* Evaluator::eval_error::what() const throw(){ return message.c_str() ; }
SEXP Evaluator::run(SEXP expr, SEXP env) throw(eval_error) {
- int error = 0 ;
- SEXP res = PROTECT( R_tryEval( expr, env, &error ) ) ;
+
+ /* grab the RCPP namespace */
+ SEXP RCPP = PROTECT( R_FindNamespace( Rf_mkString( "Rcpp") ) );
+
+ /* reset the error cache */
+ Rf_eval( Rf_lang1( Rf_install( "resetCurrentError" ) ), RCPP ) ;
+
+ /* grab the error handler from the Rcpp namespace */
+ SEXP handler = PROTECT( Rf_findVarInFrame( RCPP, Rf_install(".rcpp_error_recorder") ) ) ;
+
+ /* call to tryCatch, we can probably do better by looking into what tryCatch does */
+ SEXP trycatchcall = PROTECT( Rf_lcons( Rf_install( "tryCatch" ),
+ Rf_cons( expr, Rf_cons( handler , R_NilValue ) ) ) ) ;
+ SET_TAG( CDDR(trycatchcall), Rf_install( "error" ) ) ;
+
+ /* call the tryCatch call */
+ SEXP res = PROTECT( Rf_eval( trycatchcall, R_GlobalEnv ) );
+
+ /* was there an error ? */
+ int error = LOGICAL( Rf_eval( Rf_lang1( Rf_install("errorOccured") ), RCPP ) )[0];
+
if( error ){
- UNPROTECT( 1 ) ; /* res */
- SEXP message = PROTECT( Rf_eval( Rf_lang1( Rf_install("geterrmessage") ), R_GlobalEnv ) );
- std::string err_msg ;
- if( TYPEOF( message ) == STRSXP && Rf_length( message ) ){
- err_msg = CHAR( STRING_ELT( message, 0 ) ) ;
- } else{
- err_msg = "error with no message" ;
- }
- UNPROTECT(1) ; /* message */
- throw eval_error( err_msg ) ;
+ SEXP err_msg = PROTECT( Rf_eval(
+ Rf_lang1( Rf_install("getCurrentErrorMessage")),
+ RCPP ) );
+ std::string message = CHAR(STRING_ELT(err_msg,0)) ;
+ UNPROTECT( 5 ) ;
+ throw eval_error(message) ;
} else {
- UNPROTECT( 1) ; /* res */
+ UNPROTECT(4) ;
return res ;
}
}
More information about the Rcpp-commits
mailing list