On Fri, Oct 31, 2003 at 09:34:46AM +0000 Steve Hay wrote:

> Tassilo von Parseval wrote:

> >I get a segfault, which is what I would expect. You only allocate memory
> >for the string but not for the SV to be returned.
> >[snip]
> > 
> >
> >One could change it to:
> >
> >   SV *
> >   hello()
> >       PREINIT:
> >           char *chartext;
> >           SV   *svtext;
> >       CODE:
> >           Newz(0, chartext, 13, char);
> >           svtext = newSV(0);
> >           strcpy(chartext, "Hello, world");
> >           sv_usepvn(svtext, chartext, strlen(chartext));
> >           RETVAL = svtext;
> >       OUTPUT:
> >           RETVAL
> > 
> >
> Cool - thanks for the explanation.  I've simplified the above slightly 
> to use RETVAL itself as the SV *:
> 
>    SV *
>    hello()
>        PREINIT:
>            char    *chartext;
> 
>        CODE:
>            Newz(0, chartext, 13, char);
>            strcpy(chartext, "Hello, world");
>            RETVAL = newSV(0);
>            sv_usepvn(RETVAL, chartext, 13);
> 
>        OUTPUT:
>            RETVAL
> 
> This still works fine.

Yes, no problem with that.

> That contrasts interestingly with the void xsub case:
> 
>    void
>    hello()
>        PREINIT:
>            char    *chartext;
> 
>        CODE:
>            Newz(0, chartext, 13, char);
>            strcpy(chartext, "Hello, world");
>            sv_usepvn(ST(0), chartext, 13);
>            XSRETURN(1);
> 
> which works without having to say "ST(0) = newSV(0)".  Does that mean 
> that ST(0) is already an allocated SV *?

It could be, but what you do is dangerous and in fact uncontrollable.
ST(0) contains a totally unrelated SV. Change the abobe code to

    ...
    sv_dump(ST(0));
    sv_usepvn(ST(0), chartext, 13);
    ...

and you will see for (hello()) for instance

SV = PVGV(0x81494b0) at 0x818b650
  REFCNT = 2
  FLAGS = (GMG,SMG,MULTI)
  IV = 0
  NV = 0
  MAGIC = 0x819a240
    MG_VIRTUAL = &PL_vtbl_glob
    MG_TYPE = PERL_MAGIC_glob(*)
    MG_OBJ = 0x818b650
  NAME = "hello"
  NAMELEN = 5
  [ etc. ]

and compare it to the output you get when you say 'hello(1)' (change :
the prototype to 'SV*\nhello(...)' to allow passing parameters in):

SV = IV(0x81a2298) at 0x8128bd4
  REFCNT = 1
  FLAGS = (IOK,READONLY,pIOK)
  IV = 1
Modification of a read-only value attempted at -e line 1.

Spot the system behind it? ST(0) refers to the first value of the
stack...that could be a value that you passed to the subroutine or in
fact anything else you don't have control over.

> If so, is that always the case?  In a previous thread discussing 
> returning lists from xsubs 
> (http://www.perldiscuss.com/article.php?id=1112&group=perl.xs) it was 
> pointed out that when using EXTEND / PUSHs you get one free push if the 
> xsub was called from Perl, but don't if it was called from another 
> xsub.  What I'm wondering is would ST(0) still be a preallocated SV * if 
> the xsub was called from another xsub?
> 
> (I would try it out to see, but I don't know how to call an xsub from 
> another xsub!  How does one do that?)

An xsub should just be an ordinary Perl subroutine so you call it like
any other subroutine, see perlcall.pod. A good template is:

    /* call Perl function */
    dSP;
    ENTER;
    SAVETMPS;
    PUSHMARK(SP);
    
    /* push the arguments for the function onto the stack */
    XPUSHs(sv_2mortal(byte));
    PUTBACK;

    /* call it in void context */
    (void)call_pv("Package::some_function", G_VOID);
    FREETMPS;

When the called function should return values, use G_SCALAR or G_ARRAY
for the context. You find the returned values on the stack after that,
so you can pop them off. The call_?? return the number of elements that
the called function returned.
    
Tassilo
-- 
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

Reply via email to