I'm wondering if someone else ever wanted to do this... Deep inside my XS module I create an object and pass it to a function (which may pass it to other functions and so on). However, any of these functions may call Perl_croak(), and if they do, I need to destroy the object if I don't want to leak memory. Here's an excerpt of the original code:
tag = tag_new(tagid, gs_TagTbl[tagid].vtbl); rv = gs_TagTbl[tagid].set(aTHX_ ptti, tag, val); insert_tag(ptl, tag); Calling the 'set' method in the second line may eventually call croak(). If it does, I just want to throw away the tag object and croak() again. I didn't find anything in perl(xs|guts|call|api), so I looked at how "eval" does it, and came up with the following macros: #define dXCPT dJMPENV; int rEtV = 0 #define XCPT_TRY_START JMPENV_PUSH(rEtV); \ if (rEtV == 0) #define XCPT_TRY_END JMPENV_POP; #define XCPT_CATCH if (rEtV != 0) #define XCPT_RETHROW JMPENV_JUMP(rEtV) With these macros, I can rewrite the above code as: dXCPT; tag = tag_new(tagid, gs_TagTbl[tagid].vtbl); XCPT_TRY_START { rv = gs_TagTbl[tagid].set(aTHX_ ptti, tag, val); } XCPT_TRY_END XCPT_CATCH { tag_delete(tag); XCPT_RETHROW; } insert_tag(ptl, tag); This seems to work fine, but makes use of internal API. Is this the way to do it? Or is there any other/better way? If it turns out to be correct, would it make sense to document it and/or add some public interface for this purpose? Marcus -- Bender: "Like most of life's problems, this one can be solved with bending."