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