7

I have a complex encoding function in Pure Perl which I am converting to XS in the hope of gaining a performance boost.

The function I am converting to XS needs to recursively call itself. I can see how to use call_sv [thanks to "man perlcall"] to call Pure Perl functions.

But how the heck do I call myself (or any other XS function) from within XS?

(P.S. Efficiency is very desirable...)

Can somebody throw me a hint? Or an example? P-p-p-please!

UPDATE: First answer was absolutely correct. Calling out to recursive pure C functions works just fine.

the.jxc
  • 3,373
  • 21
  • 21

1 Answers1

10

Don't. XS is a mechanism to provide a Perl interface to a C function. Don't call the XS function from the C function (for which you'd use call_sv or the like); call the C function from the XS function.

Write your recursive C function and keep it outside of the XS code (before the MODULE = line or in a separate .c). Call it from a thin XS wrapper.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Ah... indeed I very much considered that approach. The problem is that I am using croak as my exception handling mechanism, and pure-C won't allow me to do that, will it? – the.jxc Apr 19 '13 at 09:01
  • Also, the parsing function is being driven by Perl hash structures (for encode) and is constructing hash structures (for decode). So I am parsing and working with SV structures throughout the code. Having the main function be in XS means XS will handle all my header files, and I can use mortals to ensure my SV buffers are reference counted properly. So ditching XS would be my last resort! – the.jxc Apr 19 '13 at 09:08
  • @the.jxc: You can use Perl data structures and functions from the Perl C API in your C functions, that is not an issue. – salva Apr 19 '13 at 09:23
  • @salva: Yeah, and even the reference counting I guess I can cope with. It's the "croak" that is the real challenge. – the.jxc Apr 19 '13 at 09:37
  • 2
    @the.jxc: No problem with that either, you can use `croak` from the C functions. Personally, I like to pass the perl context explicitly using the `THX` set of macros and then call `croak` as `Perl_croak(aTHX_ format, ...)`, but I think that just calling `croak(fmt, ...)` should also work. – salva Apr 19 '13 at 09:56
  • @salva: Now that's something I did not know. If I can croak from pure C, and get my reference counting correct, then this looks good. I'm gonna mark this one as "Answered", and try this all out on Monday. Muchos Gracias to both you and ikegami. – the.jxc Apr 19 '13 at 10:39
  • Oh, one last question! If I use sv_2mortal inside the inner pure-C function (within an XS outer call), will the mortal SV still receive a reference counter decrement when I finally return from the XS outer method? – the.jxc Apr 19 '13 at 11:31
  • @the.jxc: yes, they will be freed. You can also use `ENTER/SAVETEMPS/FREETEMPS/LEAVE` macros to create scoped from C – salva Apr 19 '13 at 14:01
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/28544/discussion-between-the-jxc-and-salva) – the.jxc Apr 20 '13 at 04:54