On Wed, May 26, 2004 at 10:44:22PM -0400, muppet wrote:
> 
> (by the way, i'm subbed to the list, there's no need to reply-to-all.)

(sorry, I'm used to that on a few slow lists I'm on -- and I'd drop
duplicate message IDs so I never see the dups.
I'll set perl-xs as a list in my .muttrc for list reply.)

> forgive me if i've missed something basic, but why do this in an xsub?  
> wouldn't
> 
>    sub return_list { return secondary_sub (@_) }

In the "real" code I have four different xsubs that call "secondary_sub"
-- secondary_sub is just common code to all four functions.  They are
are different method calls that all share some common code.


And about using ST(0):

> >void
> >return_list( var_a, var_b )
> >    char *var_a
> >    char *var_b
> >    PPCODE:
> >        PUSHMARK(SP);
> >        XPUSH( (SV *)var_a );
> >        XPUSH( (SV *)var_b );
> 
> erm, i think you'd rather be using ST(0) and ST(1) there, unless var_a 
> and var_b are actually just defined as SV* instead of char*.

Ah, the problem with trying to make simple examples instead of showing
the actual code.

If you look at my original code I use an O_OBJECT typemap so I'm actually
getting my C struct passed to me as "swish_handle" by the magic of the 
typemap -- "swish_handle" is not ST(0).

And then I'm just casting to an SV * as a way to pass my pointer on the
stack to my other xsub function.

void
SwishMetaList( swish_handle, index_name )
    SW_HANDLE swish_handle
    char *index_name

    PREINIT:
        SWISH_META_LIST meta_list;

    PPCODE:
        /* Grab the list of pointers */
        meta_list = SwishMetaList( swish_handle, index_name );

        PUSHMARK(SP) ;      /* always need to PUSHMARK, even w/o params */
        XPUSHs( (SV *)swish_handle );
        XPUSHs( (SV *)meta_list );
        XPUSHs( (SV *)"SWISH::API::MetaName");
        PUTBACK ;           /* lets perl know how many parameters are here */

        call_pv("SWISH::API::push_meta_list", G_ARRAY );
        SPAGAIN;

If you look at the xsub-generated C code you can see that it's not ST(0)
any more:

        if( sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG) )
                swish_handle = (SW_HANDLE)SvIV((SV*)SvRV( ST(0) ));

So I can't XPUSHs ST(0).


> >So "secondary_function" pushes any number of thingies onto the stack 
> >and returns them to perl space.  Like I said, the stack is a mystery 
> >to me, so I'm not clear how perl knows how many Foo::Bla objects are 
> >on the stack and how many to place in @list.
> 
> that's what marks and the stack pointer are for.

The PUSHMARK(SP) ... PUTBACK tell the secondary sub (push_meta_list
above) how many items (3 in this example) are passed on the stack.
That's how I understand it.

The question was how does the code that calls SwishMetaList() know how
many items were pushed onto the stack by push_meta_list()?

So, from your example code:

>       // we don't alter the stack, so it still has n on it.
>       // don't try this at home; i got this math from macros in XSUB.h:
>       warn ("stack size: %d\n", PL_stack_sp - PL_stack_base);
[...]
> this prints:
> 
>   tetsuo:~/Foo$ make && perl -I blib/lib -I blib/arch testfoo.pl
>   stack size: 4

So I guess the secondary sub call just extends the stack and the number
of parameters is just the size of the stack.

Perhaps the thing I'm missing is that both functions are working with
the same stack -- unlike other languages where the secondary function
would have it's own stack.  It's likely this bit of pod in perlcall is
what started me wondering:

       2.   The purpose of the macro "SPAGAIN" is to refresh the local copy of
            the stack pointer. This is necessary because it is possible that
            the memory allocated to the Perl stack has been reallocated whilst
            in the call_pv call.

Which made me think that the secondary function (called by call_pv) was
working with a different stack.  But, that's not what that says.  It's
just saying that the stack might have been realloc()'d so SPAGAIN makes
sure we are not pointing to the wrong memory location of the stack.

> so, the moral of the story:  your code works correctly.  the stuff gets 
> destroyed at the right time.  the perl stack is not magical, it's just 
> a C array of SVs, managed by a number of pointers and macros.

Good.  Thanks much for looking at this.  Now I can cvs commit and sleep
without worrying!

Thanks,

-- 
Bill Moseley
[EMAIL PROTECTED]

Reply via email to