How does one find what PL_stack_sp is?

K

kj

I'm *astonished* anyone other than the authors can understand the
Perl source. How can *anyone* navigate this maze? It's insane.
(And how can the Perl community defend itself against the common
charge of Perl's unreadability, when all a critic needs to do is
point to the Perl source itself for an unparalleled example of
illegibility? Granted, the Perl source is not written in Perl,
but it is obviously written by people who don't give a fig about
the readability of the code. All the piousness in the umpteen Perl
style guides begins to ring hollow after one takes a look at the
Perl source.)

I've spent a couple of hours (and 100% of my patience) trying to
find what PL_stack_sp is. This is just *one* identifier out of
thousands in the Perl source. At this rate it will take me many
months of solid work to have a sense of where things are *defined*,
let alone figuring out what they do or how they're used.

And yes, I grepped "stack_sp" in perlxstut, perlxs, perlapi, and
perlguts, and pored over Extending and Embedding Perl by Jenness
and Cozens.

The best I was able to find (and purely by random accident, BTW)
is that it is a macro defined in perlapi.h as

(*Perl_Tstack_sp_ptr(aTHX))

Great. More wild goose chases ahead. I have not been able to find
where aTHX is defined. I looked in perlapi.h, and in all the files
#include'd in it, and all the files included by those, etc. Plus
a huge list of other files (configuration files, make files, etc.),
too long to fully enumerate. aTHX is not even mentioned in any of
these.

Doing a recursive grep for Perl_Tstack_sp_ptr in the Perl source
turns up *nothing*, other than the occurrences of this identifier
in the RHS of some definitions (such as PL_stack_sp) in perlapi.h.

So, after hours of searching all I know is that PL_stack_sp is
defined in terms of things I cannot find definitions for.

OK, so what's the trick? How does one navigate this insanity?

Thanks!

kj
 
T

Tassilo v. Parseval

Also sprach kj:
I'm *astonished* anyone other than the authors can understand the
Perl source. How can *anyone* navigate this maze? It's insane.
(And how can the Perl community defend itself against the common
charge of Perl's unreadability, when all a critic needs to do is
point to the Perl source itself for an unparalleled example of
illegibility? Granted, the Perl source is not written in Perl,
but it is obviously written by people who don't give a fig about
the readability of the code. All the piousness in the umpteen Perl
style guides begins to ring hollow after one takes a look at the
Perl source.)

What you forgot to mention is that perl is also one of the most portable
pieces of software ever written. This doesn't come for free. The maze of
preprocessor directives is the price you have to pay for it. It's beyond
words how much I hated that at the beginning as I couldn't find
anything. However, as time progressed...
I've spent a couple of hours (and 100% of my patience) trying to
find what PL_stack_sp is. This is just *one* identifier out of
thousands in the Perl source. At this rate it will take me many
months of solid work to have a sense of where things are *defined*,
let alone figuring out what they do or how they're used.

And yes, I grepped "stack_sp" in perlxstut, perlxs, perlapi, and
perlguts, and pored over Extending and Embedding Perl by Jenness
and Cozens.

You wont find it there because it's not part of the public API.
PL_* are variables global to the perl interpreter. They are usually
wrapped in some other macros in case they are useful to extension
writers. In case of PL_stack_sp the macros in question are 'SP' and
'ST(x)' to access a single scalar in this stack. And those are
mentioned in perlapi.pod.
The best I was able to find (and purely by random accident, BTW)
is that it is a macro defined in perlapi.h as

(*Perl_Tstack_sp_ptr(aTHX))

That's how all global variables look before the preprocessor is done
with them. In thrdvar.h you find:

PERLVAR(Tstack_sp, SV **)

which is furhter mangled until it becomes

EXTERN_C SV*** Perl_Tstack_ptr(pTHX);
Great. More wild goose chases ahead. I have not been able to find
where aTHX is defined. I looked in perlapi.h, and in all the files
#include'd in it, and all the files included by those, etc. Plus
a huge list of other files (configuration files, make files, etc.),
too long to fully enumerate. aTHX is not even mentioned in any of
these.

(p|a)THX_? are important macros to ensure that XS modules work both on
threaded and unthreaded perls. pTHX is used in function declarations:

int function (pTHX_ int a, int b);

/* for parameterless functions use version without underscore */

int function (pTHX);

If your perl is threaded then these are expanded to

register PerlInterpreter *my_perl

Functions thus declared are supposed to be called with the corresponding
aTHX macros:

function(aTHX_ 1, 2);

In a threaded environment aTHX is replaced with the variable pointing to
the Perl interpreter of the currently executing thread. Thus it is
ensured that the interpreter can be accessed by macros and functions of
the Perl API.
Doing a recursive grep for Perl_Tstack_sp_ptr in the Perl source
turns up *nothing*, other than the occurrences of this identifier
in the RHS of some definitions (such as PL_stack_sp) in perlapi.h.

Have a closer look at what PERLVAR does. Note that it is overridden in
some headers so you have to be sure to look at the right one. In your
case:

#define PERLVAR(v,t) EXTERN_C t* Perl_##v##_ptr(pTHX);
So, after hours of searching all I know is that PL_stack_sp is
defined in terms of things I cannot find definitions for.

OK, so what's the trick? How does one navigate this insanity?

By practice and intuition. ;-)

There is a certain, albeit not always consistent, system of naming
conventions and preprocessor chains involved. PL_ are global variables
and they are usually mapped to something that is defined in thrdvar.h or
intrpvar.h using one of the various PERLVAR... macros. These two header
files are actually just the body of a C-structure declaration which you
can see in perl.h:

struct interpreter {
# include "thrdvar.h"
# include "intrpvar.h"
/*
* The following is a buffer where new variables must
* be defined to maintain binary compatibility with previous versions
*/
PERLVARA(object_compatibility,30, char)
};

So these two huge header files combined define all the fields of 'struct
interpreter'. When you see something like PL_dirty and are curious
what it is, you do a grep for 'Tdirty' in these two headers, and it
yields:

PERLVARI(Tdirty, bool, FALSE) /* in the middle of tearing things down? */

So it's a boolean with initial value FALSE.

Tassilo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,169
Latest member
ArturoOlne
Top