[14489] | 1 | /* pad.h
|
---|
| 2 | *
|
---|
| 3 | * Copyright (C) 2002, 2003, 2005, by Larry Wall and others
|
---|
| 4 | *
|
---|
| 5 | * You may distribute under the terms of either the GNU General Public
|
---|
| 6 | * License or the Artistic License, as specified in the README file.
|
---|
| 7 | *
|
---|
| 8 | * This file defines the types and macros associated with the API for
|
---|
| 9 | * manipulating scratchpads, which are used by perl to store lexical
|
---|
| 10 | * variables, op targets and constants.
|
---|
| 11 | */
|
---|
| 12 |
|
---|
| 13 |
|
---|
| 14 |
|
---|
| 15 |
|
---|
| 16 | /* a padlist is currently just an AV; but that might change,
|
---|
| 17 | * so hide the type. Ditto a pad. */
|
---|
| 18 |
|
---|
| 19 | typedef AV PADLIST;
|
---|
| 20 | typedef AV PAD;
|
---|
| 21 |
|
---|
| 22 |
|
---|
| 23 | /* offsets within a pad */
|
---|
| 24 |
|
---|
| 25 | #if PTRSIZE == 4
|
---|
| 26 | typedef U32TYPE PADOFFSET;
|
---|
| 27 | #else
|
---|
| 28 | # if PTRSIZE == 8
|
---|
| 29 | typedef U64TYPE PADOFFSET;
|
---|
| 30 | # endif
|
---|
| 31 | #endif
|
---|
| 32 | #define NOT_IN_PAD ((PADOFFSET) -1)
|
---|
| 33 |
|
---|
| 34 |
|
---|
| 35 | /* flags for the pad_new() function */
|
---|
| 36 |
|
---|
| 37 | #define padnew_CLONE 1 /* this pad is for a cloned CV */
|
---|
| 38 | #define padnew_SAVE 2 /* save old globals */
|
---|
| 39 | #define padnew_SAVESUB 4 /* also save extra stuff for start of sub */
|
---|
| 40 |
|
---|
| 41 | /* values for the pad_tidy() function */
|
---|
| 42 |
|
---|
| 43 | typedef enum {
|
---|
| 44 | padtidy_SUB, /* tidy up a pad for a sub, */
|
---|
| 45 | padtidy_SUBCLONE, /* a cloned sub, */
|
---|
| 46 | padtidy_FORMAT /* or a format */
|
---|
| 47 | } padtidy_type;
|
---|
| 48 |
|
---|
| 49 | /* ASSERT_CURPAD_LEGAL and ASSERT_CURPAD_ACTIVE respectively determine
|
---|
| 50 | * whether PL_comppad and PL_curpad are consistent and whether they have
|
---|
| 51 | * active values */
|
---|
| 52 |
|
---|
| 53 | #ifdef DEBUGGING
|
---|
| 54 | # define ASSERT_CURPAD_LEGAL(label) \
|
---|
| 55 | if (PL_comppad ? (AvARRAY(PL_comppad) != PL_curpad) : (PL_curpad != 0)) \
|
---|
| 56 | Perl_croak(aTHX_ "panic: illegal pad in %s: 0x%"UVxf"[0x%"UVxf"]",\
|
---|
| 57 | label, PTR2UV(PL_comppad), PTR2UV(PL_curpad));
|
---|
| 58 |
|
---|
| 59 |
|
---|
| 60 | # define ASSERT_CURPAD_ACTIVE(label) \
|
---|
| 61 | if (!PL_comppad || (AvARRAY(PL_comppad) != PL_curpad)) \
|
---|
| 62 | Perl_croak(aTHX_ "panic: invalid pad in %s: 0x%"UVxf"[0x%"UVxf"]",\
|
---|
| 63 | label, PTR2UV(PL_comppad), PTR2UV(PL_curpad));
|
---|
| 64 | #else
|
---|
| 65 | # define ASSERT_CURPAD_LEGAL(label)
|
---|
| 66 | # define ASSERT_CURPAD_ACTIVE(label)
|
---|
| 67 | #endif
|
---|
| 68 |
|
---|
| 69 |
|
---|
| 70 |
|
---|
| 71 | /* Note: the following three macros are actually defined in scope.h, but
|
---|
| 72 | * they are documented here for completeness, since they directly or
|
---|
| 73 | * indirectly affect pads.
|
---|
| 74 |
|
---|
| 75 | =for apidoc m|void|SAVEPADSV |PADOFFSET po
|
---|
| 76 | Save a pad slot (used to restore after an iteration)
|
---|
| 77 |
|
---|
| 78 | XXX DAPM it would make more sense to make the arg a PADOFFSET
|
---|
| 79 | =for apidoc m|void|SAVECLEARSV |SV **svp
|
---|
| 80 | Clear the pointed to pad value on scope exit. (i.e. the runtime action of 'my')
|
---|
| 81 |
|
---|
| 82 | =for apidoc m|void|SAVECOMPPAD
|
---|
| 83 | save PL_comppad and PL_curpad
|
---|
| 84 |
|
---|
| 85 |
|
---|
| 86 |
|
---|
| 87 |
|
---|
| 88 |
|
---|
| 89 | =for apidoc m|SV *|PAD_SETSV |PADOFFSET po|SV* sv
|
---|
| 90 | Set the slot at offset C<po> in the current pad to C<sv>
|
---|
| 91 |
|
---|
| 92 | =for apidoc m|void|PAD_SV |PADOFFSET po
|
---|
| 93 | Get the value at offset C<po> in the current pad
|
---|
| 94 |
|
---|
| 95 | =for apidoc m|SV *|PAD_SVl |PADOFFSET po
|
---|
| 96 | Lightweight and lvalue version of C<PAD_SV>.
|
---|
| 97 | Get or set the value at offset C<po> in the current pad.
|
---|
| 98 | Unlike C<PAD_SV>, does not print diagnostics with -DX.
|
---|
| 99 | For internal use only.
|
---|
| 100 |
|
---|
| 101 | =for apidoc m|SV *|PAD_BASE_SV |PADLIST padlist|PADOFFSET po
|
---|
| 102 | Get the value from slot C<po> in the base (DEPTH=1) pad of a padlist
|
---|
| 103 |
|
---|
| 104 | =for apidoc m|void|PAD_SET_CUR |PADLIST padlist|I32 n
|
---|
| 105 | Set the current pad to be pad C<n> in the padlist, saving
|
---|
| 106 | the previous current pad. NB currently this macro expands to a string too
|
---|
| 107 | long for some compilers, so it's best to replace it with
|
---|
| 108 |
|
---|
| 109 | SAVECOMPPAD();
|
---|
| 110 | PAD_SET_CUR_NOSAVE(padlist,n);
|
---|
| 111 |
|
---|
| 112 |
|
---|
| 113 | =for apidoc m|void|PAD_SET_CUR_NOSAVE |PADLIST padlist|I32 n
|
---|
| 114 | like PAD_SET_CUR, but without the save
|
---|
| 115 |
|
---|
| 116 | =for apidoc m|void|PAD_SAVE_SETNULLPAD
|
---|
| 117 | Save the current pad then set it to null.
|
---|
| 118 |
|
---|
| 119 | =for apidoc m|void|PAD_SAVE_LOCAL|PAD *opad|PAD *npad
|
---|
| 120 | Save the current pad to the local variable opad, then make the
|
---|
| 121 | current pad equal to npad
|
---|
| 122 |
|
---|
| 123 | =for apidoc m|void|PAD_RESTORE_LOCAL|PAD *opad
|
---|
| 124 | Restore the old pad saved into the local variable opad by PAD_SAVE_LOCAL()
|
---|
| 125 |
|
---|
| 126 | =cut
|
---|
| 127 | */
|
---|
| 128 |
|
---|
| 129 | #ifdef DEBUGGING
|
---|
| 130 | # define PAD_SV(po) pad_sv(po)
|
---|
| 131 | # define PAD_SETSV(po,sv) pad_setsv(po,sv)
|
---|
| 132 | #else
|
---|
| 133 | # define PAD_SV(po) (PL_curpad[po])
|
---|
| 134 | # define PAD_SETSV(po,sv) PL_curpad[po] = (sv)
|
---|
| 135 | #endif
|
---|
| 136 |
|
---|
| 137 | #define PAD_SVl(po) (PL_curpad[po])
|
---|
| 138 |
|
---|
| 139 | #define PAD_BASE_SV(padlist, po) \
|
---|
| 140 | (AvARRAY(padlist)[1]) \
|
---|
| 141 | ? AvARRAY((AV*)(AvARRAY(padlist)[1]))[po] : Nullsv;
|
---|
| 142 |
|
---|
| 143 |
|
---|
| 144 | #define PAD_SET_CUR_NOSAVE(padlist,n) \
|
---|
| 145 | PL_comppad = (PAD*) (AvARRAY(padlist)[n]); \
|
---|
| 146 | PL_curpad = AvARRAY(PL_comppad); \
|
---|
| 147 | DEBUG_Xv(PerlIO_printf(Perl_debug_log, \
|
---|
| 148 | "Pad 0x%"UVxf"[0x%"UVxf"] set_cur depth=%d\n", \
|
---|
| 149 | PTR2UV(PL_comppad), PTR2UV(PL_curpad), (int)(n)));
|
---|
| 150 |
|
---|
| 151 |
|
---|
| 152 | #define PAD_SET_CUR(padlist,n) \
|
---|
| 153 | SAVECOMPPAD(); \
|
---|
| 154 | PAD_SET_CUR_NOSAVE(padlist,n);
|
---|
| 155 |
|
---|
| 156 |
|
---|
| 157 | #define PAD_SAVE_SETNULLPAD() SAVECOMPPAD(); \
|
---|
| 158 | PL_comppad = Null(PAD*); PL_curpad = Null(SV**); \
|
---|
| 159 | DEBUG_Xv(PerlIO_printf(Perl_debug_log, "Pad set_null\n"));
|
---|
| 160 |
|
---|
| 161 | #define PAD_SAVE_LOCAL(opad,npad) \
|
---|
| 162 | opad = PL_comppad; \
|
---|
| 163 | PL_comppad = (npad); \
|
---|
| 164 | PL_curpad = PL_comppad ? AvARRAY(PL_comppad) : Null(SV**); \
|
---|
| 165 | DEBUG_Xv(PerlIO_printf(Perl_debug_log, \
|
---|
| 166 | "Pad 0x%"UVxf"[0x%"UVxf"] save_local\n", \
|
---|
| 167 | PTR2UV(PL_comppad), PTR2UV(PL_curpad)));
|
---|
| 168 |
|
---|
| 169 | #define PAD_RESTORE_LOCAL(opad) \
|
---|
| 170 | PL_comppad = opad; \
|
---|
| 171 | PL_curpad = PL_comppad ? AvARRAY(PL_comppad) : Null(SV**); \
|
---|
| 172 | DEBUG_Xv(PerlIO_printf(Perl_debug_log, \
|
---|
| 173 | "Pad 0x%"UVxf"[0x%"UVxf"] restore_local\n", \
|
---|
| 174 | PTR2UV(PL_comppad), PTR2UV(PL_curpad)));
|
---|
| 175 |
|
---|
| 176 |
|
---|
| 177 | /*
|
---|
| 178 | =for apidoc m|void|CX_CURPAD_SAVE|struct context
|
---|
| 179 | Save the current pad in the given context block structure.
|
---|
| 180 |
|
---|
| 181 | =for apidoc m|SV *|CX_CURPAD_SV|struct context|PADOFFSET po
|
---|
| 182 | Access the SV at offset po in the saved current pad in the given
|
---|
| 183 | context block structure (can be used as an lvalue).
|
---|
| 184 |
|
---|
| 185 | =cut
|
---|
| 186 | */
|
---|
| 187 |
|
---|
| 188 | #define CX_CURPAD_SAVE(block) (block).oldcomppad = PL_comppad
|
---|
| 189 | #define CX_CURPAD_SV(block,po) (AvARRAY((AV*)((block).oldcomppad))[po])
|
---|
| 190 |
|
---|
| 191 |
|
---|
| 192 | /*
|
---|
| 193 | =for apidoc m|U32|PAD_COMPNAME_FLAGS|PADOFFSET po
|
---|
| 194 | Return the flags for the current compiling pad name
|
---|
| 195 | at offset C<po>. Assumes a valid slot entry.
|
---|
| 196 |
|
---|
| 197 | =for apidoc m|char *|PAD_COMPNAME_PV|PADOFFSET po
|
---|
| 198 | Return the name of the current compiling pad name
|
---|
| 199 | at offset C<po>. Assumes a valid slot entry.
|
---|
| 200 |
|
---|
| 201 | =for apidoc m|HV *|PAD_COMPNAME_TYPE|PADOFFSET po
|
---|
| 202 | Return the type (stash) of the current compiling pad name at offset
|
---|
| 203 | C<po>. Must be a valid name. Returns null if not typed.
|
---|
| 204 |
|
---|
| 205 | =for apidoc m|HV *|PAD_COMPNAME_OURSTASH|PADOFFSET po
|
---|
| 206 | Return the stash associated with an C<our> variable.
|
---|
| 207 | Assumes the slot entry is a valid C<our> lexical.
|
---|
| 208 |
|
---|
| 209 | =for apidoc m|STRLEN|PAD_COMPNAME_GEN|PADOFFSET po
|
---|
| 210 | The generation number of the name at offset C<po> in the current
|
---|
| 211 | compiling pad (lvalue). Note that C<SvCUR> is hijacked for this purpose.
|
---|
| 212 |
|
---|
| 213 | =for apidoc m|STRLEN|PAD_COMPNAME_GEN_set|PADOFFSET po|int gen
|
---|
| 214 | Sets the generation number of the name at offset C<po> in the current
|
---|
| 215 | ling pad (lvalue) to C<gen>. Note that C<SvCUR_set> is hijacked for this purpose.
|
---|
| 216 |
|
---|
| 217 | =cut
|
---|
| 218 |
|
---|
| 219 | */
|
---|
| 220 |
|
---|
| 221 | #define PAD_COMPNAME_FLAGS(po) SvFLAGS(*av_fetch(PL_comppad_name, (po), FALSE))
|
---|
| 222 | #define PAD_COMPNAME_PV(po) SvPV_nolen(*av_fetch(PL_comppad_name, (po), FALSE))
|
---|
| 223 |
|
---|
| 224 | #define PAD_COMPNAME_TYPE(po) pad_compname_type(po)
|
---|
| 225 |
|
---|
| 226 | #define PAD_COMPNAME_OURSTASH(po) \
|
---|
| 227 | (GvSTASH(*av_fetch(PL_comppad_name, (po), FALSE)))
|
---|
| 228 |
|
---|
| 229 | #define PAD_COMPNAME_GEN(po) SvCUR(AvARRAY(PL_comppad_name)[po])
|
---|
| 230 |
|
---|
| 231 | #define PAD_COMPNAME_GEN_set(po, gen) SvCUR_set(AvARRAY(PL_comppad_name)[po], gen)
|
---|
| 232 |
|
---|
| 233 |
|
---|
| 234 | /*
|
---|
| 235 | =for apidoc m|void|PAD_DUP|PADLIST dstpad|PADLIST srcpad|CLONE_PARAMS* param
|
---|
| 236 | Clone a padlist.
|
---|
| 237 |
|
---|
| 238 | =for apidoc m|void|PAD_CLONE_VARS|PerlInterpreter *proto_perl \
|
---|
| 239 | |CLONE_PARAMS* param
|
---|
| 240 | Clone the state variables associated with running and compiling pads.
|
---|
| 241 |
|
---|
| 242 | =cut
|
---|
| 243 | */
|
---|
| 244 |
|
---|
| 245 |
|
---|
| 246 | #define PAD_DUP(dstpad, srcpad, param) \
|
---|
| 247 | if ((srcpad) && !AvREAL(srcpad)) { \
|
---|
| 248 | /* XXX padlists are real, but pretend to be not */ \
|
---|
| 249 | AvREAL_on(srcpad); \
|
---|
| 250 | (dstpad) = av_dup_inc((srcpad), param); \
|
---|
| 251 | AvREAL_off(srcpad); \
|
---|
| 252 | AvREAL_off(dstpad); \
|
---|
| 253 | } \
|
---|
| 254 | else \
|
---|
| 255 | (dstpad) = av_dup_inc((srcpad), param);
|
---|
| 256 |
|
---|
| 257 | /* NB - we set PL_comppad to null unless it points at a value that
|
---|
| 258 | * has already been dup'ed, ie it points to part of an active padlist.
|
---|
| 259 | * Otherwise PL_comppad ends up being a leaked scalar in code like
|
---|
| 260 | * the following:
|
---|
| 261 | * threads->create(sub { threads->create(sub {...} ) } );
|
---|
| 262 | * where the second thread dups the outer sub's comppad but not the
|
---|
| 263 | * sub's CV or padlist. */
|
---|
| 264 |
|
---|
| 265 | #define PAD_CLONE_VARS(proto_perl, param) \
|
---|
| 266 | PL_comppad = ptr_table_fetch(PL_ptr_table, proto_perl->Tcomppad); \
|
---|
| 267 | PL_curpad = PL_comppad ? AvARRAY(PL_comppad) : Null(SV**); \
|
---|
| 268 | PL_comppad_name = av_dup(proto_perl->Icomppad_name, param); \
|
---|
| 269 | PL_comppad_name_fill = proto_perl->Icomppad_name_fill; \
|
---|
| 270 | PL_comppad_name_floor = proto_perl->Icomppad_name_floor; \
|
---|
| 271 | PL_min_intro_pending = proto_perl->Imin_intro_pending; \
|
---|
| 272 | PL_max_intro_pending = proto_perl->Imax_intro_pending; \
|
---|
| 273 | PL_padix = proto_perl->Ipadix; \
|
---|
| 274 | PL_padix_floor = proto_perl->Ipadix_floor; \
|
---|
| 275 | PL_pad_reset_pending = proto_perl->Ipad_reset_pending; \
|
---|
| 276 | PL_cop_seqmax = proto_perl->Icop_seqmax;
|
---|