[32720] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 3984 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Jul 9 03:09:42 2013

Date: Tue, 9 Jul 2013 00:09:06 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Tue, 9 Jul 2013     Volume: 11 Number: 3984

Today's topics:
    Re: [XS] .h constants -> Perl subs (like POSIX' "errno_ <ben@morrow.me.uk>
    Re: [XS] DESTROY: free or flush? "related" objects? <oneingray@gmail.com>
    Re: [XS] DESTROY: free or flush? "related" objects? <ben@morrow.me.uk>
        [XS] direct access to the perl stack in XS code <rweikusat@mssgmbh.com>
    Re: [XS] direct access to the perl stack in XS code <ben@morrow.me.uk>
    Re: [XS] direct access to the perl stack in XS code <rweikusat@mssgmbh.com>
    Re: [XS] invalidating the pointers in DESTROY? <oneingray@gmail.com>
        whats better poet or mojo? <visphatesjava@gmail.com>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Sun, 7 Jul 2013 14:13:04 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: [XS] .h constants -> Perl subs (like POSIX' "errno_h")?
Message-Id: <046oaa-514.ln1@anubis.morrow.me.uk>


Quoth "Peter J. Holzer" <hjp-usenet3@hjp.at>:
> On 2013-07-06 22:33, Charles DeRykus <derykus@gmail.com> wrote:
> > On 7/6/2013 12:04 PM, Ben Morrow wrote:
> >>
> >> You can even calculate the contents of the hashref dynamically, if you
> >> like:
> >>
> >>      use constant {
> >>          map (chr(ord("@") + $_), $_), 1..4,
> >>      };
> >>
> >> This expression is evaluated at compile time, so any subs called need to
> >> be available at the point where the 'use' statement is compiled.
> >
> > Hm, appears not:
> >
> >   $ perl -le 'use constant {map( (chr(ord("@") + $_), $_), 1..4 ) }'
> >   syntax error at -e line 1, near "use constant {
> 
> Perl thinks that the { starts a block here, not an anonymous hash. You
> can force it by prepending a +:

Ah yes, *that*. Don't post without testing. Sorry.

Ben



------------------------------

Date: Sun, 07 Jul 2013 20:13:07 +0000
From: Ivan Shmakov <oneingray@gmail.com>
Subject: Re: [XS] DESTROY: free or flush? "related" objects?
Message-Id: <87txk6yvqk.fsf@violet.siamics.net>

>>>>> Ben Morrow <ben@morrow.me.uk> writes:
>>>>> Quoth Ivan Shmakov <oneingray@gmail.com>:

[...]

 >> There's another question, however: what's an easy way to invalidate
 >> the object in an XS DESTROY ()?  In Perl, I've seen it being done as
 >> follows:

 >> sub DESTROY {
 >>   ## .
 >>   return
 >>     unless ($$self);
 >>   ## ... clean the things up...
 >>   ## .
 >>   $$self
 >>     = undef;
 >> }

 > I'm not sure exactly what this is intended to accomplish, since
 > ->DESTROY would not be called at all unless $$self was about to be
 > destroyed.  Possibly it's something to do with the out-of-order
 > destruction that happens during global destruction, but you should
 > probably be able to clearly articulate the reason this code is
 > necessary before including it.

	Indeed, it's actually done in the ->close () and ->free ()
	methods, so to avoid a potential crash should either be called
	more than once.  (Adding some kind of a "die unless" guard to
	all the other XS methods is in the TODO list.)

	As of the current revision, ->DESTROY () is aliased to
	->close () (i. e., *DESTROY = \&close), and the latter is just
	an exception-generating wrapper around the XS ->object_close ():

sub close {
    my ($self) = @_;
    ## .
    return
        unless ($$self);
    my $r
        = $self->object_close ();
    die (XXX::Exception->new ($r, "object_close"))
        unless ($r == 0);
    ## .
    undef;
}

	(Or, it could be unless (! defined ($r) || $r == 0), and the
	guard avoided, given that ->object_close () results in an early
	XSRETURN_EMPTY when passed a reference to an undefined value.)

 >> Now, I try to invalidate the object from within an XS function:

 >> void
 >> obj_free (obj)
 >>     XXX::Object obj;
 >> CODE:
 >>   /* ... clean the things up... */
 >> 
 >>   /* FIXME: accessing ST () directly */

 > You don't need to.  'obj' is a SV* pointing to the right SV, unless
 > you've got a typemap that maps it to something else,

	Indeed, I do:

XXX::Parent     T_PTROBJ
XXX::Child      T_OPAQUEPTROBJ

 > in which case you want to change the 'XXX::Object' to 'SV *'.

	This way, I'd need to duplicate the guards now in typemap also
	in the .xs code itself, which is what I'd like to avoid.

 > You only need to access ST() directly if you're trying to change
 > which SVs are on the stack.

	Somehow, I've got an impression that accessing ST () directly is
	not something entirely avoided in the XS code.  So, unless I
	miss some subtle consequence of doing it this way, I'd rather
	prefer to keep the XS code uncluttered with some extra guards.

 >> sv_setref_pv (ST (0), 0, 0);

 >> However, this appears to be subtly different in that (AIUI) it's the
 >> reference that gets invalidated, and not just the referent SV.

 > Yes.  The equivalent of the Perl above is

 >     SvSetMagicSv(ST(0), &PL_sv_undef);

	Indeed, thanks.

	(It's rather like sv_setsv_mg (), though, as per sv.c.)

 >> (Thus, I cannot, say, XSRETURN_EMPTY early upon seeing such a
 >> condition.)

 > I don't understand what you mean here.

	I've meant the "return unless" guard specifically here.  Which
	now became:

CODE:
  if (! SvOK (SvRV (ST (0)))) {
    /* . */
    XSRETURN_EMPTY;
  }

	(With typemap also checking SvROK () and sv_derived_from ().)

-- 
FSF associate member #7257


------------------------------

Date: Mon, 8 Jul 2013 00:06:18 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: [XS] DESTROY: free or flush? "related" objects?
Message-Id: <as8paa-bl6.ln1@anubis.morrow.me.uk>


Quoth Ivan Shmakov <oneingray@gmail.com>:
> >>>>> Ben Morrow <ben@morrow.me.uk> writes:
> >>>>> Quoth Ivan Shmakov <oneingray@gmail.com>:
> 
>  >> There's another question, however: what's an easy way to invalidate
>  >> the object in an XS DESTROY ()?  In Perl, I've seen it being done as
>  >> follows:
> 
>  >> sub DESTROY {
>  >>   ## .
>  >>   return
>  >>     unless ($$self);
>  >>   ## ... clean the things up...
>  >>   ## .
>  >>   $$self
>  >>     = undef;
>  >> }
> 
>  > I'm not sure exactly what this is intended to accomplish, since
>  > ->DESTROY would not be called at all unless $$self was about to be
>  > destroyed.  Possibly it's something to do with the out-of-order
>  > destruction that happens during global destruction, but you should
>  > probably be able to clearly articulate the reason this code is
>  > necessary before including it.
> 
> 	Indeed, it's actually done in the ->close () and ->free ()
> 	methods, so to avoid a potential crash should either be called
> 	more than once.  (Adding some kind of a "die unless" guard to
> 	all the other XS methods is in the TODO list.)

I see. That makes sense.

> 	As of the current revision, ->DESTROY () is aliased to
> 	->close () (i. e., *DESTROY = \&close), and the latter is just
> 	an exception-generating wrapper around the XS ->object_close ():
> 
> sub close {
>     my ($self) = @_;
>     ## .
>     return
>         unless ($$self);
>     my $r
>         = $self->object_close ();
>     die (XXX::Exception->new ($r, "object_close"))
>         unless ($r == 0);
>     ## .
>     undef;
> }

It would be possible to do this from XS, of course, but perhaps not
worth it.

> 	(Or, it could be unless (! defined ($r) || $r == 0), and the
> 	guard avoided, given that ->object_close () results in an early
> 	XSRETURN_EMPTY when passed a reference to an undefined value.)

That's almost the same as 'if $r'.

>  >> Now, I try to invalidate the object from within an XS function:
> 
>  >> void
>  >> obj_free (obj)
>  >>     XXX::Object obj;
>  >> CODE:
>  >>   /* ... clean the things up... */
>  >> 
>  >>   /* FIXME: accessing ST () directly */
> 
>  > You don't need to.  'obj' is a SV* pointing to the right SV, unless
>  > you've got a typemap that maps it to something else,
> 
> 	Indeed, I do:
> 
> XXX::Parent     T_PTROBJ
> XXX::Child      T_OPAQUEPTROBJ
> 
>  > in which case you want to change the 'XXX::Object' to 'SV *'.
> 
> 	This way, I'd need to duplicate the guards now in typemap also
> 	in the .xs code itself, which is what I'd like to avoid.

OK.

>  > You only need to access ST() directly if you're trying to change
>  > which SVs are on the stack.
> 
> 	Somehow, I've got an impression that accessing ST () directly is
> 	not something entirely avoided in the XS code.  So, unless I
> 	miss some subtle consequence of doing it this way, I'd rather
> 	prefer to keep the XS code uncluttered with some extra guards.

That's true. The code generated by xsubpp, in particular, plays quite
free with the stack. You might want to use dTOPss (pp.h) instead, or you
might rather avoid descending into the twisty maze of perl macros.

Ben



------------------------------

Date: Mon, 08 Jul 2013 10:19:01 +0100
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: [XS] direct access to the perl stack in XS code
Message-Id: <87r4f91kai.fsf@sapphire.mobileactivedefense.com>

I finally grew somewhat tired of the Sys::Syslog code which does too
many weird things it shouldn't be doing (such as interfacing with the
Windows event log :->) in Perl code, including downright stupid things
such as using run-time translated strings for the priority constants
and things which change the 'global' execution environment (bad thing
for a routine supposed to generate diagnostic output). I've had a look
at Unix::Syslog but don't quite like that, either, because of 'weird
things' in the XS code ('hand-written' constant access functions,
mapping constants to names with for loops) and things written in Perl
which could equally well be implemented in C (message formatting).

Since this should really be an exercise in non-coding aka "just call
the C library routines and assume anything else is someone else's
business" and I had an otherwise spare Sunday evening in front of me,
I thought I could just run h2xs on the syslog.h file and see where
that would get me. Things never turning out to be quite as beautiful
as they should, some code does need to be written for that, in
particular, there's no (sane) way to invoke a C 'variadic
format-string function' with an a priori unknown set of arguments
which came from perl.

Perlapi(1) documents a function named
sv_vsetpvfn which seemed suitable for the formatting part which can
either work with a va_list or an array of SVs. At first, I thought of
copying the arguments on the stack into an array but then, it occurred
to me that the perl stack really ought to be such an array, already
laying in front of my feet and ready to be used. The code I'm
presently using for syslog which seems to be working fine is

void
syslog(__pri, __fmt, ...)
	int	__pri
	char *	__fmt
INIT:
	char *msg;
	SV *msg_sv;
	bool dummy;
CODE:
	if (items > 2) {
		msg_sv = sv_newmortal();
		sv_vsetpvfn(msg_sv, __fmt, sv_len(ST(1)), NULL,
			    PL_stack_base + ax + 2, items - 2,
			    &dummy);
		msg = SvPV_nolen(msg_sv);
	} else {
		msg = __fmt;
	}
	syslog(__pri, "%s", msg);

Is there, excluding aesthetic/ philosophic aspects, a reason why I shouldn't be
doing this?


------------------------------

Date: Mon, 8 Jul 2013 12:56:52 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: [XS] direct access to the perl stack in XS code
Message-Id: <41mqaa-mqh.ln1@anubis.morrow.me.uk>


Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:
> I finally grew somewhat tired of the Sys::Syslog code which does too
> many weird things it shouldn't be doing (such as interfacing with the
[...]
> 
> Since this should really be an exercise in non-coding aka "just call
> the C library routines and assume anything else is someone else's
> business" and I had an otherwise spare Sunday evening in front of me,
> I thought I could just run h2xs on the syslog.h file and see where
> that would get me. Things never turning out to be quite as beautiful
> as they should, some code does need to be written for that, in
> particular, there's no (sane) way to invoke a C 'variadic
> format-string function' with an a priori unknown set of arguments
> which came from perl.

No. This is because there's no (standard) way to invoke a variadic C
function with a dynamic argument list.

> Perlapi(1) documents a function named
> sv_vsetpvfn which seemed suitable for the formatting part which can
> either work with a va_list or an array of SVs.

The only problem with using this is that is will not handle %m. You will
need to run through the format list, replace %m with %s, and insert
strerror into the argument list.

> At first, I thought of
> copying the arguments on the stack into an array but then, it occurred
> to me that the perl stack really ought to be such an array, already
> laying in front of my feet and ready to be used. The code I'm
> presently using for syslog which seems to be working fine is
> 
> void
> syslog(__pri, __fmt, ...)
> 	int	__pri
> 	char *	__fmt
> INIT:
> 	char *msg;
> 	SV *msg_sv;
> 	bool dummy;
> CODE:
> 	if (items > 2) {
> 		msg_sv = sv_newmortal();
> 		sv_vsetpvfn(msg_sv, __fmt, sv_len(ST(1)), NULL,

Calling sv_len here separately from the SvPV done by the typemap means
the format argument will be stringified twice. If it is tied or
overloaded this can have unfortunate consquences, starting with not
getting the same result both times, and ending with segfaults because
the temporary returned by FETCH is only valid until the next FETCH.

Instead you should take a SV* argument, and use SvPV to retrieve string
value and length in one go. (I don't think you can reasonably use the
length(s) XS feature here.)

> 			    PL_stack_base + ax + 2, items - 2,

I would probably write this &ST(2), but as you like.

> 			    &dummy);
> 		msg = SvPV_nolen(msg_sv);
> 	} else {
> 		msg = __fmt;
> 	}
> 	syslog(__pri, "%s", msg);
> 
> Is there, excluding aesthetic/ philosophic aspects, a reason why I
> shouldn't be doing this?

No, though if you want to handle %m you will need to copy the arguments
off the stack anyway.

Ben



------------------------------

Date: Mon, 08 Jul 2013 15:28:59 +0100
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: [XS] direct access to the perl stack in XS code
Message-Id: <87y59hunv8.fsf@sapphire.mobileactivedefense.com>

Ben Morrow <ben@morrow.me.uk> writes:
> Quoth Rainer Weikusat <rweikusat@mssgmbh.com>:

[syslog(3)]

>> there's no (sane) way to invoke a C 'variadic format-string
>> function' with an a priori unknown set of arguments
>> which came from perl.
>
> No. This is because there's no (standard) way to invoke a variadic C
> function with a dynamic argument list.

Even if there was, the code would need to interpret the format string
in order to determine the types of the arguments which need to be
passed to the C library routine and convert the 'Perl values' as
required. Which would then interpret the format string again. That's
not particularly sane.

>> Perlapi(1) documents a function named sv_vsetpvfn which seemed
>> suitable for the formatting part which can either work with a
>> va_list or an array of SVs.
>
> The only problem with using this is that is will not handle %m. You will
> need to run through the format list, replace %m with %s, and insert
> strerror into the argument list.

If I cared that much about %m, I would change the formatting function
to deal with it :-)[*]. Otherwise, there's again the need to scan the
format string twice and then either copy it a couple of times (what
the existing syslog modules do) or do an arbitrary number of 'in the
middle of an array' inserts. Omitting some features which can't be
supported easily is better than providing them with the help of a
quick and bad implementation punishing everyone.

[*] I'm not yet using a forked perl and don't plan to start doing so
unless I encounter a much more serious obstacle.

[...]

>> void
>> syslog(__pri, __fmt, ...)
>> 	int	__pri
>> 	char *	__fmt
>> INIT:
>> 	char *msg;
>> 	SV *msg_sv;
>> 	bool dummy;
>> CODE:
>> 	if (items > 2) {
>> 		msg_sv = sv_newmortal();
>> 		sv_vsetpvfn(msg_sv, __fmt, sv_len(ST(1)), NULL,
>
> Calling sv_len here separately from the SvPV done by the typemap means
> the format argument will be stringified twice.

Thanks.

[...]

> Instead you should take a SV* argument, and use SvPV to retrieve string
> value and length in one go. (I don't think you can reasonably use the
> length(s) XS feature here.)
>
>> 			    PL_stack_base + ax + 2, items - 2,
>
> I would probably write this &ST(2), but as you like.

Some people like to pretend that 'C arrays' were something they're not
really hard. That leads to expressions like &a[n] or even (as in this
case) &a[n + m]. That's by definition the same as &*(a + n + m), that
is a + n + m plus some kind of "jump to the left, then, jump quickly to
the right and pretend you didn't move at all" prefix ...



------------------------------

Date: Sun, 07 Jul 2013 20:25:19 +0000
From: Ivan Shmakov <oneingray@gmail.com>
Subject: Re: [XS] invalidating the pointers in DESTROY?
Message-Id: <87ppuuyv68.fsf@violet.siamics.net>

>>>>> Ben Morrow <ben@morrow.me.uk> writes:
>>>>> Quoth Ivan Shmakov <oneingray@gmail.com>:
>>>>> Ivan Shmakov <oneingray@gmail.com> writes:

[...]

 >>>   return
 >>>     unless ($$self);

 >> CODE:
 >>   /* NB: accessing ST () directly here and below */
 >>   if (! SvOK (SvRV (ST (0)))) {

 > SvOK is defined ().  Boolean true is SvTRUE, though it makes very
 > little difference here.

	Indeed, the code should never be passed a reference to a defined
	boolean false value.

	... Unless the user does that explicitly, that is.  Certainly,
	I'd prefer to use an object more "opaque" from the Perl side...

[...]

 >>>   $$self
 >>>     = undef;

 >>   /* invalidate the pointer */
 >>   sv_setsv_mg (SvRV (ST (0)), &PL_sv_undef);

 > This is the same.

	ACK, thanks.

-- 
FSF associate member #7257


------------------------------

Date: Sat, 6 Jul 2013 20:23:17 -0700 (PDT)
From: johannes falcone <visphatesjava@gmail.com>
Subject: whats better poet or mojo?
Message-Id: <055eb025-a245-4104-9dae-f1ba6ab0fd63@googlegroups.com>

lol


------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests. 

#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V11 Issue 3984
***************************************


home help back first fref pref prev next nref lref last post