Sounds very useful. Count me in favour. On a slightly related topic, I've wanted something to handle exceptions in XS, but I'm specifically interested in catching C++ exceptions in XS, converting them into Perl exceptions then sending them back into Perl to be caught with an eval.
To date I've had to wrap every XS function in an identical try/catch block to achieve it. This adds a lot of unnecessary bloat. Having all XS functions funnelled through a single user-defined function that contained the try/catch block would get rid of the bloat. Wrapper(...) { try { // Call real XS function } catch (std::exception & e) { // create Perl exception & croak } } So instead of an XSUB registration like this newXS("My::m1", XS_My_m1, file); newXS("My::m2", XS_My_m2, file); the registration would need to include a pointer to the wrapper function newXS("My::m1", XS_My_m1, wrapper, file); newXS("My::m2", XS_My_m2, wrapper, file); Paul > -----Original Message----- > From: Marcus Holland-Moritz [mailto:[EMAIL PROTECTED] > Sent: 02 January 2005 21:08 > To: p5p > Cc: Nick Ing-Simmons; perl-xs@perl.org > Subject: Add exception handling macros for XS code (was: Re: Catching > Perl_croak() from XS) > > I've posted the question below on perl-xs. > > It seems that at least Nick I-S and me are interested in > an easy way to catch Perl_croak() from within XS code > without using call_xx(). > > I've proposed a set of macros to hide the JMPENV_* stuff, > which isn't part of the public API. If nobody has objections, > I'd like to add these (or similar) macros to the core (and > Devel::PPPort). > > Marcus > > > On 2005-01-02, at 18:30:23 +0000, Nick Ing-Simmons wrote: > > > Marcus Holland-Moritz <[EMAIL PROTECTED]> writes: > > >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. > > > > Which is why I have to date avoid this and done this kind of thing > > one of two ways: > > A. Make the "object" a perl level object (as well) > > and give the perl class a DESTROY method which discards > > the C/C++ objuect. > > B. Wrap the callback (your .set) in a perl XS 'cv' > > and call that via call_sv(cv,G_EVAL) > > and the test SvTRUE(ERRSV) > > I've thought of both solutions already, but both seemed > like way too much overhead for what I wanted to do. > > > >Is this the way to do it? > > > > I am not entirely sure. > > > > >Or is there any other/better way? > > > > Two other ways above... > > > > > > > >If it turns out to be correct, would it make sense to document > > >it and/or add some public interface for this purpose? > > > > That would be good. > > > > > > > >Marcus > > > > > -- > QOTD: > "Like this rose, our love will wilt and die."