| 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; | 
|---|