in reply to Re: What does perl stack OPs really do?
in thread What does perl stack OPs really do?

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?

Replies are listed 'Best First'.
Re^3: What does perl stack OPs really do?
by Anonymous Monk on Jun 23, 2011 at 09:48 UTC
    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 :)
      As I made up a wrapper, the real code is pretty long.
      This is the perl code:
      { my $static_var = 0; sub return_op { say "in return_op: $static_var"; return $static_var; } }
      This is the main function:
      int main(.......) { ...... // return value test { cout<<"### return value test"<<endl; pppStack re1 = interp->call("return_op",true,false); pppStack re2 = interp->call("return_op",true,false); } ,,,,,, }
      And this is the code in Interp class that do the calling:
      class pppInterp { public: ......// a lot of methods here pppStack call(string subname, bool want_re, bool want_array); pppStack call(string subname, pppStack& args, bool want_re, bool w +ant_array); protected: // the interpreter only has this one property static bool inited; PerlInterpreter* my_perl; } // // the method implementation // pppStack pppInterp::call(string subname, bool want_re, bool want_array +) { pppStack empty; return call(subname,empty,want_re,want_array); } pppStack pppInterp::call(string subname, pppStack& args, bool want_re, + bool want_array) { // enter sub SPAGAIN; ENTER; SAVETMPS; // push args PUSHMARK(SP); pppStack::iterator it; int arg_count = 0; for (it=args.begin(); it!=args.end(); it++) { SV* arg_copy = newSVsv((*it)->get_internal()); sv_2mortal(arg_copy); XPUSHs(arg_copy); arg_count++; } PUTBACK; // call sub I32 flags = G_EVAL; if (arg_count==0) flags |= G_NOARGS; if (!want_re) flags |= G_DISCARD; if (want_array) flags |= G_ARRAY; else flags |= G_SCALAR; int re_count = call_pv(subname.c_str(),flags); // check eval if (SvTRUE(ERRSV)) { if (want_array) POPs; throw(SvPV_nolen(ERRSV)); } // fetch args pppStack re; if (want_re) { SPAGAIN; int i; for (i=0; i<re_count; i++) { SV* tmp = POPs; Perl_sv_dump(my_perl,tmp); re.push_front( create_sv(tmp) ); } } PUTBACK; // exit sub FREETMPS; LEAVE; return re; }
      at last, it gives the return value like this. You can see, each time of calling gives me a different SV. It is printed immediately after POPs.
      ### return value test in return_op: 0 SV = PVIV(0xffd228) at 0xfebda0 REFCNT = 1 FLAGS = (TEMP,IOK,POK,pIOK,pPOK) IV = 0 PV = 0x1013fd0 "0"\0 CUR = 1 LEN = 8 in return_op: 0 SV = PVIV(0xffd240) at 0xfebf80 REFCNT = 1 FLAGS = (TEMP,IOK,POK,pIOK,pPOK) IV = 0 PV = 0x10102b0 "0"\0 CUR = 1 LEN = 8
      I founded the key here:
      If I increase the ref count of returned scalar, each time it will give me a different one:
      void call_it() { ...... SV* re = POPs; Perl_sv_dump(my_perl,re); SvREFCNT_inc(re); ...... } int main(......) { ...... // calling the first time printf("first time\n"); call_it(); // call again printf("again\n"); call_it(); // call again printf("and again\n"); call_it(); ...... }
      $ gcc -g -o test -I /usr/lib64/perl5/CORE -L /usr/lib64/perl5/CORE -lp +erl mini.c $ ./test going to return it: aaa SV = PV(0xc43c78) at 0xc45d80 REFCNT = 1 FLAGS = (TEMP,POK,pPOK) PV = 0xc5bde0 "aaa"\0 CUR = 3 LEN = 8 again going to return it: aaa SV = PV(0xc43df8) at 0xc45f60 REFCNT = 1 FLAGS = (TEMP,POK,pPOK) PV = 0xc5c730 "aaa"\0 CUR = 3 LEN = 8 and again going to return it: aaa SV = PV(0xc43dc8) at 0xc612f8 REFCNT = 1 FLAGS = (TEMP,POK,pPOK) PV = 0xc6a290 "aaa"\0 CUR = 3 LEN = 8
      Otherwise, it will give me the same one:
      void call_it() { ...... SV* re = POPs; Perl_sv_dump(my_perl,re); ...... }
      $ gcc -g -o test -I /usr/lib64/perl5/CORE -L /usr/lib64/perl5/CORE -lp +erl mini.c $ ./test first time going to return it: aaa SV = PV(0x2001c78) at 0x2003d80 REFCNT = 1 FLAGS = (TEMP,POK,pPOK) PV = 0x2019de0 "aaa"\0 CUR = 3 LEN = 8 again going to return it: aaa SV = PV(0x2001c78) at 0x2003d80 REFCNT = 1 FLAGS = (TEMP,POK,pPOK) PV = 0x2019de0 "aaa"\0 CUR = 3 LEN = 8 and again going to return it: aaa SV = PV(0x2001c78) at 0x2003d80 REFCNT = 1 FLAGS = (TEMP,POK,pPOK) PV = 0x2019de0 "aaa"\0 CUR = 3 LEN = 8
      Why??!!