Hi,
For this perl (Inline::C) script:
### try.pl ###
use strict;
use warnings;
use Inline C => Config =>
FORCE_BUILD => 1,
BUILD_NOISY => 1,
CLEAN_AFTER_BUILD => 0,
;
use Inline C => <<'EOC';
void foo(SV * x, ...) {
dXSARGS;
int i, ret = 0;
for(i = 0; i < items; i++) {
ret += (int)SvIV(ST(i));
}
printf("%d\n", ret);
XSRETURN(0);
}
EOC
# Apart from the building output, this script
# finally outputs -5 (== 1 + 2 + 3 - 11)
foo(1,2,3,-11);
Inline::C will generate the following XS file:
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "INLINE.h"
void foo(SV * x, ...) {
dXSARGS;
int i, ret = 0;
for(i = 0; i < items; i++) {
ret += (int)SvIV(ST(i));
}
printf("%d\n", ret);
XSRETURN(0);
}
MODULE = try_pl_22db PACKAGE = main
PROTOTYPES: DISABLE
void
foo (x, ...)
SV * x
PREINIT:
I32* temp;
PPCODE:
temp = PL_markstack_ptr++;
foo(x);
if (PL_markstack_ptr != temp) {
/* truly void, because dXSARGS not invoked */
PL_markstack_ptr = temp;
XSRETURN_EMPTY; /* return empty stack */
}
/* must have used dXSARGS; list context implied */
return; /* assume stack size is correct */
(That Inline.h file is automatically included. It's not used or needed in this case, and can be ignored.)
It's the
PL_markstack_ptr dance with the
temp pointer at the end that I'm particularly interested in - with an aim to avoiding it.
Some "void" functions will return nothing, others will return values off the stack.
Inline::C performs that dance to determine whether this void function is returning something, or whether it is "truly void".
I use Inline::C to generate quite a few XS files, and I'm hoping to avoid having to include this dance, especially since it started spitting out warnings in bleadperl recently (but since fixed).
It's not something you see in other XS files, and I figure it shouldn't be too hard to avoid.
The one thing I really don't understand is the need to restore the value of PL_markstack_ptr to the value held by temp (
PL_markstack_ptr = temp;), prior to returning empty.
To date, I've had good success in removing this dance. For "truly void" functions that invoke dXSARGS (such as the given example), the implementation at the end of that XS file can be rewritten as
void
foo (x, ...)
SV * x
CODE:
PL_markstack_ptr++;
foo(x);
XSRETURN_EMPTY;
However, in this instance,
PL_markstack_ptr has not been reset to the value it held prior to its incrementation.
Under what circumstances might that omission bite ?
I
think (needs double checking) that, with the way I've constructed
foo(),
PL_markstack_ptr does need to be incremented - but I'd prefer not to perform that original dance if I don't have to.
UPDATE: Just double checked and found an instance of a very similar function that
does require that
PL_markstack_ptr is incremented.
Cheers,
Rob
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
|
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.