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)

>
>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

Reply via email to