Re: [R-pkg-devel] safely allocate SEXP and handle failure
В Thu, 21 Sep 2023 15:10:56 +0200 Jan Gorecki пишет: > Do you by any chance know any examples of using > R_withCallingErrorHandler? Or could you modify your example to use > this instead? Calling handlers are different from exiting handlers established by tryCatch. Instead of replacing the value of an expression that raised a condition with the return value of the exiting handler, calling handlers get an opportunity to clean up or invoke a so-called restart, but when they return, the execution continues: withCallingHandlers(stop("fatal"), error = function(cond) { writeLines("I'm a calling handler, this is my argument:") str(cond) }) # I'm a calling handler, this is my argument: # List of 2 # $ message: chr "fatal" # $ call : language withCallingHandlers(stop("fatal"), ... # - attr(*, "class")= chr [1:3] "simpleError" "error" "condition" # Error in withCallingHandlers(stop("fatal"), error = function(cond) { : # fatal Since setting up restarts will involve calling into R, a complete solution will involve much more code than R_tryCatchError. -- Best regards, Ivan __ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Re: [R-pkg-devel] safely allocate SEXP and handle failure
On Thu, 21 Sep 2023 09:46:26 +0200 Jan Gorecki wrote: > I would like to safely allocate R object from C. By safely I mean > that, I can test if allocation succeeded or failed, and then raise > exception myself. > R_alloc and allocVector both raises exception straightaway, so I am > not able to handle failed allocation myself. All R objects are subject to garbage collection (as potential garbage or at least as a source of information about live objects), so they have to be allocated by talking to the GC. (This also means that R_alloc() is not a good way to create new SEXPs.) It's not that it's impossible to return a failure code on allocation failures instead of performing a longjmp() away from your code, but since the rest of error handling in R works this way, extension code has to always be ready to be longjmp()'d away from at every R API call. How about catching the exception instead? struct alloc_args { SEXPTYPE type; R_xlen_t len; }; static SEXP do_allocate(void * arguments) { struct alloc_args * args = arguments; return allocVector(args->type, args->len); } static SEXP maybe_allocate(SEXPTYPE type, R_xlen_t len) { struct alloc_args args = { .type = type, .len = len }; return R_tryCatchError(do_allocate, &args, NULL, NULL); } // returns R_NilValue on failure via the default tryCatch handler Code is untested but should work according to WRE: https://cran.r-project.org/doc/manuals/R-exts.html#Condition-handling-and-cleanup-code -- Best regards, Ivan __ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
[R-pkg-devel] safely allocate SEXP and handle failure
Dear pkg developers I would like to safely allocate R object from C. By safely I mean that, I can test if allocation succeeded or failed, and then raise exception myself. R_alloc and allocVector both raises exception straightaway, so I am not able to handle failed allocation myself. In plain C it is something like that: int *x = malloc(nx*sizeof(int)); if (!x) { my_fun_to_set_exception_signal(); free(x); return; } How can I do it for creating SEXP object? Best Regards, Jan Gorecki __ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel