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