The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

Pad Data Structures */

/* offsets within a pad */

typedef SSize_t PADOFFSET; /* signed so that -1 is a valid value */ #define NOT_IN_PAD ((PADOFFSET) -1)

/* B.xs expects the first members of these two structs to line up (xpadl_max with xpadnl_fill). */

struct padlist { SSize_t xpadl_max; /* max index for which array has space */ union { PAD ** xpadlarr_alloc; /* Pointer to beginning of array of AVs. index 0 is a padnamelist * */ struct { PADNAMELIST * padnl; PAD * pad_1; /* this slice of PAD * array always alloced */ PAD * pad_2; /* maybe unalloced */ } * xpadlarr_dbg; /* for use with a C debugger only */ } xpadl_arr; U32 xpadl_id; /* Semi-unique ID, shared between clones */ U32 xpadl_outid; /* ID of outer pad */ };

struct padnamelist { SSize_t xpadnl_fill; /* max index in use */ PADNAME ** xpadnl_alloc; /* pointer to beginning of array */ SSize_t xpadnl_max; /* max index for which array has space */ PADOFFSET xpadnl_max_named; /* highest index with len > 0 */ U32 xpadnl_refcnt; };

/* PERL_PADNAME_MINIMAL uses less memory, but on some platforms PERL_PADNAME_ALIGNED may be faster, so platform-specific hints can define one or the other. */ #if defined(PERL_PADNAME_MINIMAL) && defined (PERL_PADNAME_ALIGNED) # error PERL_PADNAME_MINIMAL and PERL_PADNAME_ALIGNED are exclusive #endif

#if !defined(PERL_PADNAME_MINIMAL) && !defined(PERL_PADNAME_ALIGNED) # define PERL_PADNAME_MINIMAL #endif

#define _PADNAME_BASE \ char * xpadn_pv; \ HV * xpadn_ourstash; \ union { \ HV * xpadn_typestash; \ CV * xpadn_protocv; \ } xpadn_type_u; \ U32 xpadn_low; \ U32 xpadn_high; \ U32 xpadn_refcnt; \ int xpadn_gen; \ U8 xpadn_len; \ U8 xpadn_flags

struct padname { _PADNAME_BASE; };

struct padname_with_str { #ifdef PERL_PADNAME_MINIMAL _PADNAME_BASE; #else struct padname xpadn_padname; #endif char xpadn_str[1]; };

#undef _PADNAME_BASE

#define PADNAME_FROM_PV(s) \ ((PADNAME *)((s) - STRUCT_OFFSET(struct padname_with_str, xpadn_str)))

/* a value that PL_cop_seqmax is guaranteed never to be, * flagging that a lexical is being introduced, or has not yet left scope */ #define PERL_PADSEQ_INTRO U32_MAX #define COP_SEQMAX_INC \ (PL_cop_seqmax++, \ (void)(PL_cop_seqmax == PERL_PADSEQ_INTRO && PL_cop_seqmax++))

/* B.xs needs these for the benefit of B::Deparse */ /* Low range end is exclusive (valid from the cop seq after this one) */ /* High range end is inclusive (valid up to this cop seq) */

#define COP_SEQ_RANGE_LOW(pn) (pn)->xpadn_low #define COP_SEQ_RANGE_HIGH(pn) (pn)->xpadn_high #define PARENT_PAD_INDEX(pn) (pn)->xpadn_low #define PARENT_FAKELEX_FLAGS(pn) (pn)->xpadn_high

/* Flags set in the SvIVX field of FAKE namesvs */

#define PAD_FAKELEX_ANON 1 /* the lex is declared in an ANON, or ... */ #define PAD_FAKELEX_MULTI 2 /* the lex can be instantiated multiple times */

/* flags for the pad_new() function */

#define padnew_CLONE 1 /* this pad is for a cloned CV */ #define padnew_SAVE 2 /* save old globals */ #define padnew_SAVESUB 4 /* also save extra stuff for start of sub */

/* values for the pad_tidy() function */

typedef enum { padtidy_SUB, /* tidy up a pad for a sub, */ padtidy_SUBCLONE, /* a cloned sub, */ padtidy_FORMAT /* or a format */ } padtidy_type;

/* flags for pad_add_name_pvn. */

#define padadd_OUR 0x01 /* our declaration. */ #define padadd_STATE 0x02 /* state declaration. */ #define padadd_NO_DUP_CHECK 0x04 /* skip warning on dups. */ #define padadd_STALEOK 0x08 /* allow stale lexical in active * sub, but only one level up */

/* ASSERT_CURPAD_LEGAL and ASSERT_CURPAD_ACTIVE respectively determine * whether PL_comppad and PL_curpad are consistent and whether they have * active values */

# define pad_peg(label)

#ifdef DEBUGGING # define ASSERT_CURPAD_LEGAL(label) \ pad_peg(label); \ if (PL_comppad ? (AvARRAY(PL_comppad) != PL_curpad) : (PL_curpad != 0)) \ Perl_croak(aTHX_ "panic: illegal pad in %s: 0x%" UVxf "[0x%" UVxf "]",\ label, PTR2UV(PL_comppad), PTR2UV(PL_curpad));

# define ASSERT_CURPAD_ACTIVE(label) \ pad_peg(label); \ if (!PL_comppad || (AvARRAY(PL_comppad) != PL_curpad)) \ Perl_croak(aTHX_ "panic: invalid pad in %s: 0x%" UVxf "[0x%" UVxf "]",\ label, PTR2UV(PL_comppad), PTR2UV(PL_curpad)); #else # define ASSERT_CURPAD_LEGAL(label) # define ASSERT_CURPAD_ACTIVE(label) #endif

/* Note: the following three macros are actually defined in scope.h, but * they are documented here for completeness, since they directly or * indirectly affect pads.

XXX DAPM it would make more sense to make the arg a PADOFFSET =for apidoc m|void|SAVECLEARSV |SV **svp Clear the pointed to pad value on scope exit. (i.e. the runtime action of my)

    SAVECOMPPAD();
    PAD_SET_CUR_NOSAVE(padlist,n);

Exactly like "pad_add_name_pvn", but takes a literal string instead of a string/length pair.

Exactly like "pad_findmy_pvn", but takes a literal string instead of a string/length pair.