----- Original Message -----
From: "Marvin Humphrey" <[EMAIL PROTECTED]>
> SV* return_a_scalar (SV* input_sv) {
> if (return_the_input_unchanged) {
> SvREFCNT_inc(input_sv); /* otherwise it goes to zero */
> return input_sv;
> }
> else {
> SV* new_scalar = newSVpvn("foo", 3);
> return new_scalar;
> }
> }
>
Sometimes it's hellpful (not sure if "hellpful" is a typo or not) to look at
the C code that's actually being compiled because there are often things
going on in there that we're unaware of from our Inline::C or XS code.
eg:
use warnings;
use Devel::Peek;
use Inline C => Config =>
CLEAN_AFTER_BUILD => 0,
BUILD_NOISY => 1;
use Inline C => <<'END';
SV * foo(SV * x) {
return x;
}
SV * foo1(SV * x) {
SvREFCNT_inc(x);
return x;
}
void foo2(SV * x) {
Inline_Stack_Vars;
Inline_Stack_Reset;
Inline_Stack_Push(x);
Inline_Stack_Done;
Inline_Stack_Return(1);
}
SV * foo3(SV * x) {
SV * ret;
ret = newSViv((int)SvIV(x));
return ret;
}
END
$n = 42;
# foo() results in the refcount going to zero.
# All other functions work ok, I think.
#$z = foo($n);
#Dump($n);
#print "\n$z############\n";
$z = foo1($n);
Dump($n);
print "\n$z############\n";
$z = foo2($n);
Dump($n);
print "\n$z############\n";
$z = foo3($n);
Dump($n);
print "\n$z############\n";
__END__
After running that, go into the _Inline/build directory and take a look at
the C
file. (See below my sig for a copy of the C file I got.) I think the main
source of confusion arises from the sv_2mortal() calls. You'll see such a
call in both XS(XS_main_foo) and XS(XS_main_foo1). With the former, there's
the problem with which you are familiar, but there's no problem with the
latter because, I presume, of the Sv_REFCNT_inc() in foo1(). (I believe that
the Sv_REFCNT_inc is the correct fix for the problem, btw.)
There's no sv_2mortal() call in XS(XS_main_foo2) - so there's no problem
there either.
With XS(XS_main_foo3), the sv_2mortal() call reappears. Not sure why that
doesn't pose a problem - something to do with what's actually being assigned
to 'ret', I suspect. I'm a bit pressed for time .... in addition to my other
problem (dimness).
Hth.
Cheers,
Rob
/*
* This file was generated automatically by xsubpp version 1.9508 from the
* contents of try_pl_294f.xs. Do not edit this file, edit try_pl_294f.xs
instead.
*
* ANY CHANGES MADE HERE WILL BE LOST!
*
*/
#line 1 "try_pl_294f.xs"
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "INLINE.h"
SV * foo(SV * x) {
return x;
}
SV * foo1(SV * x) {
SvREFCNT_inc(x);
return x;
}
void foo2(SV * x) {
Inline_Stack_Vars;
Inline_Stack_Reset;
Inline_Stack_Push(x);
Inline_Stack_Done;
Inline_Stack_Return(1);
}
SV * foo3(SV * x) {
SV * ret;
ret = newSViv((int)SvIV(x));
return ret;
}
#line 40 "try_pl_294f.c"
XS(XS_main_foo); /* prototype to pass -Wmissing-prototypes */
XS(XS_main_foo)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: main::foo(x)");
{
SV * x = ST(0);
SV * RETVAL;
RETVAL = foo(x);
ST(0) = RETVAL;
sv_2mortal(ST(0));
}
XSRETURN(1);
}
XS(XS_main_foo1); /* prototype to pass -Wmissing-prototypes */
XS(XS_main_foo1)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: main::foo1(x)");
{
SV * x = ST(0);
SV * RETVAL;
RETVAL = foo1(x);
ST(0) = RETVAL;
sv_2mortal(ST(0));
}
XSRETURN(1);
}
XS(XS_main_foo2); /* prototype to pass -Wmissing-prototypes */
XS(XS_main_foo2)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: main::foo2(x)");
SP -= items;
{
SV * x = ST(0);
#line 47 "try_pl_294f.xs"
I32* temp;
#line 86 "try_pl_294f.c"
#line 49 "try_pl_294f.xs"
temp = PL_markstack_ptr++;
foo2(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 */
#line 97 "try_pl_294f.c"
PUTBACK;
return;
}
}
XS(XS_main_foo3); /* prototype to pass -Wmissing-prototypes */
XS(XS_main_foo3)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: main::foo3(x)");
{
SV * x = ST(0);
SV * RETVAL;
RETVAL = foo3(x);
ST(0) = RETVAL;
sv_2mortal(ST(0));
}
XSRETURN(1);
}
#ifdef __cplusplus
extern "C"
#endif
XS(boot_try_pl_294f); /* prototype to pass -Wmissing-prototypes */
XS(boot_try_pl_294f)
{
dXSARGS;
char* file = __FILE__;
XS_VERSION_BOOTCHECK ;
newXS("main::foo", XS_main_foo, file);
newXS("main::foo1", XS_main_foo1, file);
newXS("main::foo2", XS_main_foo2, file);
newXS("main::foo3", XS_main_foo3, file);
XSRETURN_YES;
}