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




Reply via email to