llancet has asked for the wisdom of the Perl Monks concerning the following question:

For instance, in this piece of code:

SV* my_sv = newSViv(12345); XPUSHs(my_sv);
Does XPUSHs make a copy of my_sv, or it really pushes my_sv into stack?

And in this piece of code:

SPAGAIN; ENTER; SAVETMPS; PUSHMARK(SP); call_pv( "a_perl_sub_that_return_something", some_flags ); SV* return = POPs; FREETMPS; LEAVE;
It seems if I want to use the poped SV permanently (after FREETMPS and LEAVE), I have to make a copy of return by newSVsv(), otherwise return will lose the value inside it?
Do I need to free the return manually, or it has been done automatically by FREETMPS and LEAVE?

Replies are listed 'Best First'.
Re: What does perl stack OPs really do?
by ikegami (Patriarch) on Jun 20, 2011 at 18:36 UTC

    Does XPUSHs make a copy of my_sv, or it really pushes my_sv into stack?

    It really pushes it onto the stack.

    #define XPUSHs(s) STMT_START { EXTEND(sp,1); (*++sp = (s)); } STMT_END

    Your code has a memory leak, though. The scalar won't get freed since you didn't mortalise it, meaning you didn't tell Perl the stack owns a reference to it.

    SV* my_sv = newSViv(12345); XPUSHs(sv_2mortal(my_sv));

    Same thing:

    SV* my_sv = newSViv(12345); mXPUSHs(my_sv);

    It seems if I want to use the poped SV permanently (after FREETMPS and LEAVE), I have to make a copy of return by newSVsv(),

    I think you can simple increase its REFCNT. If you do this, it's your responsibility to decrement its REFCNT when you're done with it.

    Do I need to free the return manually, or it has been done automatically by FREETMPS and LEAVE?

    You just have to call FREETMPS.

      I found that perl actually don't return the same scalar. For example:
      # perl code { my $static_var = 0; sub return_it { return $static_var } }
      If I call this sub from C code several times, each time I will obtain returned SVs that have different address. The SVs are observed instantly after pop:
      SV* tmp = POPs; Perl_sv_dump(my_perl,tmp);
      Why? Does perl already made a copy of return values?
        I found that perl actually don't return the same scalar...

        Doubtful. Can you copy/paste the output?

        Or better still, a patch , something along the lines of

        $ diff -ruN tmp.empty tmp.full diff -ruN tmp.empty/1 tmp.full/1 --- tmp.empty/1 1969-12-31 16:00:00.000000000 -0800 +++ tmp.full/1 2011-06-23 02:46:59.875000000 -0700 @@ -0,0 +1 @@ +ECHO is on. diff -ruN tmp.empty/2 tmp.full/2 --- tmp.empty/2 1969-12-31 16:00:00.000000000 -0800 +++ tmp.full/2 2011-06-23 02:47:01.312500000 -0700 @@ -0,0 +1 @@ +ECHO is on.
        so that we may compile code try the same code as you :)
Re: What does perl stack OPs really do?
by Anonymous Monk on Jun 20, 2011 at 09:52 UTC