Commit | Line | Data |
---|---|---|
a8a597b2 MB |
1 | /* B.xs |
2 | * | |
3 | * Copyright (c) 1996 Malcolm Beattie | |
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 | */ | |
9 | ||
c5be433b | 10 | #define PERL_NO_GET_CONTEXT |
fedf30e1 | 11 | #define PERL_EXT |
a8a597b2 MB |
12 | #include "EXTERN.h" |
13 | #include "perl.h" | |
14 | #include "XSUB.h" | |
a8a597b2 | 15 | |
51aa15f3 GS |
16 | #ifdef PerlIO |
17 | typedef PerlIO * InputStream; | |
18 | #else | |
19 | typedef FILE * InputStream; | |
20 | #endif | |
21 | ||
22 | ||
27da23d5 | 23 | static const char* const svclassnames[] = { |
a8a597b2 | 24 | "B::NULL", |
1cb9cd50 | 25 | "B::IV", |
b53eecb4 | 26 | "B::NV", |
a8a597b2 | 27 | "B::PV", |
e94d9b54 | 28 | "B::INVLIST", |
a8a597b2 MB |
29 | "B::PVIV", |
30 | "B::PVNV", | |
31 | "B::PVMG", | |
5c35adbb | 32 | "B::REGEXP", |
4ce457a6 | 33 | "B::GV", |
a8a597b2 MB |
34 | "B::PVLV", |
35 | "B::AV", | |
36 | "B::HV", | |
37 | "B::CV", | |
a8a597b2 MB |
38 | "B::FM", |
39 | "B::IO", | |
40 | }; | |
41 | ||
a8a597b2 | 42 | |
27da23d5 | 43 | static const char* const opclassnames[] = { |
a8a597b2 MB |
44 | "B::NULL", |
45 | "B::OP", | |
46 | "B::UNOP", | |
47 | "B::BINOP", | |
48 | "B::LOGOP", | |
a8a597b2 MB |
49 | "B::LISTOP", |
50 | "B::PMOP", | |
51 | "B::SVOP", | |
7934575e | 52 | "B::PADOP", |
a8a597b2 | 53 | "B::PVOP", |
a8a597b2 | 54 | "B::LOOP", |
b46e009d | 55 | "B::COP", |
2f7c6295 DM |
56 | "B::METHOP", |
57 | "B::UNOP_AUX" | |
a8a597b2 MB |
58 | }; |
59 | ||
27da23d5 | 60 | static const size_t opsizes[] = { |
651aa52e AE |
61 | 0, |
62 | sizeof(OP), | |
63 | sizeof(UNOP), | |
64 | sizeof(BINOP), | |
65 | sizeof(LOGOP), | |
66 | sizeof(LISTOP), | |
67 | sizeof(PMOP), | |
68 | sizeof(SVOP), | |
69 | sizeof(PADOP), | |
70 | sizeof(PVOP), | |
71 | sizeof(LOOP), | |
b46e009d | 72 | sizeof(COP), |
2f7c6295 DM |
73 | sizeof(METHOP), |
74 | sizeof(UNOP_AUX), | |
651aa52e AE |
75 | }; |
76 | ||
df3728a2 | 77 | #define MY_CXT_KEY "B::_guts" XS_VERSION |
a8a597b2 | 78 | |
89ca4ac7 | 79 | typedef struct { |
b043c4bf | 80 | SV * x_specialsv_list[8]; |
a462fa00 | 81 | int x_walkoptree_debug; /* Flag for walkoptree debug hook */ |
89ca4ac7 JH |
82 | } my_cxt_t; |
83 | ||
84 | START_MY_CXT | |
85 | ||
86 | #define walkoptree_debug (MY_CXT.x_walkoptree_debug) | |
87 | #define specialsv_list (MY_CXT.x_specialsv_list) | |
e8edd1e6 | 88 | |
a462fa00 DD |
89 | |
90 | static void B_init_my_cxt(pTHX_ my_cxt_t * cxt) { | |
91 | cxt->x_specialsv_list[0] = Nullsv; | |
92 | cxt->x_specialsv_list[1] = &PL_sv_undef; | |
93 | cxt->x_specialsv_list[2] = &PL_sv_yes; | |
94 | cxt->x_specialsv_list[3] = &PL_sv_no; | |
95 | cxt->x_specialsv_list[4] = (SV *) pWARN_ALL; | |
96 | cxt->x_specialsv_list[5] = (SV *) pWARN_NONE; | |
97 | cxt->x_specialsv_list[6] = (SV *) pWARN_STD; | |
b043c4bf | 98 | cxt->x_specialsv_list[7] = &PL_sv_zero; |
a462fa00 DD |
99 | } |
100 | ||
a8a597b2 | 101 | |
6079961f NC |
102 | static SV * |
103 | make_op_object(pTHX_ const OP *o) | |
a8a597b2 | 104 | { |
6079961f | 105 | SV *opsv = sv_newmortal(); |
1e85b658 | 106 | sv_setiv(newSVrv(opsv, opclassnames[op_class(o)]), PTR2IV(o)); |
6079961f | 107 | return opsv; |
a8a597b2 MB |
108 | } |
109 | ||
71324a3b DM |
110 | |
111 | static SV * | |
112 | get_overlay_object(pTHX_ const OP *o, const char * const name, U32 namelen) | |
113 | { | |
114 | HE *he; | |
115 | SV **svp; | |
116 | SV *key; | |
117 | SV *sv =get_sv("B::overlay", 0); | |
118 | if (!sv || !SvROK(sv)) | |
119 | return NULL; | |
120 | sv = SvRV(sv); | |
121 | if (SvTYPE(sv) != SVt_PVHV) | |
122 | return NULL; | |
123 | key = newSViv(PTR2IV(o)); | |
124 | he = hv_fetch_ent((HV*)sv, key, 0, 0); | |
125 | SvREFCNT_dec(key); | |
126 | if (!he) | |
127 | return NULL; | |
128 | sv = HeVAL(he); | |
129 | if (!sv || !SvROK(sv)) | |
130 | return NULL; | |
131 | sv = SvRV(sv); | |
132 | if (SvTYPE(sv) != SVt_PVHV) | |
133 | return NULL; | |
134 | svp = hv_fetch((HV*)sv, name, namelen, 0); | |
135 | if (!svp) | |
136 | return NULL; | |
137 | sv = *svp; | |
138 | return sv; | |
139 | } | |
140 | ||
141 | ||
a8a597b2 | 142 | static SV * |
0c74f67f | 143 | make_sv_object(pTHX_ SV *sv) |
a8a597b2 | 144 | { |
0c74f67f | 145 | SV *const arg = sv_newmortal(); |
27da23d5 | 146 | const char *type = 0; |
a8a597b2 | 147 | IV iv; |
89ca4ac7 | 148 | dMY_CXT; |
9496d2e5 | 149 | |
c33e8be1 | 150 | for (iv = 0; iv < (IV)(sizeof(specialsv_list)/sizeof(SV*)); iv++) { |
e8edd1e6 | 151 | if (sv == specialsv_list[iv]) { |
a8a597b2 MB |
152 | type = "B::SPECIAL"; |
153 | break; | |
154 | } | |
155 | } | |
156 | if (!type) { | |
157 | type = svclassnames[SvTYPE(sv)]; | |
56431972 | 158 | iv = PTR2IV(sv); |
a8a597b2 MB |
159 | } |
160 | sv_setiv(newSVrv(arg, type), iv); | |
161 | return arg; | |
162 | } | |
163 | ||
164 | static SV * | |
9496d2e5 | 165 | make_temp_object(pTHX_ SV *temp) |
8e01d9a6 NC |
166 | { |
167 | SV *target; | |
9496d2e5 | 168 | SV *arg = sv_newmortal(); |
8e01d9a6 NC |
169 | const char *const type = svclassnames[SvTYPE(temp)]; |
170 | const IV iv = PTR2IV(temp); | |
171 | ||
172 | target = newSVrv(arg, type); | |
173 | sv_setiv(target, iv); | |
174 | ||
175 | /* Need to keep our "temp" around as long as the target exists. | |
176 | Simplest way seems to be to hang it from magic, and let that clear | |
177 | it up. No vtable, so won't actually get in the way of anything. */ | |
178 | sv_magicext(target, temp, PERL_MAGIC_sv, NULL, NULL, 0); | |
179 | /* magic object has had its reference count increased, so we must drop | |
180 | our reference. */ | |
181 | SvREFCNT_dec(temp); | |
182 | return arg; | |
183 | } | |
184 | ||
185 | static SV * | |
d2b4c688 | 186 | make_warnings_object(pTHX_ const COP *const cop) |
5c3c3f81 | 187 | { |
d2b4c688 | 188 | const STRLEN *const warnings = cop->cop_warnings; |
5c3c3f81 NC |
189 | const char *type = 0; |
190 | dMY_CXT; | |
191 | IV iv = sizeof(specialsv_list)/sizeof(SV*); | |
192 | ||
193 | /* Counting down is deliberate. Before the split between make_sv_object | |
194 | and make_warnings_obj there appeared to be a bug - Nullsv and pWARN_STD | |
195 | were both 0, so you could never get a B::SPECIAL for pWARN_STD */ | |
196 | ||
197 | while (iv--) { | |
198 | if ((SV*)warnings == specialsv_list[iv]) { | |
199 | type = "B::SPECIAL"; | |
200 | break; | |
201 | } | |
202 | } | |
203 | if (type) { | |
9496d2e5 | 204 | SV *arg = sv_newmortal(); |
5c3c3f81 | 205 | sv_setiv(newSVrv(arg, type), iv); |
8e01d9a6 | 206 | return arg; |
5c3c3f81 NC |
207 | } else { |
208 | /* B assumes that warnings are a regular SV. Seems easier to keep it | |
209 | happy by making them into a regular SV. */ | |
9496d2e5 | 210 | return make_temp_object(aTHX_ newSVpvn((char *)(warnings + 1), *warnings)); |
8e01d9a6 NC |
211 | } |
212 | } | |
213 | ||
214 | static SV * | |
9496d2e5 | 215 | make_cop_io_object(pTHX_ COP *cop) |
8e01d9a6 | 216 | { |
8b850bd5 NC |
217 | SV *const value = newSV(0); |
218 | ||
33972ad6 | 219 | Perl_emulate_cop_io(aTHX_ cop, value); |
8b850bd5 NC |
220 | |
221 | if(SvOK(value)) { | |
0c74f67f | 222 | return make_sv_object(aTHX_ value); |
8e01d9a6 | 223 | } else { |
8b850bd5 | 224 | SvREFCNT_dec(value); |
0c74f67f | 225 | return make_sv_object(aTHX_ NULL); |
5c3c3f81 | 226 | } |
5c3c3f81 NC |
227 | } |
228 | ||
229 | static SV * | |
9496d2e5 | 230 | make_mg_object(pTHX_ MAGIC *mg) |
a8a597b2 | 231 | { |
9496d2e5 | 232 | SV *arg = sv_newmortal(); |
56431972 | 233 | sv_setiv(newSVrv(arg, "B::MAGIC"), PTR2IV(mg)); |
a8a597b2 MB |
234 | return arg; |
235 | } | |
236 | ||
237 | static SV * | |
52ad86de | 238 | cstring(pTHX_ SV *sv, bool perlstyle) |
a8a597b2 | 239 | { |
09e97b95 | 240 | SV *sstr; |
a8a597b2 MB |
241 | |
242 | if (!SvOK(sv)) | |
09e97b95 NC |
243 | return newSVpvs_flags("0", SVs_TEMP); |
244 | ||
245 | sstr = newSVpvs_flags("\"", SVs_TEMP); | |
246 | ||
247 | if (perlstyle && SvUTF8(sv)) { | |
d79a7a3d | 248 | SV *tmpsv = sv_newmortal(); /* Temporary SV to feed sv_uni_display */ |
5d7488b2 AL |
249 | const STRLEN len = SvCUR(sv); |
250 | const char *s = sv_uni_display(tmpsv, sv, 8*len, UNI_DISPLAY_QQ); | |
d79a7a3d RGS |
251 | while (*s) |
252 | { | |
253 | if (*s == '"') | |
6beb30a6 | 254 | sv_catpvs(sstr, "\\\""); |
d79a7a3d | 255 | else if (*s == '$') |
6beb30a6 | 256 | sv_catpvs(sstr, "\\$"); |
d79a7a3d | 257 | else if (*s == '@') |
6beb30a6 | 258 | sv_catpvs(sstr, "\\@"); |
d79a7a3d RGS |
259 | else if (*s == '\\') |
260 | { | |
261 | if (strchr("nrftax\\",*(s+1))) | |
262 | sv_catpvn(sstr, s++, 2); | |
263 | else | |
6beb30a6 | 264 | sv_catpvs(sstr, "\\\\"); |
d79a7a3d RGS |
265 | } |
266 | else /* should always be printable */ | |
267 | sv_catpvn(sstr, s, 1); | |
268 | ++s; | |
269 | } | |
d79a7a3d | 270 | } |
a8a597b2 MB |
271 | else |
272 | { | |
273 | /* XXX Optimise? */ | |
5d7488b2 AL |
274 | STRLEN len; |
275 | const char *s = SvPV(sv, len); | |
a8a597b2 MB |
276 | for (; len; len--, s++) |
277 | { | |
278 | /* At least try a little for readability */ | |
279 | if (*s == '"') | |
6beb30a6 | 280 | sv_catpvs(sstr, "\\\""); |
a8a597b2 | 281 | else if (*s == '\\') |
6beb30a6 | 282 | sv_catpvs(sstr, "\\\\"); |
b326da91 | 283 | /* trigraphs - bleagh */ |
5d7488b2 | 284 | else if (!perlstyle && *s == '?' && len>=3 && s[1] == '?') { |
47bf35fa | 285 | Perl_sv_catpvf(aTHX_ sstr, "\\%03o", '?'); |
b326da91 | 286 | } |
52ad86de | 287 | else if (perlstyle && *s == '$') |
6beb30a6 | 288 | sv_catpvs(sstr, "\\$"); |
52ad86de | 289 | else if (perlstyle && *s == '@') |
6beb30a6 | 290 | sv_catpvs(sstr, "\\@"); |
ce561ef2 | 291 | else if (isPRINT(*s)) |
a8a597b2 MB |
292 | sv_catpvn(sstr, s, 1); |
293 | else if (*s == '\n') | |
6beb30a6 | 294 | sv_catpvs(sstr, "\\n"); |
a8a597b2 | 295 | else if (*s == '\r') |
6beb30a6 | 296 | sv_catpvs(sstr, "\\r"); |
a8a597b2 | 297 | else if (*s == '\t') |
6beb30a6 | 298 | sv_catpvs(sstr, "\\t"); |
a8a597b2 | 299 | else if (*s == '\a') |
6beb30a6 | 300 | sv_catpvs(sstr, "\\a"); |
a8a597b2 | 301 | else if (*s == '\b') |
6beb30a6 | 302 | sv_catpvs(sstr, "\\b"); |
a8a597b2 | 303 | else if (*s == '\f') |
6beb30a6 | 304 | sv_catpvs(sstr, "\\f"); |
52ad86de | 305 | else if (!perlstyle && *s == '\v') |
6beb30a6 | 306 | sv_catpvs(sstr, "\\v"); |
a8a597b2 MB |
307 | else |
308 | { | |
a8a597b2 | 309 | /* Don't want promotion of a signed -1 char in sprintf args */ |
5d7488b2 | 310 | const unsigned char c = (unsigned char) *s; |
47bf35fa | 311 | Perl_sv_catpvf(aTHX_ sstr, "\\%03o", c); |
a8a597b2 MB |
312 | } |
313 | /* XXX Add line breaks if string is long */ | |
314 | } | |
a8a597b2 | 315 | } |
09e97b95 | 316 | sv_catpvs(sstr, "\""); |
a8a597b2 MB |
317 | return sstr; |
318 | } | |
319 | ||
320 | static SV * | |
cea2e8a9 | 321 | cchar(pTHX_ SV *sv) |
a8a597b2 | 322 | { |
422d053b | 323 | SV *sstr = newSVpvs_flags("'", SVs_TEMP); |
5d7488b2 | 324 | const char *s = SvPV_nolen(sv); |
422d053b NC |
325 | /* Don't want promotion of a signed -1 char in sprintf args */ |
326 | const unsigned char c = (unsigned char) *s; | |
a8a597b2 | 327 | |
422d053b | 328 | if (c == '\'') |
6beb30a6 | 329 | sv_catpvs(sstr, "\\'"); |
422d053b | 330 | else if (c == '\\') |
6beb30a6 | 331 | sv_catpvs(sstr, "\\\\"); |
422d053b | 332 | else if (isPRINT(c)) |
a8a597b2 | 333 | sv_catpvn(sstr, s, 1); |
422d053b | 334 | else if (c == '\n') |
6beb30a6 | 335 | sv_catpvs(sstr, "\\n"); |
422d053b | 336 | else if (c == '\r') |
6beb30a6 | 337 | sv_catpvs(sstr, "\\r"); |
422d053b | 338 | else if (c == '\t') |
6beb30a6 | 339 | sv_catpvs(sstr, "\\t"); |
422d053b | 340 | else if (c == '\a') |
6beb30a6 | 341 | sv_catpvs(sstr, "\\a"); |
422d053b | 342 | else if (c == '\b') |
6beb30a6 | 343 | sv_catpvs(sstr, "\\b"); |
422d053b | 344 | else if (c == '\f') |
6beb30a6 | 345 | sv_catpvs(sstr, "\\f"); |
422d053b | 346 | else if (c == '\v') |
6beb30a6 | 347 | sv_catpvs(sstr, "\\v"); |
a8a597b2 | 348 | else |
422d053b | 349 | Perl_sv_catpvf(aTHX_ sstr, "\\%03o", c); |
6beb30a6 | 350 | sv_catpvs(sstr, "'"); |
a8a597b2 MB |
351 | return sstr; |
352 | } | |
353 | ||
35633035 DM |
354 | #define PMOP_pmreplstart(o) o->op_pmstashstartu.op_pmreplstart |
355 | #define PMOP_pmreplroot(o) o->op_pmreplrootu.op_pmreplroot | |
8f3d514b | 356 | |
20f7624e NC |
357 | static SV * |
358 | walkoptree(pTHX_ OP *o, const char *method, SV *ref) | |
a8a597b2 MB |
359 | { |
360 | dSP; | |
20f7624e NC |
361 | OP *kid; |
362 | SV *object; | |
1e85b658 | 363 | const char *const classname = opclassnames[op_class(o)]; |
89ca4ac7 JH |
364 | dMY_CXT; |
365 | ||
20f7624e NC |
366 | /* Check that no-one has changed our reference, or is holding a reference |
367 | to it. */ | |
368 | if (SvREFCNT(ref) == 1 && SvROK(ref) && SvTYPE(ref) == SVt_RV | |
369 | && (object = SvRV(ref)) && SvREFCNT(object) == 1 | |
370 | && SvTYPE(object) == SVt_PVMG && SvIOK_only(object) | |
371 | && !SvMAGICAL(object) && !SvMAGIC(object) && SvSTASH(object)) { | |
372 | /* Looks good, so rebless it for the class we need: */ | |
373 | sv_bless(ref, gv_stashpv(classname, GV_ADD)); | |
374 | } else { | |
375 | /* Need to make a new one. */ | |
376 | ref = sv_newmortal(); | |
377 | object = newSVrv(ref, classname); | |
378 | } | |
379 | sv_setiv(object, PTR2IV(o)); | |
380 | ||
a8a597b2 MB |
381 | if (walkoptree_debug) { |
382 | PUSHMARK(sp); | |
20f7624e | 383 | XPUSHs(ref); |
a8a597b2 MB |
384 | PUTBACK; |
385 | perl_call_method("walkoptree_debug", G_DISCARD); | |
386 | } | |
387 | PUSHMARK(sp); | |
20f7624e | 388 | XPUSHs(ref); |
a8a597b2 MB |
389 | PUTBACK; |
390 | perl_call_method(method, G_DISCARD); | |
391 | if (o && (o->op_flags & OPf_KIDS)) { | |
e6dae479 | 392 | for (kid = ((UNOP*)o)->op_first; kid; kid = OpSIBLING(kid)) { |
20f7624e | 393 | ref = walkoptree(aTHX_ kid, method, ref); |
a8a597b2 MB |
394 | } |
395 | } | |
1e85b658 | 396 | if (o && (op_class(o) == OPclass_PMOP) && o->op_type != OP_SPLIT |
8f3d514b | 397 | && (kid = PMOP_pmreplroot(cPMOPo))) |
f3be9b72 | 398 | { |
20f7624e | 399 | ref = walkoptree(aTHX_ kid, method, ref); |
f3be9b72 | 400 | } |
20f7624e | 401 | return ref; |
a8a597b2 MB |
402 | } |
403 | ||
5d7488b2 | 404 | static SV ** |
1df34986 AE |
405 | oplist(pTHX_ OP *o, SV **SP) |
406 | { | |
407 | for(; o; o = o->op_next) { | |
7252851f | 408 | if (o->op_opt == 0) |
1df34986 | 409 | break; |
2814eb74 | 410 | o->op_opt = 0; |
6079961f | 411 | XPUSHs(make_op_object(aTHX_ o)); |
1df34986 AE |
412 | switch (o->op_type) { |
413 | case OP_SUBST: | |
8f3d514b | 414 | SP = oplist(aTHX_ PMOP_pmreplstart(cPMOPo), SP); |
1df34986 AE |
415 | continue; |
416 | case OP_SORT: | |
f66c782a | 417 | if (o->op_flags & OPf_STACKED && o->op_flags & OPf_SPECIAL) { |
e6dae479 | 418 | OP *kid = OpSIBLING(cLISTOPo->op_first); /* pass pushmark */ |
1df34986 AE |
419 | kid = kUNOP->op_first; /* pass rv2gv */ |
420 | kid = kUNOP->op_first; /* pass leave */ | |
f66c782a | 421 | SP = oplist(aTHX_ kid->op_next, SP); |
1df34986 AE |
422 | } |
423 | continue; | |
424 | } | |
425 | switch (PL_opargs[o->op_type] & OA_CLASS_MASK) { | |
426 | case OA_LOGOP: | |
427 | SP = oplist(aTHX_ cLOGOPo->op_other, SP); | |
428 | break; | |
429 | case OA_LOOP: | |
430 | SP = oplist(aTHX_ cLOOPo->op_lastop, SP); | |
431 | SP = oplist(aTHX_ cLOOPo->op_nextop, SP); | |
432 | SP = oplist(aTHX_ cLOOPo->op_redoop, SP); | |
433 | break; | |
434 | } | |
435 | } | |
436 | return SP; | |
437 | } | |
438 | ||
a8a597b2 MB |
439 | typedef OP *B__OP; |
440 | typedef UNOP *B__UNOP; | |
441 | typedef BINOP *B__BINOP; | |
442 | typedef LOGOP *B__LOGOP; | |
a8a597b2 MB |
443 | typedef LISTOP *B__LISTOP; |
444 | typedef PMOP *B__PMOP; | |
445 | typedef SVOP *B__SVOP; | |
7934575e | 446 | typedef PADOP *B__PADOP; |
a8a597b2 MB |
447 | typedef PVOP *B__PVOP; |
448 | typedef LOOP *B__LOOP; | |
449 | typedef COP *B__COP; | |
b46e009d | 450 | typedef METHOP *B__METHOP; |
a8a597b2 MB |
451 | |
452 | typedef SV *B__SV; | |
453 | typedef SV *B__IV; | |
454 | typedef SV *B__PV; | |
455 | typedef SV *B__NV; | |
456 | typedef SV *B__PVMG; | |
5c35adbb | 457 | typedef SV *B__REGEXP; |
a8a597b2 MB |
458 | typedef SV *B__PVLV; |
459 | typedef SV *B__BM; | |
460 | typedef SV *B__RV; | |
1df34986 | 461 | typedef SV *B__FM; |
a8a597b2 MB |
462 | typedef AV *B__AV; |
463 | typedef HV *B__HV; | |
464 | typedef CV *B__CV; | |
465 | typedef GV *B__GV; | |
466 | typedef IO *B__IO; | |
467 | ||
468 | typedef MAGIC *B__MAGIC; | |
fd9f6265 JJ |
469 | typedef HE *B__HE; |
470 | typedef struct refcounted_he *B__RHE; | |
7261499d | 471 | typedef PADLIST *B__PADLIST; |
9b7476d7 | 472 | typedef PADNAMELIST *B__PADNAMELIST; |
0f94cb1f | 473 | typedef PADNAME *B__PADNAME; |
9b7476d7 | 474 | |
a8a597b2 | 475 | |
3486ec84 | 476 | #ifdef MULTIPLICITY |
115ff745 | 477 | # define ASSIGN_COMMON_ALIAS(prefix, var) \ |
3800c318 | 478 | STMT_START { XSANY.any_i32 = STRUCT_OFFSET(struct interpreter, prefix##var); } STMT_END |
32855229 | 479 | #else |
115ff745 | 480 | # define ASSIGN_COMMON_ALIAS(prefix, var) \ |
32855229 NC |
481 | STMT_START { XSANY.any_ptr = (void *)&PL_##var; } STMT_END |
482 | #endif | |
483 | ||
484 | /* This needs to be ALIASed in a custom way, hence can't easily be defined as | |
485 | a regular XSUB. */ | |
486 | static XSPROTO(intrpvar_sv_common); /* prototype to pass -Wmissing-prototypes */ | |
487 | static XSPROTO(intrpvar_sv_common) | |
488 | { | |
489 | dVAR; | |
490 | dXSARGS; | |
491 | SV *ret; | |
492 | if (items != 0) | |
493 | croak_xs_usage(cv, ""); | |
3486ec84 | 494 | #ifdef MULTIPLICITY |
32855229 NC |
495 | ret = *(SV **)(XSANY.any_i32 + (char *)my_perl); |
496 | #else | |
497 | ret = *(SV **)(XSANY.any_ptr); | |
498 | #endif | |
0c74f67f | 499 | ST(0) = make_sv_object(aTHX_ ret); |
32855229 NC |
500 | XSRETURN(1); |
501 | } | |
502 | ||
bec746fe DM |
503 | |
504 | ||
0508288e NC |
505 | #define SVp 0x0 |
506 | #define U32p 0x1 | |
507 | #define line_tp 0x2 | |
508 | #define OPp 0x3 | |
509 | #define PADOFFSETp 0x4 | |
510 | #define U8p 0x5 | |
511 | #define IVp 0x6 | |
512 | #define char_pp 0x7 | |
513 | /* Keep this last: */ | |
514 | #define op_offset_special 0x8 | |
bec746fe DM |
515 | |
516 | /* table that drives most of the B::*OP methods */ | |
517 | ||
0b057af7 | 518 | static const struct OP_methods { |
bec746fe | 519 | const char *name; |
7d6d3fb7 | 520 | U8 namelen; |
0508288e NC |
521 | U8 type; /* if op_offset_special, access is handled on a case-by-case basis */ |
522 | U16 offset; | |
bec746fe | 523 | } op_methods[] = { |
3800c318 | 524 | { STR_WITH_LEN("next"), OPp, STRUCT_OFFSET(struct op, op_next), },/* 0*/ |
1ed44841 | 525 | { STR_WITH_LEN("sibling"), op_offset_special, 0, },/* 1*/ |
3800c318 JH |
526 | { STR_WITH_LEN("targ"), PADOFFSETp, STRUCT_OFFSET(struct op, op_targ), },/* 2*/ |
527 | { STR_WITH_LEN("flags"), U8p, STRUCT_OFFSET(struct op, op_flags), },/* 3*/ | |
528 | { STR_WITH_LEN("private"), U8p, STRUCT_OFFSET(struct op, op_private), },/* 4*/ | |
529 | { STR_WITH_LEN("first"), OPp, STRUCT_OFFSET(struct unop, op_first), },/* 5*/ | |
530 | { STR_WITH_LEN("last"), OPp, STRUCT_OFFSET(struct binop, op_last), },/* 6*/ | |
531 | { STR_WITH_LEN("other"), OPp, STRUCT_OFFSET(struct logop, op_other), },/* 7*/ | |
99639b5b | 532 | { STR_WITH_LEN("pmreplstart"), op_offset_special, 0, },/* 8*/ |
3800c318 JH |
533 | { STR_WITH_LEN("redoop"), OPp, STRUCT_OFFSET(struct loop, op_redoop), },/* 9*/ |
534 | { STR_WITH_LEN("nextop"), OPp, STRUCT_OFFSET(struct loop, op_nextop), },/*10*/ | |
535 | { STR_WITH_LEN("lastop"), OPp, STRUCT_OFFSET(struct loop, op_lastop), },/*11*/ | |
536 | { STR_WITH_LEN("pmflags"), U32p, STRUCT_OFFSET(struct pmop, op_pmflags),},/*12*/ | |
3800c318 | 537 | { STR_WITH_LEN("code_list"),OPp, STRUCT_OFFSET(struct pmop, op_code_list),},/*13*/ |
3800c318 JH |
538 | { STR_WITH_LEN("sv"), SVp, STRUCT_OFFSET(struct svop, op_sv), },/*14*/ |
539 | { STR_WITH_LEN("gv"), SVp, STRUCT_OFFSET(struct svop, op_sv), },/*15*/ | |
540 | { STR_WITH_LEN("padix"), PADOFFSETp,STRUCT_OFFSET(struct padop, op_padix),},/*16*/ | |
541 | { STR_WITH_LEN("cop_seq"), U32p, STRUCT_OFFSET(struct cop, cop_seq), },/*17*/ | |
542 | { STR_WITH_LEN("line"), line_tp, STRUCT_OFFSET(struct cop, cop_line), },/*18*/ | |
543 | { STR_WITH_LEN("hints"), U32p, STRUCT_OFFSET(struct cop, cop_hints), },/*19*/ | |
bec746fe | 544 | #ifdef USE_ITHREADS |
3800c318 | 545 | { STR_WITH_LEN("pmoffset"),IVp, STRUCT_OFFSET(struct pmop, op_pmoffset),},/*20*/ |
99639b5b | 546 | { STR_WITH_LEN("filegv"), op_offset_special, 0, },/*21*/ |
3800c318 | 547 | { STR_WITH_LEN("file"), char_pp, STRUCT_OFFSET(struct cop, cop_file), },/*22*/ |
99639b5b | 548 | { STR_WITH_LEN("stash"), op_offset_special, 0, },/*23*/ |
99639b5b | 549 | { STR_WITH_LEN("stashpv"), op_offset_special, 0, },/*24*/ |
3800c318 | 550 | { STR_WITH_LEN("stashoff"),PADOFFSETp,STRUCT_OFFSET(struct cop,cop_stashoff),},/*25*/ |
bec746fe | 551 | #else |
99639b5b | 552 | { STR_WITH_LEN("pmoffset"),op_offset_special, 0, },/*20*/ |
3800c318 | 553 | { STR_WITH_LEN("filegv"), SVp, STRUCT_OFFSET(struct cop, cop_filegv),},/*21*/ |
99639b5b | 554 | { STR_WITH_LEN("file"), op_offset_special, 0, },/*22*/ |
3800c318 | 555 | { STR_WITH_LEN("stash"), SVp, STRUCT_OFFSET(struct cop, cop_stash), },/*23*/ |
99639b5b DM |
556 | { STR_WITH_LEN("stashpv"), op_offset_special, 0, },/*24*/ |
557 | { STR_WITH_LEN("stashoff"),op_offset_special, 0, },/*25*/ | |
bec746fe | 558 | #endif |
99639b5b DM |
559 | { STR_WITH_LEN("size"), op_offset_special, 0, },/*26*/ |
560 | { STR_WITH_LEN("name"), op_offset_special, 0, },/*27*/ | |
561 | { STR_WITH_LEN("desc"), op_offset_special, 0, },/*28*/ | |
562 | { STR_WITH_LEN("ppaddr"), op_offset_special, 0, },/*29*/ | |
563 | { STR_WITH_LEN("type"), op_offset_special, 0, },/*30*/ | |
564 | { STR_WITH_LEN("opt"), op_offset_special, 0, },/*31*/ | |
565 | { STR_WITH_LEN("spare"), op_offset_special, 0, },/*32*/ | |
566 | { STR_WITH_LEN("children"),op_offset_special, 0, },/*33*/ | |
567 | { STR_WITH_LEN("pmreplroot"), op_offset_special, 0, },/*34*/ | |
568 | { STR_WITH_LEN("pmstashpv"), op_offset_special, 0, },/*35*/ | |
569 | { STR_WITH_LEN("pmstash"), op_offset_special, 0, },/*36*/ | |
570 | { STR_WITH_LEN("precomp"), op_offset_special, 0, },/*37*/ | |
571 | { STR_WITH_LEN("reflags"), op_offset_special, 0, },/*38*/ | |
572 | { STR_WITH_LEN("sv"), op_offset_special, 0, },/*39*/ | |
573 | { STR_WITH_LEN("gv"), op_offset_special, 0, },/*40*/ | |
574 | { STR_WITH_LEN("pv"), op_offset_special, 0, },/*41*/ | |
575 | { STR_WITH_LEN("label"), op_offset_special, 0, },/*42*/ | |
576 | { STR_WITH_LEN("arybase"), op_offset_special, 0, },/*43*/ | |
577 | { STR_WITH_LEN("warnings"),op_offset_special, 0, },/*44*/ | |
578 | { STR_WITH_LEN("io"), op_offset_special, 0, },/*45*/ | |
579 | { STR_WITH_LEN("hints_hash"),op_offset_special, 0, },/*46*/ | |
99639b5b DM |
580 | { STR_WITH_LEN("slabbed"), op_offset_special, 0, },/*47*/ |
581 | { STR_WITH_LEN("savefree"),op_offset_special, 0, },/*48*/ | |
582 | { STR_WITH_LEN("static"), op_offset_special, 0, },/*49*/ | |
99639b5b | 583 | { STR_WITH_LEN("folded"), op_offset_special, 0, },/*50*/ |
87b5a8b9 | 584 | { STR_WITH_LEN("moresib"), op_offset_special, 0, },/*51*/ |
29e61fd9 | 585 | { STR_WITH_LEN("parent"), op_offset_special, 0, },/*52*/ |
b46e009d | 586 | { STR_WITH_LEN("first"), op_offset_special, 0, },/*53*/ |
587 | { STR_WITH_LEN("meth_sv"), op_offset_special, 0, },/*54*/ | |
429ba3b2 | 588 | { STR_WITH_LEN("pmregexp"),op_offset_special, 0, },/*55*/ |
810bd8b7 | 589 | # ifdef USE_ITHREADS |
590 | { STR_WITH_LEN("rclass"), op_offset_special, 0, },/*56*/ | |
591 | # else | |
592 | { STR_WITH_LEN("rclass"), op_offset_special, 0, },/*56*/ | |
593 | # endif | |
bec746fe DM |
594 | }; |
595 | ||
b1826b71 NC |
596 | #include "const-c.inc" |
597 | ||
7a2c16aa | 598 | MODULE = B PACKAGE = B |
a8a597b2 | 599 | |
b1826b71 NC |
600 | INCLUDE: const-xs.inc |
601 | ||
a8a597b2 MB |
602 | PROTOTYPES: DISABLE |
603 | ||
604 | BOOT: | |
4c1f658f | 605 | { |
7a2c16aa NC |
606 | CV *cv; |
607 | const char *file = __FILE__; | |
c3890f9c | 608 | SV *sv; |
89ca4ac7 | 609 | MY_CXT_INIT; |
a462fa00 | 610 | B_init_my_cxt(aTHX_ &(MY_CXT)); |
32855229 | 611 | cv = newXS("B::init_av", intrpvar_sv_common, file); |
115ff745 | 612 | ASSIGN_COMMON_ALIAS(I, initav); |
32855229 | 613 | cv = newXS("B::check_av", intrpvar_sv_common, file); |
115ff745 | 614 | ASSIGN_COMMON_ALIAS(I, checkav_save); |
32855229 | 615 | cv = newXS("B::unitcheck_av", intrpvar_sv_common, file); |
115ff745 | 616 | ASSIGN_COMMON_ALIAS(I, unitcheckav_save); |
32855229 | 617 | cv = newXS("B::begin_av", intrpvar_sv_common, file); |
115ff745 | 618 | ASSIGN_COMMON_ALIAS(I, beginav_save); |
32855229 | 619 | cv = newXS("B::end_av", intrpvar_sv_common, file); |
115ff745 | 620 | ASSIGN_COMMON_ALIAS(I, endav); |
32855229 | 621 | cv = newXS("B::main_cv", intrpvar_sv_common, file); |
115ff745 | 622 | ASSIGN_COMMON_ALIAS(I, main_cv); |
32855229 | 623 | cv = newXS("B::inc_gv", intrpvar_sv_common, file); |
115ff745 | 624 | ASSIGN_COMMON_ALIAS(I, incgv); |
32855229 | 625 | cv = newXS("B::defstash", intrpvar_sv_common, file); |
115ff745 | 626 | ASSIGN_COMMON_ALIAS(I, defstash); |
32855229 | 627 | cv = newXS("B::curstash", intrpvar_sv_common, file); |
115ff745 | 628 | ASSIGN_COMMON_ALIAS(I, curstash); |
32855229 NC |
629 | #ifdef USE_ITHREADS |
630 | cv = newXS("B::regex_padav", intrpvar_sv_common, file); | |
115ff745 | 631 | ASSIGN_COMMON_ALIAS(I, regex_padav); |
32855229 NC |
632 | #endif |
633 | cv = newXS("B::warnhook", intrpvar_sv_common, file); | |
115ff745 | 634 | ASSIGN_COMMON_ALIAS(I, warnhook); |
32855229 | 635 | cv = newXS("B::diehook", intrpvar_sv_common, file); |
115ff745 | 636 | ASSIGN_COMMON_ALIAS(I, diehook); |
c3890f9c | 637 | sv = get_sv("B::OP::does_parent", GV_ADDMULTI); |
c3890f9c | 638 | #ifdef PERL_OP_PARENT |
e1812838 | 639 | sv_setsv(sv, &PL_sv_yes); |
c3890f9c | 640 | #else |
e1812838 | 641 | sv_setsv(sv, &PL_sv_no); |
c3890f9c | 642 | #endif |
32855229 NC |
643 | } |
644 | ||
5f7e30c4 NC |
645 | void |
646 | formfeed() | |
647 | PPCODE: | |
648 | PUSHs(make_sv_object(aTHX_ GvSV(gv_fetchpvs("\f", GV_ADD, SVt_PV)))); | |
649 | ||
7a2c16aa NC |
650 | long |
651 | amagic_generation() | |
652 | CODE: | |
653 | RETVAL = PL_amagic_generation; | |
654 | OUTPUT: | |
655 | RETVAL | |
656 | ||
8ae5a962 | 657 | void |
7a2c16aa | 658 | comppadlist() |
7261499d FC |
659 | PREINIT: |
660 | PADLIST *padlist = CvPADLIST(PL_main_cv ? PL_main_cv : PL_compcv); | |
8ae5a962 | 661 | PPCODE: |
7261499d FC |
662 | { |
663 | SV * const rv = sv_newmortal(); | |
664 | sv_setiv(newSVrv(rv, padlist ? "B::PADLIST" : "B::NULL"), | |
665 | PTR2IV(padlist)); | |
666 | PUSHs(rv); | |
667 | } | |
7a2c16aa | 668 | |
8ae5a962 | 669 | void |
a4aabc83 NC |
670 | sv_undef() |
671 | ALIAS: | |
672 | sv_no = 1 | |
673 | sv_yes = 2 | |
8ae5a962 | 674 | PPCODE: |
0c74f67f NC |
675 | PUSHs(make_sv_object(aTHX_ ix > 1 ? &PL_sv_yes |
676 | : ix < 1 ? &PL_sv_undef | |
677 | : &PL_sv_no)); | |
a4aabc83 | 678 | |
6079961f | 679 | void |
e97701b4 NC |
680 | main_root() |
681 | ALIAS: | |
682 | main_start = 1 | |
6079961f NC |
683 | PPCODE: |
684 | PUSHs(make_op_object(aTHX_ ix ? PL_main_start : PL_main_root)); | |
e97701b4 | 685 | |
2edf0c1d NC |
686 | UV |
687 | sub_generation() | |
688 | ALIAS: | |
689 | dowarn = 1 | |
690 | CODE: | |
691 | RETVAL = ix ? PL_dowarn : PL_sub_generation; | |
692 | OUTPUT: | |
693 | RETVAL | |
694 | ||
a8a597b2 | 695 | void |
20f7624e NC |
696 | walkoptree(op, method) |
697 | B::OP op | |
5d7488b2 | 698 | const char * method |
cea2e8a9 | 699 | CODE: |
20f7624e | 700 | (void) walkoptree(aTHX_ op, method, &PL_sv_undef); |
a8a597b2 MB |
701 | |
702 | int | |
703 | walkoptree_debug(...) | |
704 | CODE: | |
89ca4ac7 | 705 | dMY_CXT; |
a8a597b2 MB |
706 | RETVAL = walkoptree_debug; |
707 | if (items > 0 && SvTRUE(ST(1))) | |
708 | walkoptree_debug = 1; | |
709 | OUTPUT: | |
710 | RETVAL | |
711 | ||
56431972 | 712 | #define address(sv) PTR2IV(sv) |
a8a597b2 MB |
713 | |
714 | IV | |
715 | address(sv) | |
716 | SV * sv | |
717 | ||
8ae5a962 | 718 | void |
a8a597b2 MB |
719 | svref_2object(sv) |
720 | SV * sv | |
8ae5a962 | 721 | PPCODE: |
a8a597b2 MB |
722 | if (!SvROK(sv)) |
723 | croak("argument is not a reference"); | |
0c74f67f | 724 | PUSHs(make_sv_object(aTHX_ SvRV(sv))); |
0cc1d052 NIS |
725 | |
726 | void | |
727 | opnumber(name) | |
5d7488b2 | 728 | const char * name |
0cc1d052 NIS |
729 | CODE: |
730 | { | |
731 | int i; | |
732 | IV result = -1; | |
733 | ST(0) = sv_newmortal(); | |
c8b388b0 | 734 | if (strBEGINs(name,"pp_")) |
0cc1d052 NIS |
735 | name += 3; |
736 | for (i = 0; i < PL_maxo; i++) | |
737 | { | |
752602b1 | 738 | if (strEQ(name, PL_op_name[i])) |
0cc1d052 NIS |
739 | { |
740 | result = i; | |
741 | break; | |
742 | } | |
743 | } | |
744 | sv_setiv(ST(0),result); | |
745 | } | |
a8a597b2 MB |
746 | |
747 | void | |
748 | ppname(opnum) | |
749 | int opnum | |
750 | CODE: | |
751 | ST(0) = sv_newmortal(); | |
cc5b6bab NC |
752 | if (opnum >= 0 && opnum < PL_maxo) |
753 | Perl_sv_setpvf(aTHX_ ST(0), "pp_%s", PL_op_name[opnum]); | |
a8a597b2 MB |
754 | |
755 | void | |
756 | hash(sv) | |
757 | SV * sv | |
758 | CODE: | |
a8a597b2 MB |
759 | STRLEN len; |
760 | U32 hash = 0; | |
8c5b7c71 | 761 | const char *s = SvPVbyte(sv, len); |
c32d3395 | 762 | PERL_HASH(hash, s, len); |
147e3846 | 763 | ST(0) = sv_2mortal(Perl_newSVpvf(aTHX_ "0x%" UVxf, (UV)hash)); |
a8a597b2 MB |
764 | |
765 | #define cast_I32(foo) (I32)foo | |
766 | IV | |
767 | cast_I32(i) | |
768 | IV i | |
769 | ||
770 | void | |
771 | minus_c() | |
651233d2 NC |
772 | ALIAS: |
773 | save_BEGINs = 1 | |
a8a597b2 | 774 | CODE: |
651233d2 NC |
775 | if (ix) |
776 | PL_savebegin = TRUE; | |
777 | else | |
778 | PL_minus_c = TRUE; | |
059a8bb7 | 779 | |
847ded71 | 780 | void |
a8a597b2 MB |
781 | cstring(sv) |
782 | SV * sv | |
84556172 NC |
783 | ALIAS: |
784 | perlstring = 1 | |
9e380ad4 | 785 | cchar = 2 |
09e97b95 | 786 | PPCODE: |
847ded71 | 787 | PUSHs(ix == 2 ? cchar(aTHX_ sv) : cstring(aTHX_ sv, (bool)ix)); |
a8a597b2 MB |
788 | |
789 | void | |
790 | threadsv_names() | |
791 | PPCODE: | |
f5ba1307 | 792 | |
a8a597b2 | 793 | |
a462fa00 DD |
794 | #ifdef USE_ITHREADS |
795 | void | |
796 | CLONE(...) | |
797 | PPCODE: | |
798 | PUTBACK; /* some vars go out of scope now in machine code */ | |
799 | { | |
800 | MY_CXT_CLONE; | |
801 | B_init_my_cxt(aTHX_ &(MY_CXT)); | |
802 | } | |
803 | return; /* dont execute another implied XSPP PUTBACK */ | |
9488fb36 | 804 | |
a462fa00 | 805 | #endif |
a9ed1a44 | 806 | |
fdbacc68 | 807 | MODULE = B PACKAGE = B::OP |
a8a597b2 | 808 | |
651aa52e | 809 | |
9b1961be NC |
810 | # The type checking code in B has always been identical for all OP types, |
811 | # irrespective of whether the action is actually defined on that OP. | |
812 | # We should fix this | |
086f9b42 | 813 | void |
9b1961be | 814 | next(o) |
a8a597b2 | 815 | B::OP o |
9b1961be | 816 | ALIAS: |
bec746fe DM |
817 | B::OP::next = 0 |
818 | B::OP::sibling = 1 | |
819 | B::OP::targ = 2 | |
820 | B::OP::flags = 3 | |
821 | B::OP::private = 4 | |
822 | B::UNOP::first = 5 | |
823 | B::BINOP::last = 6 | |
824 | B::LOGOP::other = 7 | |
825 | B::PMOP::pmreplstart = 8 | |
826 | B::LOOP::redoop = 9 | |
827 | B::LOOP::nextop = 10 | |
828 | B::LOOP::lastop = 11 | |
829 | B::PMOP::pmflags = 12 | |
830 | B::PMOP::code_list = 13 | |
831 | B::SVOP::sv = 14 | |
832 | B::SVOP::gv = 15 | |
833 | B::PADOP::padix = 16 | |
834 | B::COP::cop_seq = 17 | |
835 | B::COP::line = 18 | |
836 | B::COP::hints = 19 | |
837 | B::PMOP::pmoffset = 20 | |
838 | B::COP::filegv = 21 | |
839 | B::COP::file = 22 | |
840 | B::COP::stash = 23 | |
841 | B::COP::stashpv = 24 | |
842 | B::COP::stashoff = 25 | |
287ce0d8 DM |
843 | B::OP::size = 26 |
844 | B::OP::name = 27 | |
845 | B::OP::desc = 28 | |
846 | B::OP::ppaddr = 29 | |
847 | B::OP::type = 30 | |
848 | B::OP::opt = 31 | |
849 | B::OP::spare = 32 | |
850 | B::LISTOP::children = 33 | |
851 | B::PMOP::pmreplroot = 34 | |
852 | B::PMOP::pmstashpv = 35 | |
853 | B::PMOP::pmstash = 36 | |
854 | B::PMOP::precomp = 37 | |
855 | B::PMOP::reflags = 38 | |
856 | B::PADOP::sv = 39 | |
857 | B::PADOP::gv = 40 | |
858 | B::PVOP::pv = 41 | |
859 | B::COP::label = 42 | |
860 | B::COP::arybase = 43 | |
861 | B::COP::warnings = 44 | |
862 | B::COP::io = 45 | |
863 | B::COP::hints_hash = 46 | |
3164fde4 RU |
864 | B::OP::slabbed = 47 |
865 | B::OP::savefree = 48 | |
866 | B::OP::static = 49 | |
867 | B::OP::folded = 50 | |
87b5a8b9 | 868 | B::OP::moresib = 51 |
29e61fd9 | 869 | B::OP::parent = 52 |
b46e009d | 870 | B::METHOP::first = 53 |
871 | B::METHOP::meth_sv = 54 | |
429ba3b2 | 872 | B::PMOP::pmregexp = 55 |
810bd8b7 | 873 | B::METHOP::rclass = 56 |
9b1961be | 874 | PREINIT: |
086f9b42 NC |
875 | SV *ret; |
876 | PPCODE: | |
99639b5b | 877 | if (ix < 0 || (U32)ix >= C_ARRAY_LENGTH(op_methods)) |
287ce0d8 | 878 | croak("Illegal alias %d for B::*OP::next", (int)ix); |
71324a3b DM |
879 | ret = get_overlay_object(aTHX_ o, |
880 | op_methods[ix].name, op_methods[ix].namelen); | |
881 | if (ret) { | |
882 | ST(0) = ret; | |
883 | XSRETURN(1); | |
884 | } | |
bec746fe DM |
885 | |
886 | /* handle non-direct field access */ | |
887 | ||
0508288e | 888 | if (op_methods[ix].type == op_offset_special) |
bec746fe | 889 | switch (ix) { |
9d28cd7b | 890 | case 1: /* B::OP::op_sibling */ |
e6dae479 | 891 | ret = make_op_object(aTHX_ OpSIBLING(o)); |
1ed44841 DM |
892 | break; |
893 | ||
9d28cd7b | 894 | case 8: /* B::PMOP::pmreplstart */ |
2721a2ca DM |
895 | ret = make_op_object(aTHX_ |
896 | cPMOPo->op_type == OP_SUBST | |
897 | ? cPMOPo->op_pmstashstartu.op_pmreplstart | |
898 | : NULL | |
899 | ); | |
900 | break; | |
bec746fe | 901 | #ifdef USE_ITHREADS |
9d28cd7b | 902 | case 21: /* B::COP::filegv */ |
bec746fe DM |
903 | ret = make_sv_object(aTHX_ (SV *)CopFILEGV((COP*)o)); |
904 | break; | |
905 | #endif | |
1dc74fdb | 906 | #ifndef USE_ITHREADS |
9d28cd7b | 907 | case 22: /* B::COP::file */ |
bec746fe DM |
908 | ret = sv_2mortal(newSVpv(CopFILE((COP*)o), 0)); |
909 | break; | |
910 | #endif | |
911 | #ifdef USE_ITHREADS | |
9d28cd7b | 912 | case 23: /* B::COP::stash */ |
bec746fe DM |
913 | ret = make_sv_object(aTHX_ (SV *)CopSTASH((COP*)o)); |
914 | break; | |
915 | #endif | |
9d28cd7b | 916 | case 24: /* B::COP::stashpv */ |
bec746fe DM |
917 | ret = sv_2mortal(CopSTASH((COP*)o) |
918 | && SvTYPE(CopSTASH((COP*)o)) == SVt_PVHV | |
919 | ? newSVhek(HvNAME_HEK(CopSTASH((COP*)o))) | |
920 | : &PL_sv_undef); | |
bec746fe | 921 | break; |
9d28cd7b | 922 | case 26: /* B::OP::size */ |
1e85b658 | 923 | ret = sv_2mortal(newSVuv((UV)(opsizes[op_class(o)]))); |
287ce0d8 | 924 | break; |
9d28cd7b DM |
925 | case 27: /* B::OP::name */ |
926 | case 28: /* B::OP::desc */ | |
287ce0d8 DM |
927 | ret = sv_2mortal(newSVpv( |
928 | (char *)(ix == 28 ? OP_DESC(o) : OP_NAME(o)), 0)); | |
929 | break; | |
9d28cd7b | 930 | case 29: /* B::OP::ppaddr */ |
287ce0d8 DM |
931 | { |
932 | int i; | |
933 | ret = sv_2mortal(Perl_newSVpvf(aTHX_ "PL_ppaddr[OP_%s]", | |
934 | PL_op_name[o->op_type])); | |
935 | for (i=13; (STRLEN)i < SvCUR(ret); ++i) | |
936 | SvPVX(ret)[i] = toUPPER(SvPVX(ret)[i]); | |
937 | } | |
938 | break; | |
9d28cd7b DM |
939 | case 30: /* B::OP::type */ |
940 | case 31: /* B::OP::opt */ | |
941 | case 32: /* B::OP::spare */ | |
9d28cd7b DM |
942 | case 47: /* B::OP::slabbed */ |
943 | case 48: /* B::OP::savefree */ | |
944 | case 49: /* B::OP::static */ | |
9d28cd7b | 945 | case 50: /* B::OP::folded */ |
87b5a8b9 | 946 | case 51: /* B::OP::moresib */ |
3164fde4 | 947 | /* These are all bitfields, so we can't take their addresses */ |
287ce0d8 DM |
948 | ret = sv_2mortal(newSVuv((UV)( |
949 | ix == 30 ? o->op_type | |
950 | : ix == 31 ? o->op_opt | |
3164fde4 RU |
951 | : ix == 47 ? o->op_slabbed |
952 | : ix == 48 ? o->op_savefree | |
953 | : ix == 49 ? o->op_static | |
954 | : ix == 50 ? o->op_folded | |
87b5a8b9 | 955 | : ix == 51 ? o->op_moresib |
287ce0d8 DM |
956 | : o->op_spare))); |
957 | break; | |
9d28cd7b | 958 | case 33: /* B::LISTOP::children */ |
287ce0d8 DM |
959 | { |
960 | OP *kid; | |
961 | UV i = 0; | |
e6dae479 | 962 | for (kid = ((LISTOP*)o)->op_first; kid; kid = OpSIBLING(kid)) |
287ce0d8 DM |
963 | i++; |
964 | ret = sv_2mortal(newSVuv(i)); | |
965 | } | |
966 | break; | |
9d28cd7b | 967 | case 34: /* B::PMOP::pmreplroot */ |
5012eebe | 968 | if (cPMOPo->op_type == OP_SPLIT) { |
287ce0d8 | 969 | ret = sv_newmortal(); |
5012eebe DM |
970 | #ifndef USE_ITHREADS |
971 | if (o->op_private & OPpSPLIT_LEX) | |
972 | #endif | |
973 | sv_setiv(ret, cPMOPo->op_pmreplrootu.op_pmtargetoff); | |
974 | #ifndef USE_ITHREADS | |
975 | else { | |
976 | GV *const target = cPMOPo->op_pmreplrootu.op_pmtargetgv; | |
977 | sv_setiv(newSVrv(ret, target ? | |
978 | svclassnames[SvTYPE((SV*)target)] : "B::SV"), | |
979 | PTR2IV(target)); | |
980 | } | |
287ce0d8 DM |
981 | #endif |
982 | } | |
983 | else { | |
984 | OP *const root = cPMOPo->op_pmreplrootu.op_pmreplroot; | |
985 | ret = make_op_object(aTHX_ root); | |
986 | } | |
987 | break; | |
988 | #ifdef USE_ITHREADS | |
9d28cd7b | 989 | case 35: /* B::PMOP::pmstashpv */ |
287ce0d8 DM |
990 | ret = sv_2mortal(newSVpv(PmopSTASHPV(cPMOPo),0)); |
991 | break; | |
992 | #else | |
9d28cd7b | 993 | case 36: /* B::PMOP::pmstash */ |
287ce0d8 DM |
994 | ret = make_sv_object(aTHX_ (SV *) PmopSTASH(cPMOPo)); |
995 | break; | |
996 | #endif | |
9d28cd7b DM |
997 | case 37: /* B::PMOP::precomp */ |
998 | case 38: /* B::PMOP::reflags */ | |
287ce0d8 DM |
999 | { |
1000 | REGEXP *rx = PM_GETRE(cPMOPo); | |
1001 | ret = sv_newmortal(); | |
1002 | if (rx) { | |
1003 | if (ix==38) { | |
1004 | sv_setuv(ret, RX_EXTFLAGS(rx)); | |
1005 | } | |
1006 | else { | |
1007 | sv_setpvn(ret, RX_PRECOMP(rx), RX_PRELEN(rx)); | |
fea7fb25 DM |
1008 | if (RX_UTF8(rx)) |
1009 | SvUTF8_on(ret); | |
287ce0d8 DM |
1010 | } |
1011 | } | |
1012 | } | |
1013 | break; | |
3a23d767 DM |
1014 | case 39: /* B::PADOP::sv */ |
1015 | case 40: /* B::PADOP::gv */ | |
1016 | /* PADOPs should only be created on threaded builds. | |
1017 | * They don't have an sv or gv field, just an op_padix | |
1018 | * field. Leave it to the caller to retrieve padix | |
1019 | * and look up th value in the pad. Don't do it here, | |
1020 | * becuase PL_curpad is the pad of the caller, not the | |
1021 | * pad of the sub the op is part of */ | |
1022 | ret = make_sv_object(aTHX_ NULL); | |
287ce0d8 | 1023 | break; |
9d28cd7b | 1024 | case 41: /* B::PVOP::pv */ |
0b9a13c3 DM |
1025 | /* OP_TRANS uses op_pv to point to a OPtrans_map struct, |
1026 | * whereas other PVOPs point to a null terminated string. | |
1027 | * For trans, for now just return the whole struct as a | |
1028 | * string and let the caller unpack() it */ | |
c923a699 DM |
1029 | if ( cPVOPo->op_type == OP_TRANS |
1030 | || cPVOPo->op_type == OP_TRANSR) | |
1031 | { | |
0b9a13c3 | 1032 | const OPtrans_map *const tbl = (OPtrans_map*)cPVOPo->op_pv; |
c923a699 | 1033 | ret = newSVpvn_flags(cPVOPo->op_pv, |
0b9a13c3 DM |
1034 | (char*)(&tbl->map[tbl->size + 1]) |
1035 | - (char*)tbl, | |
c923a699 | 1036 | SVs_TEMP); |
287ce0d8 DM |
1037 | } |
1038 | else | |
1039 | ret = newSVpvn_flags(cPVOPo->op_pv, strlen(cPVOPo->op_pv), SVs_TEMP); | |
1040 | break; | |
9d28cd7b | 1041 | case 42: /* B::COP::label */ |
287ce0d8 DM |
1042 | ret = sv_2mortal(newSVpv(CopLABEL(cCOPo),0)); |
1043 | break; | |
9d28cd7b | 1044 | case 43: /* B::COP::arybase */ |
287ce0d8 DM |
1045 | ret = sv_2mortal(newSVuv(0)); |
1046 | break; | |
9d28cd7b | 1047 | case 44: /* B::COP::warnings */ |
287ce0d8 DM |
1048 | ret = make_warnings_object(aTHX_ cCOPo); |
1049 | break; | |
9d28cd7b | 1050 | case 45: /* B::COP::io */ |
287ce0d8 DM |
1051 | ret = make_cop_io_object(aTHX_ cCOPo); |
1052 | break; | |
9d28cd7b | 1053 | case 46: /* B::COP::hints_hash */ |
287ce0d8 DM |
1054 | ret = sv_newmortal(); |
1055 | sv_setiv(newSVrv(ret, "B::RHE"), | |
1056 | PTR2IV(CopHINTHASH_get(cCOPo))); | |
1057 | break; | |
9d28cd7b | 1058 | case 52: /* B::OP::parent */ |
1fafe688 | 1059 | #ifdef PERL_OP_PARENT |
29e61fd9 | 1060 | ret = make_op_object(aTHX_ op_parent(o)); |
1fafe688 DM |
1061 | #else |
1062 | ret = make_op_object(aTHX_ NULL); | |
1063 | #endif | |
29e61fd9 | 1064 | break; |
b46e009d | 1065 | case 53: /* B::METHOP::first */ |
1066 | /* METHOP struct has an op_first/op_meth_sv union | |
1067 | * as its first extra field. How to interpret the | |
1068 | * union depends on the op type. For the purposes of | |
1069 | * B, we treat it as a struct with both fields present, | |
1070 | * where one of the fields always happens to be null | |
1071 | * (i.e. we return NULL in preference to croaking with | |
1072 | * 'method not implemented'). | |
1073 | */ | |
1074 | ret = make_op_object(aTHX_ | |
1075 | o->op_type == OP_METHOD | |
1076 | ? cMETHOPx(o)->op_u.op_first : NULL); | |
1077 | break; | |
1078 | case 54: /* B::METHOP::meth_sv */ | |
1079 | /* see comment above about METHOP */ | |
1080 | ret = make_sv_object(aTHX_ | |
1081 | o->op_type == OP_METHOD | |
1082 | ? NULL : cMETHOPx(o)->op_u.op_meth_sv); | |
1083 | break; | |
429ba3b2 FC |
1084 | case 55: /* B::PMOP::pmregexp */ |
1085 | ret = make_sv_object(aTHX_ (SV *)PM_GETRE(cPMOPo)); | |
1086 | break; | |
810bd8b7 | 1087 | case 56: /* B::METHOP::rclass */ |
1088 | #ifdef USE_ITHREADS | |
1089 | ret = sv_2mortal(newSVuv( | |
1090 | (o->op_type == OP_METHOD_REDIR || | |
1091 | o->op_type == OP_METHOD_REDIR_SUPER) ? | |
1092 | cMETHOPx(o)->op_rclass_targ : 0 | |
1093 | )); | |
1094 | #else | |
1095 | ret = make_sv_object(aTHX_ | |
1096 | (o->op_type == OP_METHOD_REDIR || | |
1097 | o->op_type == OP_METHOD_REDIR_SUPER) ? | |
1098 | cMETHOPx(o)->op_rclass_sv : NULL | |
1099 | ); | |
1100 | #endif | |
1101 | break; | |
bec746fe DM |
1102 | default: |
1103 | croak("method %s not implemented", op_methods[ix].name); | |
0508288e NC |
1104 | } else { |
1105 | /* do a direct structure offset lookup */ | |
1106 | const char *const ptr = (char *)o + op_methods[ix].offset; | |
f68c0b4a NC |
1107 | switch (op_methods[ix].type) { |
1108 | case OPp: | |
1109 | ret = make_op_object(aTHX_ *((OP **)ptr)); | |
1110 | break; | |
1111 | case PADOFFSETp: | |
1112 | ret = sv_2mortal(newSVuv(*((PADOFFSET*)ptr))); | |
1113 | break; | |
1114 | case U8p: | |
1115 | ret = sv_2mortal(newSVuv(*((U8*)ptr))); | |
1116 | break; | |
1117 | case U32p: | |
1118 | ret = sv_2mortal(newSVuv(*((U32*)ptr))); | |
1119 | break; | |
1120 | case SVp: | |
1121 | ret = make_sv_object(aTHX_ *((SV **)ptr)); | |
1122 | break; | |
1123 | case line_tp: | |
1124 | ret = sv_2mortal(newSVuv(*((line_t *)ptr))); | |
1125 | break; | |
1126 | case IVp: | |
1127 | ret = sv_2mortal(newSViv(*((IV*)ptr))); | |
1128 | break; | |
1129 | case char_pp: | |
1130 | ret = sv_2mortal(newSVpv(*((char **)ptr), 0)); | |
1131 | break; | |
1132 | default: | |
0508288e | 1133 | croak("Illegal type 0x%x for B::*OP::%s", |
f68c0b4a | 1134 | (unsigned)op_methods[ix].type, op_methods[ix].name); |
0508288e | 1135 | } |
086f9b42 NC |
1136 | } |
1137 | ST(0) = ret; | |
1138 | XSRETURN(1); | |
a8a597b2 | 1139 | |
7252851f | 1140 | |
1df34986 | 1141 | void |
fdbacc68 | 1142 | oplist(o) |
1df34986 AE |
1143 | B::OP o |
1144 | PPCODE: | |
1145 | SP = oplist(aTHX_ o, SP); | |
1146 | ||
e412117e | 1147 | |
2f7c6295 DM |
1148 | |
1149 | MODULE = B PACKAGE = B::UNOP_AUX | |
1150 | ||
1151 | # UNOP_AUX class ops are like UNOPs except that they have an extra | |
1152 | # op_aux pointer that points to an array of UNOP_AUX_item unions. | |
1153 | # Element -1 of the array contains the length | |
1154 | ||
1155 | ||
1156 | # return a string representation of op_aux where possible The op's CV is | |
1157 | # needed as an extra arg to allow GVs and SVs moved into the pad to be | |
1158 | # accessed okay. | |
1159 | ||
1160 | void | |
1161 | string(o, cv) | |
1162 | B::OP o | |
1163 | B::CV cv | |
1164 | PREINIT: | |
1165 | SV *ret; | |
4fa06845 | 1166 | UNOP_AUX_item *aux; |
2f7c6295 | 1167 | PPCODE: |
4fa06845 | 1168 | aux = cUNOP_AUXo->op_aux; |
2f7c6295 | 1169 | switch (o->op_type) { |
e839e6ed DM |
1170 | case OP_MULTICONCAT: |
1171 | ret = multiconcat_stringify(o); | |
1172 | break; | |
1173 | ||
fedf30e1 | 1174 | case OP_MULTIDEREF: |
48ee9c0e | 1175 | ret = multideref_stringify(o, cv); |
fedf30e1 | 1176 | break; |
4fa06845 DM |
1177 | |
1178 | case OP_ARGELEM: | |
147e3846 | 1179 | ret = sv_2mortal(Perl_newSVpvf(aTHX_ "%" IVdf, |
6daeaaa3 | 1180 | PTR2IV(aux))); |
4fa06845 DM |
1181 | break; |
1182 | ||
1183 | case OP_ARGCHECK: | |
147e3846 | 1184 | ret = Perl_newSVpvf(aTHX_ "%" IVdf ",%" IVdf, aux[0].iv, aux[1].iv); |
4fa06845 DM |
1185 | if (aux[2].iv) |
1186 | Perl_sv_catpvf(aTHX_ ret, ",%c", (char)aux[2].iv); | |
1187 | ret = sv_2mortal(ret); | |
1188 | break; | |
1189 | ||
2f7c6295 DM |
1190 | default: |
1191 | ret = sv_2mortal(newSVpvn("", 0)); | |
1192 | } | |
4fa06845 | 1193 | |
2f7c6295 DM |
1194 | ST(0) = ret; |
1195 | XSRETURN(1); | |
1196 | ||
1197 | ||
1198 | # Return the contents of the op_aux array as a list of IV/GV/etc objects. | |
1199 | # How to interpret each array element is op-dependent. The op's CV is | |
1200 | # needed as an extra arg to allow GVs and SVs which have been moved into | |
1201 | # the pad to be accessed okay. | |
1202 | ||
1203 | void | |
1204 | aux_list(o, cv) | |
1205 | B::OP o | |
1206 | B::CV cv | |
4fa06845 DM |
1207 | PREINIT: |
1208 | UNOP_AUX_item *aux; | |
2f7c6295 | 1209 | PPCODE: |
fedf30e1 | 1210 | PERL_UNUSED_VAR(cv); /* not needed on unthreaded builds */ |
4fa06845 | 1211 | aux = cUNOP_AUXo->op_aux; |
2f7c6295 DM |
1212 | switch (o->op_type) { |
1213 | default: | |
1214 | XSRETURN(0); /* by default, an empty list */ | |
fedf30e1 | 1215 | |
4fa06845 | 1216 | case OP_ARGELEM: |
6daeaaa3 | 1217 | XPUSHs(sv_2mortal(newSViv(PTR2IV(aux)))); |
4fa06845 DM |
1218 | XSRETURN(1); |
1219 | break; | |
1220 | ||
1221 | case OP_ARGCHECK: | |
1222 | EXTEND(SP, 3); | |
6daeaaa3 DM |
1223 | PUSHs(sv_2mortal(newSViv(aux[0].iv))); |
1224 | PUSHs(sv_2mortal(newSViv(aux[1].iv))); | |
4fa06845 DM |
1225 | PUSHs(sv_2mortal(aux[2].iv ? Perl_newSVpvf(aTHX_ "%c", |
1226 | (char)aux[2].iv) : &PL_sv_no)); | |
1227 | break; | |
1228 | ||
e839e6ed DM |
1229 | case OP_MULTICONCAT: |
1230 | { | |
ca84e88e | 1231 | SSize_t nargs; |
e839e6ed DM |
1232 | char *p; |
1233 | STRLEN len; | |
1234 | U32 utf8 = 0; | |
1235 | SV *sv; | |
1236 | UNOP_AUX_item *lens; | |
1237 | ||
1238 | /* return (nargs, const string, segment len 0, 1, 2, ...) */ | |
1239 | ||
1240 | /* if this changes, this block of code probably needs fixing */ | |
1241 | assert(PERL_MULTICONCAT_HEADER_SIZE == 5); | |
ca84e88e | 1242 | nargs = aux[PERL_MULTICONCAT_IX_NARGS].ssize; |
e839e6ed | 1243 | EXTEND(SP, ((SSize_t)(2 + (nargs+1)))); |
ca84e88e | 1244 | PUSHs(sv_2mortal(newSViv((IV)nargs))); |
e839e6ed DM |
1245 | |
1246 | p = aux[PERL_MULTICONCAT_IX_PLAIN_PV].pv; | |
b5bf9f73 | 1247 | len = aux[PERL_MULTICONCAT_IX_PLAIN_LEN].ssize; |
e839e6ed DM |
1248 | if (!p) { |
1249 | p = aux[PERL_MULTICONCAT_IX_UTF8_PV].pv; | |
b5bf9f73 | 1250 | len = aux[PERL_MULTICONCAT_IX_UTF8_LEN].ssize; |
e839e6ed DM |
1251 | utf8 = SVf_UTF8; |
1252 | } | |
1253 | sv = newSVpvn(p, len); | |
1254 | SvFLAGS(sv) |= utf8; | |
1255 | PUSHs(sv_2mortal(sv)); | |
1256 | ||
1257 | lens = aux + PERL_MULTICONCAT_IX_LENGTHS; | |
1258 | nargs++; /* loop (nargs+1) times */ | |
1259 | if (utf8) { | |
1260 | U8 *p = (U8*)SvPVX(sv); | |
1261 | while (nargs--) { | |
b5bf9f73 | 1262 | SSize_t bytes = lens->ssize; |
e839e6ed DM |
1263 | SSize_t chars; |
1264 | if (bytes <= 0) | |
1265 | chars = bytes; | |
1266 | else { | |
1267 | /* return char lengths rather than byte lengths */ | |
1268 | chars = utf8_length(p, p + bytes); | |
1269 | p += bytes; | |
1270 | } | |
1271 | lens++; | |
1272 | PUSHs(sv_2mortal(newSViv(chars))); | |
1273 | } | |
1274 | } | |
1275 | else { | |
1276 | while (nargs--) { | |
b5bf9f73 | 1277 | PUSHs(sv_2mortal(newSViv(lens->ssize))); |
e839e6ed DM |
1278 | lens++; |
1279 | } | |
1280 | } | |
1281 | break; | |
1282 | } | |
1283 | ||
fedf30e1 DM |
1284 | case OP_MULTIDEREF: |
1285 | #ifdef USE_ITHREADS | |
1286 | # define ITEM_SV(item) *av_fetch(comppad, (item)->pad_offset, FALSE); | |
1287 | #else | |
1288 | # define ITEM_SV(item) UNOP_AUX_item_sv(item) | |
1289 | #endif | |
1290 | { | |
1291 | UNOP_AUX_item *items = cUNOP_AUXo->op_aux; | |
1292 | UV actions = items->uv; | |
1293 | UV len = items[-1].uv; | |
1294 | SV *sv; | |
1295 | bool last = 0; | |
1296 | bool is_hash = FALSE; | |
1297 | #ifdef USE_ITHREADS | |
1298 | PADLIST * const padlist = CvPADLIST(cv); | |
9cdf4efd | 1299 | PAD *comppad = PadlistARRAY(padlist)[1]; |
fedf30e1 DM |
1300 | #endif |
1301 | ||
052a7c76 DM |
1302 | /* len should never be big enough to truncate or wrap */ |
1303 | assert(len <= SSize_t_MAX); | |
1304 | EXTEND(SP, (SSize_t)len); | |
fedf30e1 DM |
1305 | PUSHs(sv_2mortal(newSViv(actions))); |
1306 | ||
1307 | while (!last) { | |
1308 | switch (actions & MDEREF_ACTION_MASK) { | |
1309 | ||
1310 | case MDEREF_reload: | |
1311 | actions = (++items)->uv; | |
1312 | PUSHs(sv_2mortal(newSVuv(actions))); | |
1313 | continue; | |
2b5060ae | 1314 | NOT_REACHED; /* NOTREACHED */ |
fedf30e1 DM |
1315 | |
1316 | case MDEREF_HV_padhv_helem: | |
1317 | is_hash = TRUE; | |
2b5060ae | 1318 | /* FALLTHROUGH */ |
fedf30e1 DM |
1319 | case MDEREF_AV_padav_aelem: |
1320 | PUSHs(sv_2mortal(newSVuv((++items)->pad_offset))); | |
1321 | goto do_elem; | |
2b5060ae | 1322 | NOT_REACHED; /* NOTREACHED */ |
fedf30e1 DM |
1323 | |
1324 | case MDEREF_HV_gvhv_helem: | |
1325 | is_hash = TRUE; | |
2b5060ae | 1326 | /* FALLTHROUGH */ |
fedf30e1 DM |
1327 | case MDEREF_AV_gvav_aelem: |
1328 | sv = ITEM_SV(++items); | |
1329 | PUSHs(make_sv_object(aTHX_ sv)); | |
1330 | goto do_elem; | |
2b5060ae | 1331 | NOT_REACHED; /* NOTREACHED */ |
fedf30e1 DM |
1332 | |
1333 | case MDEREF_HV_gvsv_vivify_rv2hv_helem: | |
1334 | is_hash = TRUE; | |
2b5060ae | 1335 | /* FALLTHROUGH */ |
fedf30e1 DM |
1336 | case MDEREF_AV_gvsv_vivify_rv2av_aelem: |
1337 | sv = ITEM_SV(++items); | |
1338 | PUSHs(make_sv_object(aTHX_ sv)); | |
1339 | goto do_vivify_rv2xv_elem; | |
2b5060ae | 1340 | NOT_REACHED; /* NOTREACHED */ |
fedf30e1 DM |
1341 | |
1342 | case MDEREF_HV_padsv_vivify_rv2hv_helem: | |
1343 | is_hash = TRUE; | |
2b5060ae | 1344 | /* FALLTHROUGH */ |
fedf30e1 DM |
1345 | case MDEREF_AV_padsv_vivify_rv2av_aelem: |
1346 | PUSHs(sv_2mortal(newSVuv((++items)->pad_offset))); | |
1347 | goto do_vivify_rv2xv_elem; | |
2b5060ae | 1348 | NOT_REACHED; /* NOTREACHED */ |
fedf30e1 DM |
1349 | |
1350 | case MDEREF_HV_pop_rv2hv_helem: | |
1351 | case MDEREF_HV_vivify_rv2hv_helem: | |
1352 | is_hash = TRUE; | |
2b5060ae | 1353 | /* FALLTHROUGH */ |
fedf30e1 DM |
1354 | do_vivify_rv2xv_elem: |
1355 | case MDEREF_AV_pop_rv2av_aelem: | |
1356 | case MDEREF_AV_vivify_rv2av_aelem: | |
1357 | do_elem: | |
1358 | switch (actions & MDEREF_INDEX_MASK) { | |
1359 | case MDEREF_INDEX_none: | |
1360 | last = 1; | |
1361 | break; | |
1362 | case MDEREF_INDEX_const: | |
1363 | if (is_hash) { | |
1364 | sv = ITEM_SV(++items); | |
1365 | PUSHs(make_sv_object(aTHX_ sv)); | |
1366 | } | |
1367 | else | |
1368 | PUSHs(sv_2mortal(newSViv((++items)->iv))); | |
1369 | break; | |
1370 | case MDEREF_INDEX_padsv: | |
1371 | PUSHs(sv_2mortal(newSVuv((++items)->pad_offset))); | |
1372 | break; | |
1373 | case MDEREF_INDEX_gvsv: | |
1374 | sv = ITEM_SV(++items); | |
1375 | PUSHs(make_sv_object(aTHX_ sv)); | |
1376 | break; | |
1377 | } | |
1378 | if (actions & MDEREF_FLAG_last) | |
1379 | last = 1; | |
1380 | is_hash = FALSE; | |
1381 | ||
1382 | break; | |
1383 | } /* switch */ | |
1384 | ||
1385 | actions >>= MDEREF_SHIFT; | |
1386 | } /* while */ | |
1387 | XSRETURN(len); | |
1388 | ||
1389 | } /* OP_MULTIDEREF */ | |
2f7c6295 DM |
1390 | } /* switch */ |
1391 | ||
1392 | ||
1393 | ||
651aa52e AE |
1394 | MODULE = B PACKAGE = B::SV |
1395 | ||
de64752d NC |
1396 | #define MAGICAL_FLAG_BITS (SVs_GMG|SVs_SMG|SVs_RMG) |
1397 | ||
651aa52e | 1398 | U32 |
de64752d | 1399 | REFCNT(sv) |
651aa52e | 1400 | B::SV sv |
de64752d NC |
1401 | ALIAS: |
1402 | FLAGS = 0xFFFFFFFF | |
1403 | SvTYPE = SVTYPEMASK | |
1404 | POK = SVf_POK | |
1405 | ROK = SVf_ROK | |
1406 | MAGICAL = MAGICAL_FLAG_BITS | |
1407 | CODE: | |
1408 | RETVAL = ix ? (SvFLAGS(sv) & (U32)ix) : SvREFCNT(sv); | |
1409 | OUTPUT: | |
1410 | RETVAL | |
651aa52e | 1411 | |
9efba5c8 | 1412 | void |
429a5ce7 SM |
1413 | object_2svref(sv) |
1414 | B::SV sv | |
9efba5c8 NC |
1415 | PPCODE: |
1416 | ST(0) = sv_2mortal(newRV(sv)); | |
1417 | XSRETURN(1); | |
1418 | ||
a8a597b2 MB |
1419 | MODULE = B PACKAGE = B::IV PREFIX = Sv |
1420 | ||
1421 | IV | |
1422 | SvIV(sv) | |
1423 | B::IV sv | |
1424 | ||
e4da9d6a | 1425 | MODULE = B PACKAGE = B::IV |
a8a597b2 | 1426 | |
e4da9d6a NC |
1427 | #define sv_SVp 0x00000 |
1428 | #define sv_IVp 0x10000 | |
1429 | #define sv_UVp 0x20000 | |
1430 | #define sv_STRLENp 0x30000 | |
1431 | #define sv_U32p 0x40000 | |
1432 | #define sv_U8p 0x50000 | |
1433 | #define sv_char_pp 0x60000 | |
1434 | #define sv_NVp 0x70000 | |
6782c6e0 | 1435 | #define sv_char_p 0x80000 |
3da43c35 | 1436 | #define sv_SSize_tp 0x90000 |
ffc5d9fc NC |
1437 | #define sv_I32p 0xA0000 |
1438 | #define sv_U16p 0xB0000 | |
e4da9d6a | 1439 | |
3800c318 JH |
1440 | #define IV_ivx_ix sv_IVp | STRUCT_OFFSET(struct xpviv, xiv_iv) |
1441 | #define IV_uvx_ix sv_UVp | STRUCT_OFFSET(struct xpvuv, xuv_uv) | |
1442 | #define NV_nvx_ix sv_NVp | STRUCT_OFFSET(struct xpvnv, xnv_u.xnv_nv) | |
e4da9d6a | 1443 | |
3800c318 JH |
1444 | #define PV_cur_ix sv_STRLENp | STRUCT_OFFSET(struct xpv, xpv_cur) |
1445 | #define PV_len_ix sv_STRLENp | STRUCT_OFFSET(struct xpv, xpv_len) | |
6782c6e0 | 1446 | |
3800c318 | 1447 | #define PVMG_stash_ix sv_SVp | STRUCT_OFFSET(struct xpvmg, xmg_stash) |
6782c6e0 | 1448 | |
9ca4b7ea | 1449 | #define PVBM_useful_ix sv_IVp | STRUCT_OFFSET(struct xpviv, xiv_u.xivu_iv) |
91a71e08 | 1450 | |
3800c318 JH |
1451 | #define PVLV_targoff_ix sv_U32p | STRUCT_OFFSET(struct xpvlv, xlv_targoff) |
1452 | #define PVLV_targlen_ix sv_U32p | STRUCT_OFFSET(struct xpvlv, xlv_targlen) | |
1453 | #define PVLV_targ_ix sv_SVp | STRUCT_OFFSET(struct xpvlv, xlv_targ) | |
1454 | #define PVLV_type_ix sv_char_p | STRUCT_OFFSET(struct xpvlv, xlv_type) | |
1455 | ||
1456 | #define PVGV_stash_ix sv_SVp | STRUCT_OFFSET(struct xpvgv, xnv_u.xgv_stash) | |
1457 | #define PVGV_flags_ix sv_STRLENp | STRUCT_OFFSET(struct xpvgv, xpv_cur) | |
1458 | #define PVIO_lines_ix sv_IVp | STRUCT_OFFSET(struct xpvio, xiv_iv) | |
1459 | ||
1460 | #define PVIO_page_ix sv_IVp | STRUCT_OFFSET(struct xpvio, xio_page) | |
1461 | #define PVIO_page_len_ix sv_IVp | STRUCT_OFFSET(struct xpvio, xio_page_len) | |
1462 | #define PVIO_lines_left_ix sv_IVp | STRUCT_OFFSET(struct xpvio, xio_lines_left) | |
1463 | #define PVIO_top_name_ix sv_char_pp | STRUCT_OFFSET(struct xpvio, xio_top_name) | |
1464 | #define PVIO_top_gv_ix sv_SVp | STRUCT_OFFSET(struct xpvio, xio_top_gv) | |
1465 | #define PVIO_fmt_name_ix sv_char_pp | STRUCT_OFFSET(struct xpvio, xio_fmt_name) | |
1466 | #define PVIO_fmt_gv_ix sv_SVp | STRUCT_OFFSET(struct xpvio, xio_fmt_gv) | |
1467 | #define PVIO_bottom_name_ix sv_char_pp | STRUCT_OFFSET(struct xpvio, xio_bottom_name) | |
1468 | #define PVIO_bottom_gv_ix sv_SVp | STRUCT_OFFSET(struct xpvio, xio_bottom_gv) | |
1469 | #define PVIO_type_ix sv_char_p | STRUCT_OFFSET(struct xpvio, xio_type) | |
1470 | #define PVIO_flags_ix sv_U8p | STRUCT_OFFSET(struct xpvio, xio_flags) | |
1471 | ||
1472 | #define PVAV_max_ix sv_SSize_tp | STRUCT_OFFSET(struct xpvav, xav_max) | |
1473 | ||
1474 | #define PVCV_stash_ix sv_SVp | STRUCT_OFFSET(struct xpvcv, xcv_stash) | |
9ca4b7ea | 1475 | #define PVCV_gv_ix sv_SVp | STRUCT_OFFSET(struct xpvcv, xcv_gv_u.xcv_gv) |
3800c318 JH |
1476 | #define PVCV_file_ix sv_char_pp | STRUCT_OFFSET(struct xpvcv, xcv_file) |
1477 | #define PVCV_outside_ix sv_SVp | STRUCT_OFFSET(struct xpvcv, xcv_outside) | |
1478 | #define PVCV_outside_seq_ix sv_U32p | STRUCT_OFFSET(struct xpvcv, xcv_outside_seq) | |
1479 | #define PVCV_flags_ix sv_U32p | STRUCT_OFFSET(struct xpvcv, xcv_flags) | |
ffc5d9fc | 1480 | |
3800c318 | 1481 | #define PVHV_max_ix sv_STRLENp | STRUCT_OFFSET(struct xpvhv, xhv_max) |
3800c318 | 1482 | #define PVHV_keys_ix sv_STRLENp | STRUCT_OFFSET(struct xpvhv, xhv_keys) |
d65a2b0a | 1483 | |
e4da9d6a NC |
1484 | # The type checking code in B has always been identical for all SV types, |
1485 | # irrespective of whether the action is actually defined on that SV. | |
1486 | # We should fix this | |
1487 | void | |
1488 | IVX(sv) | |
1489 | B::SV sv | |
1490 | ALIAS: | |
1491 | B::IV::IVX = IV_ivx_ix | |
1492 | B::IV::UVX = IV_uvx_ix | |
1493 | B::NV::NVX = NV_nvx_ix | |
6782c6e0 NC |
1494 | B::PV::CUR = PV_cur_ix |
1495 | B::PV::LEN = PV_len_ix | |
1496 | B::PVMG::SvSTASH = PVMG_stash_ix | |
1497 | B::PVLV::TARGOFF = PVLV_targoff_ix | |
1498 | B::PVLV::TARGLEN = PVLV_targlen_ix | |
1499 | B::PVLV::TARG = PVLV_targ_ix | |
1500 | B::PVLV::TYPE = PVLV_type_ix | |
f1f19364 NC |
1501 | B::GV::STASH = PVGV_stash_ix |
1502 | B::GV::GvFLAGS = PVGV_flags_ix | |
91a71e08 | 1503 | B::BM::USEFUL = PVBM_useful_ix |
55440d31 NC |
1504 | B::IO::LINES = PVIO_lines_ix |
1505 | B::IO::PAGE = PVIO_page_ix | |
1506 | B::IO::PAGE_LEN = PVIO_page_len_ix | |
1507 | B::IO::LINES_LEFT = PVIO_lines_left_ix | |
1508 | B::IO::TOP_NAME = PVIO_top_name_ix | |
1509 | B::IO::TOP_GV = PVIO_top_gv_ix | |
1510 | B::IO::FMT_NAME = PVIO_fmt_name_ix | |
1511 | B::IO::FMT_GV = PVIO_fmt_gv_ix | |
1512 | B::IO::BOTTOM_NAME = PVIO_bottom_name_ix | |
1513 | B::IO::BOTTOM_GV = PVIO_bottom_gv_ix | |
1514 | B::IO::IoTYPE = PVIO_type_ix | |
1515 | B::IO::IoFLAGS = PVIO_flags_ix | |
3da43c35 | 1516 | B::AV::MAX = PVAV_max_ix |
ffc5d9fc | 1517 | B::CV::STASH = PVCV_stash_ix |
ffc5d9fc | 1518 | B::CV::FILE = PVCV_file_ix |
ffc5d9fc NC |
1519 | B::CV::OUTSIDE = PVCV_outside_ix |
1520 | B::CV::OUTSIDE_SEQ = PVCV_outside_seq_ix | |
1521 | B::CV::CvFLAGS = PVCV_flags_ix | |
d65a2b0a NC |
1522 | B::HV::MAX = PVHV_max_ix |
1523 | B::HV::KEYS = PVHV_keys_ix | |
e4da9d6a NC |
1524 | PREINIT: |
1525 | char *ptr; | |
1526 | SV *ret; | |
1527 | PPCODE: | |
1528 | ptr = (ix & 0xFFFF) + (char *)SvANY(sv); | |
1529 | switch ((U8)(ix >> 16)) { | |
1530 | case (U8)(sv_SVp >> 16): | |
428744c7 | 1531 | ret = make_sv_object(aTHX_ *((SV **)ptr)); |
e4da9d6a NC |
1532 | break; |
1533 | case (U8)(sv_IVp >> 16): | |
1534 | ret = sv_2mortal(newSViv(*((IV *)ptr))); | |
1535 | break; | |
1536 | case (U8)(sv_UVp >> 16): | |
1537 | ret = sv_2mortal(newSVuv(*((UV *)ptr))); | |
1538 | break; | |
6782c6e0 NC |
1539 | case (U8)(sv_STRLENp >> 16): |
1540 | ret = sv_2mortal(newSVuv(*((STRLEN *)ptr))); | |
1541 | break; | |
e4da9d6a NC |
1542 | case (U8)(sv_U32p >> 16): |
1543 | ret = sv_2mortal(newSVuv(*((U32 *)ptr))); | |
1544 | break; | |
1545 | case (U8)(sv_U8p >> 16): | |
1546 | ret = sv_2mortal(newSVuv(*((U8 *)ptr))); | |
1547 | break; | |
1548 | case (U8)(sv_char_pp >> 16): | |
1549 | ret = sv_2mortal(newSVpv(*((char **)ptr), 0)); | |
1550 | break; | |
1551 | case (U8)(sv_NVp >> 16): | |
1552 | ret = sv_2mortal(newSVnv(*((NV *)ptr))); | |
1553 | break; | |
6782c6e0 NC |
1554 | case (U8)(sv_char_p >> 16): |
1555 | ret = newSVpvn_flags((char *)ptr, 1, SVs_TEMP); | |
1556 | break; | |
3da43c35 NC |
1557 | case (U8)(sv_SSize_tp >> 16): |
1558 | ret = sv_2mortal(newSViv(*((SSize_t *)ptr))); | |
1559 | break; | |
ffc5d9fc NC |
1560 | case (U8)(sv_I32p >> 16): |
1561 | ret = sv_2mortal(newSVuv(*((I32 *)ptr))); | |
1562 | break; | |
1563 | case (U8)(sv_U16p >> 16): | |
1564 | ret = sv_2mortal(newSVuv(*((U16 *)ptr))); | |
1565 | break; | |
c33e8be1 Z |
1566 | default: |
1567 | croak("Illegal alias 0x%08x for B::*IVX", (unsigned)ix); | |
e4da9d6a NC |
1568 | } |
1569 | ST(0) = ret; | |
1570 | XSRETURN(1); | |
a8a597b2 | 1571 | |
a8a597b2 MB |
1572 | void |
1573 | packiv(sv) | |
1574 | B::IV sv | |
6829f5e2 NC |
1575 | ALIAS: |
1576 | needs64bits = 1 | |
a8a597b2 | 1577 | CODE: |
6829f5e2 NC |
1578 | if (ix) { |
1579 | ST(0) = boolSV((I32)SvIVX(sv) != SvIVX(sv)); | |
1580 | } else if (sizeof(IV) == 8) { | |
a8a597b2 | 1581 | U32 wp[2]; |
5d7488b2 | 1582 | const IV iv = SvIVX(sv); |
a8a597b2 MB |
1583 | /* |
1584 | * The following way of spelling 32 is to stop compilers on | |
1585 | * 32-bit architectures from moaning about the shift count | |
1586 | * being >= the width of the type. Such architectures don't | |
1587 | * reach this code anyway (unless sizeof(IV) > 8 but then | |
1588 | * everything else breaks too so I'm not fussed at the moment). | |
1589 | */ | |
42718184 RB |
1590 | #ifdef UV_IS_QUAD |
1591 | wp[0] = htonl(((UV)iv) >> (sizeof(UV)*4)); | |
1592 | #else | |
1593 | wp[0] = htonl(((U32)iv) >> (sizeof(UV)*4)); | |
1594 | #endif | |
a8a597b2 | 1595 | wp[1] = htonl(iv & 0xffffffff); |
d3d34884 | 1596 | ST(0) = newSVpvn_flags((char *)wp, 8, SVs_TEMP); |
a8a597b2 MB |
1597 | } else { |
1598 | U32 w = htonl((U32)SvIVX(sv)); | |
d3d34884 | 1599 | ST(0) = newSVpvn_flags((char *)&w, 4, SVs_TEMP); |
a8a597b2 MB |
1600 | } |
1601 | ||
1602 | MODULE = B PACKAGE = B::NV PREFIX = Sv | |
1603 | ||
76ef7183 | 1604 | NV |
a8a597b2 MB |
1605 | SvNV(sv) |
1606 | B::NV sv | |
1607 | ||
89c6bc13 NC |
1608 | MODULE = B PACKAGE = B::REGEXP |
1609 | ||
154b8842 | 1610 | void |
81e413dd | 1611 | REGEX(sv) |
89c6bc13 | 1612 | B::REGEXP sv |
81e413dd NC |
1613 | ALIAS: |
1614 | precomp = 1 | |
6190dd99 | 1615 | qr_anoncv = 2 |
1f306347 | 1616 | compflags = 3 |
154b8842 | 1617 | PPCODE: |
6190dd99 | 1618 | if (ix == 1) { |
81e413dd | 1619 | PUSHs(newSVpvn_flags(RX_PRECOMP(sv), RX_PRELEN(sv), SVs_TEMP)); |
1f306347 | 1620 | } else if (ix == 2) { |
6190dd99 | 1621 | PUSHs(make_sv_object(aTHX_ (SV *)ReANY(sv)->qr_anoncv)); |
81e413dd NC |
1622 | } else { |
1623 | dXSTARG; | |
17d6506d DD |
1624 | if (ix) |
1625 | PUSHu(RX_COMPFLAGS(sv)); | |
1626 | else | |
81e413dd | 1627 | /* FIXME - can we code this method more efficiently? */ |
17d6506d | 1628 | PUSHi(PTR2IV(sv)); |
81e413dd | 1629 | } |
89c6bc13 | 1630 | |
fdbacc68 | 1631 | MODULE = B PACKAGE = B::PV |
a8a597b2 | 1632 | |
8ae5a962 | 1633 | void |
fdbacc68 | 1634 | RV(sv) |
b326da91 | 1635 | B::PV sv |
8ae5a962 NC |
1636 | PPCODE: |
1637 | if (!SvROK(sv)) | |
b326da91 | 1638 | croak( "argument is not SvROK" ); |
0c74f67f | 1639 | PUSHs(make_sv_object(aTHX_ SvRV(sv))); |
b326da91 | 1640 | |
a8a597b2 | 1641 | void |
fdbacc68 | 1642 | PV(sv) |
a8a597b2 | 1643 | B::PV sv |
3d665704 NC |
1644 | ALIAS: |
1645 | PVX = 1 | |
f4c36584 | 1646 | PVBM = 2 |
84fea184 | 1647 | B::BM::TABLE = 3 |
a804b0fe NC |
1648 | PREINIT: |
1649 | const char *p; | |
1650 | STRLEN len = 0; | |
1651 | U32 utf8 = 0; | |
a8a597b2 | 1652 | CODE: |
84fea184 | 1653 | if (ix == 3) { |
2bda37ba NC |
1654 | const MAGIC *const mg = mg_find(sv, PERL_MAGIC_bm); |
1655 | ||
1656 | if (!mg) | |
1657 | croak("argument to B::BM::TABLE is not a PVBM"); | |
1658 | p = mg->mg_ptr; | |
1659 | len = mg->mg_len; | |
84fea184 | 1660 | } else if (ix == 2) { |
f4c36584 | 1661 | /* This used to read 257. I think that that was buggy - should have |
26ec7981 NC |
1662 | been 258. (The "\0", the flags byte, and 256 for the table.) |
1663 | The only user of this method is B::Bytecode in B::PV::bsave. | |
1664 | I'm guessing that nothing tested the runtime correctness of | |
1665 | output of bytecompiled string constant arguments to index (etc). | |
1666 | ||
1667 | Note the start pointer is and has always been SvPVX(sv), not | |
1668 | SvPVX(sv) + SvCUR(sv) PVBM was added in 651aa52ea1faa806, and | |
1669 | first used by the compiler in 651aa52ea1faa806. It's used to | |
1670 | get a "complete" dump of the buffer at SvPVX(), not just the | |
1671 | PVBM table. This permits the generated bytecode to "load" | |
2bda37ba NC |
1672 | SvPVX in "one" hit. |
1673 | ||
1674 | 5.15 and later store the BM table via MAGIC, so the compiler | |
1675 | should handle this just fine without changes if PVBM now | |
1676 | always returns the SvPVX() buffer. */ | |
8d919b0a FC |
1677 | p = isREGEXP(sv) |
1678 | ? RX_WRAPPED_const((REGEXP*)sv) | |
1679 | : SvPVX_const(sv); | |
2bda37ba | 1680 | len = SvCUR(sv); |
f4c36584 | 1681 | } else if (ix) { |
8d919b0a | 1682 | p = isREGEXP(sv) ? RX_WRAPPED((REGEXP*)sv) : SvPVX(sv); |
3d665704 NC |
1683 | len = strlen(p); |
1684 | } else if (SvPOK(sv)) { | |
a804b0fe NC |
1685 | len = SvCUR(sv); |
1686 | p = SvPVX_const(sv); | |
1687 | utf8 = SvUTF8(sv); | |
eb32218e | 1688 | } else if (isREGEXP(sv)) { |
8d919b0a FC |
1689 | len = SvCUR(sv); |
1690 | p = RX_WRAPPED_const((REGEXP*)sv); | |
1691 | utf8 = SvUTF8(sv); | |
eb32218e | 1692 | } else { |
b326da91 MB |
1693 | /* XXX for backward compatibility, but should fail */ |
1694 | /* croak( "argument is not SvPOK" ); */ | |
a804b0fe | 1695 | p = NULL; |
b326da91 | 1696 | } |
a804b0fe | 1697 | ST(0) = newSVpvn_flags(p, len, SVs_TEMP | utf8); |
a8a597b2 | 1698 | |
fdbacc68 | 1699 | MODULE = B PACKAGE = B::PVMG |
a8a597b2 MB |
1700 | |
1701 | void | |
fdbacc68 | 1702 | MAGIC(sv) |
a8a597b2 MB |
1703 | B::PVMG sv |
1704 | MAGIC * mg = NO_INIT | |
1705 | PPCODE: | |
1706 | for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) | |
9496d2e5 | 1707 | XPUSHs(make_mg_object(aTHX_ mg)); |
a8a597b2 | 1708 | |
b2adfa9b | 1709 | MODULE = B PACKAGE = B::MAGIC |
a8a597b2 MB |
1710 | |
1711 | void | |
b2adfa9b | 1712 | MOREMAGIC(mg) |
a8a597b2 | 1713 | B::MAGIC mg |
b2adfa9b NC |
1714 | ALIAS: |
1715 | PRIVATE = 1 | |
1716 | TYPE = 2 | |
1717 | FLAGS = 3 | |
fb6620c6 | 1718 | LENGTH = 4 |
b2adfa9b NC |
1719 | OBJ = 5 |
1720 | PTR = 6 | |
1721 | REGEX = 7 | |
1722 | precomp = 8 | |
1723 | PPCODE: | |
1724 | switch (ix) { | |
1725 | case 0: | |
1726 | XPUSHs(mg->mg_moremagic ? make_mg_object(aTHX_ mg->mg_moremagic) | |
1727 | : &PL_sv_undef); | |
1728 | break; | |
1729 | case 1: | |
1730 | mPUSHu(mg->mg_private); | |
1731 | break; | |
1732 | case 2: | |
1733 | PUSHs(newSVpvn_flags(&(mg->mg_type), 1, SVs_TEMP)); | |
1734 | break; | |
1735 | case 3: | |
1736 | mPUSHu(mg->mg_flags); | |
1737 | break; | |
1738 | case 4: | |
1739 | mPUSHi(mg->mg_len); | |
1740 | break; | |
1741 | case 5: | |
0c74f67f | 1742 | PUSHs(make_sv_object(aTHX_ mg->mg_obj)); |
b2adfa9b NC |
1743 | break; |
1744 | case 6: | |
1745 | if (mg->mg_ptr) { | |
1746 | if (mg->mg_len >= 0) { | |
1747 | PUSHs(newSVpvn_flags(mg->mg_ptr, mg->mg_len, SVs_TEMP)); | |
651aa52e | 1748 | } else if (mg->mg_len == HEf_SVKEY) { |
0c74f67f | 1749 | PUSHs(make_sv_object(aTHX_ (SV*)mg->mg_ptr)); |
fdbd1d64 | 1750 | } else |
b2adfa9b NC |
1751 | PUSHs(sv_newmortal()); |
1752 | } else | |
1753 | PUSHs(sv_newmortal()); | |
1754 | break; | |
1755 | case 7: | |
1756 | if(mg->mg_type == PERL_MAGIC_qr) { | |
1757 | mPUSHi(PTR2IV(mg->mg_obj)); | |
1758 | } else { | |
1759 | croak("REGEX is only meaningful on r-magic"); | |
1760 | } | |
1761 | break; | |
1762 | case 8: | |
1763 | if (mg->mg_type == PERL_MAGIC_qr) { | |
1764 | REGEXP *rx = (REGEXP *)mg->mg_obj; | |
227aaa42 NC |
1765 | PUSHs(newSVpvn_flags(rx ? RX_PRECOMP(rx) : NULL, |
1766 | rx ? RX_PRELEN(rx) : 0, SVs_TEMP)); | |
b2adfa9b NC |
1767 | } else { |
1768 | croak( "precomp is only meaningful on r-magic" ); | |
1769 | } | |
1770 | break; | |
1771 | } | |
a8a597b2 | 1772 | |
8922e438 FC |
1773 | MODULE = B PACKAGE = B::BM PREFIX = Bm |
1774 | ||
1775 | U32 | |
1776 | BmPREVIOUS(sv) | |
1777 | B::BM sv | |
99639b5b | 1778 | CODE: |
99639b5b | 1779 | PERL_UNUSED_VAR(sv); |
99639b5b DM |
1780 | RETVAL = BmPREVIOUS(sv); |
1781 | OUTPUT: | |
1782 | RETVAL | |
1783 | ||
8922e438 FC |
1784 | |
1785 | U8 | |
1786 | BmRARE(sv) | |
1787 | B::BM sv | |
99639b5b | 1788 | CODE: |
99639b5b | 1789 | PERL_UNUSED_VAR(sv); |
99639b5b DM |
1790 | RETVAL = BmRARE(sv); |
1791 | OUTPUT: | |
1792 | RETVAL | |
1793 | ||
8922e438 | 1794 | |
a8a597b2 MB |
1795 | MODULE = B PACKAGE = B::GV PREFIX = Gv |
1796 | ||
1797 | void | |
1798 | GvNAME(gv) | |
1799 | B::GV gv | |
cbf9c13f NC |
1800 | ALIAS: |
1801 | FILE = 1 | |
435e8dd0 | 1802 | B::HV::NAME = 2 |
a8a597b2 | 1803 | CODE: |
435e8dd0 NC |
1804 | ST(0) = sv_2mortal(newSVhek(!ix ? GvNAME_HEK(gv) |
1805 | : (ix == 1 ? GvFILE_HEK(gv) | |
1806 | : HvNAME_HEK((HV *)gv)))); | |
a8a597b2 | 1807 | |
87d7fd28 GS |
1808 | bool |
1809 | is_empty(gv) | |
1810 | B::GV gv | |
711fbbf0 NC |
1811 | ALIAS: |
1812 | isGV_with_GP = 1 | |
87d7fd28 | 1813 | CODE: |
711fbbf0 | 1814 | if (ix) { |
8298454c | 1815 | RETVAL = cBOOL(isGV_with_GP(gv)); |
711fbbf0 NC |
1816 | } else { |
1817 | RETVAL = GvGP(gv) == Null(GP*); | |
1818 | } | |
50786ba8 | 1819 | OUTPUT: |
711fbbf0 | 1820 | RETVAL |
50786ba8 | 1821 | |
651aa52e AE |
1822 | void* |
1823 | GvGP(gv) | |
1824 | B::GV gv | |
1825 | ||
3800c318 JH |
1826 | #define GP_sv_ix (SVp << 16) | STRUCT_OFFSET(struct gp, gp_sv) |
1827 | #define GP_io_ix (SVp << 16) | STRUCT_OFFSET(struct gp, gp_io) | |
1828 | #define GP_cv_ix (SVp << 16) | STRUCT_OFFSET(struct gp, gp_cv) | |
1829 | #define GP_cvgen_ix (U32p << 16) | STRUCT_OFFSET(struct gp, gp_cvgen) | |
1830 | #define GP_refcnt_ix (U32p << 16) | STRUCT_OFFSET(struct gp, gp_refcnt) | |
1831 | #define GP_hv_ix (SVp << 16) | STRUCT_OFFSET(struct gp, gp_hv) | |
1832 | #define GP_av_ix (SVp << 16) | STRUCT_OFFSET(struct gp, gp_av) | |
1833 | #define GP_form_ix (SVp << 16) | STRUCT_OFFSET(struct gp, gp_form) | |
1834 | #define GP_egv_ix (SVp << 16) | STRUCT_OFFSET(struct gp, gp_egv) | |
a8a597b2 | 1835 | |
257e0650 NC |
1836 | void |
1837 | SV(gv) | |
a8a597b2 | 1838 | B::GV gv |
257e0650 NC |
1839 | ALIAS: |
1840 | SV = GP_sv_ix | |
1841 | IO = GP_io_ix | |
1842 | CV = GP_cv_ix | |
1843 | CVGEN = GP_cvgen_ix | |
1844 | GvREFCNT = GP_refcnt_ix | |
1845 | HV = GP_hv_ix | |
1846 | AV = GP_av_ix | |
1847 | FORM = GP_form_ix | |
1848 | EGV = GP_egv_ix | |
257e0650 NC |
1849 | PREINIT: |
1850 | GP *gp; | |
1851 | char *ptr; | |
1852 | SV *ret; | |
1853 | PPCODE: | |
1854 | gp = GvGP(gv); | |
1855 | if (!gp) { | |
1856 | const GV *const gv = CvGV(cv); | |
46c3f339 | 1857 | Perl_croak(aTHX_ "NULL gp in B::GV::%s", gv ? GvNAME(gv) : "???"); |
257e0650 NC |
1858 | } |
1859 | ptr = (ix & 0xFFFF) + (char *)gp; | |
1860 | switch ((U8)(ix >> 16)) { | |
7d6d3fb7 | 1861 | case SVp: |
0c74f67f | 1862 | ret = make_sv_object(aTHX_ *((SV **)ptr)); |
257e0650 | 1863 | break; |
7d6d3fb7 | 1864 | case U32p: |
257e0650 NC |
1865 | ret = sv_2mortal(newSVuv(*((U32*)ptr))); |
1866 | break; | |
c33e8be1 Z |
1867 | default: |
1868 | croak("Illegal alias 0x%08x for B::*SV", (unsigned)ix); | |
257e0650 NC |
1869 | } |
1870 | ST(0) = ret; | |
1871 | XSRETURN(1); | |
a8a597b2 | 1872 | |
39ff6c37 FC |
1873 | U32 |
1874 | GvLINE(gv) | |
1875 | B::GV gv | |
1876 | ||
bb1efdce FC |
1877 | U32 |
1878 | GvGPFLAGS(gv) | |
1879 | B::GV gv | |
1880 | ||
8ae5a962 NC |
1881 | void |
1882 | FILEGV(gv) | |
a8a597b2 | 1883 | B::GV gv |
8ae5a962 | 1884 | PPCODE: |
0c74f67f | 1885 | PUSHs(make_sv_object(aTHX_ (SV *)GvFILEGV(gv))); |
a8a597b2 | 1886 | |
a8a597b2 MB |
1887 | MODULE = B PACKAGE = B::IO PREFIX = Io |
1888 | ||
04071355 | 1889 | |
b326da91 MB |
1890 | bool |
1891 | IsSTD(io,name) | |
1892 | B::IO io | |
5d7488b2 | 1893 | const char* name |
b326da91 MB |
1894 | PREINIT: |
1895 | PerlIO* handle = 0; | |
1896 | CODE: | |
1897 | if( strEQ( name, "stdin" ) ) { | |
1898 | handle = PerlIO_stdin(); | |
1899 | } | |
1900 | else if( strEQ( name, "stdout" ) ) { | |
1901 | handle = PerlIO_stdout(); | |
1902 | } | |
1903 | else if( strEQ( name, "stderr" ) ) { | |
1904 | handle = PerlIO_stderr(); | |
1905 | } | |
1906 | else { | |
1907 | croak( "Invalid value '%s'", name ); | |
1908 | } | |
1909 | RETVAL = handle == IoIFP(io); | |
1910 | OUTPUT: | |
1911 | RETVAL | |
1912 | ||
a8a597b2 MB |
1913 | MODULE = B PACKAGE = B::AV PREFIX = Av |
1914 | ||
1915 | SSize_t | |
1916 | AvFILL(av) | |
1917 | B::AV av | |
1918 | ||
a8a597b2 MB |
1919 | void |
1920 | AvARRAY(av) | |
1921 | B::AV av | |
1922 | PPCODE: | |
1923 | if (AvFILL(av) >= 0) { | |
1924 | SV **svp = AvARRAY(av); | |
1925 | I32 i; | |
1926 | for (i = 0; i <= AvFILL(av); i++) | |
0c74f67f | 1927 | XPUSHs(make_sv_object(aTHX_ svp[i])); |
a8a597b2 MB |
1928 | } |
1929 | ||
429a5ce7 SM |
1930 | void |
1931 | AvARRAYelt(av, idx) | |
1932 | B::AV av | |
1933 | int idx | |
1934 | PPCODE: | |
1935 | if (idx >= 0 && AvFILL(av) >= 0 && idx <= AvFILL(av)) | |
0c74f67f | 1936 | XPUSHs(make_sv_object(aTHX_ (AvARRAY(av)[idx]))); |
429a5ce7 | 1937 | else |
0c74f67f | 1938 | XPUSHs(make_sv_object(aTHX_ NULL)); |
429a5ce7 | 1939 | |
edcc7c74 | 1940 | |
f2da823f FC |
1941 | MODULE = B PACKAGE = B::FM PREFIX = Fm |
1942 | ||
f2da823f | 1943 | IV |
99639b5b DM |
1944 | FmLINES(format) |
1945 | B::FM format | |
1946 | CODE: | |
1947 | PERL_UNUSED_VAR(format); | |
1948 | RETVAL = 0; | |
1949 | OUTPUT: | |
1950 | RETVAL | |
1951 | ||
f2da823f | 1952 | |
a8a597b2 MB |
1953 | MODULE = B PACKAGE = B::CV PREFIX = Cv |
1954 | ||
651aa52e AE |
1955 | U32 |
1956 | CvCONST(cv) | |
1957 | B::CV cv | |
1958 | ||
6079961f | 1959 | void |
a8a597b2 MB |
1960 | CvSTART(cv) |
1961 | B::CV cv | |
a0da4400 NC |
1962 | ALIAS: |
1963 | ROOT = 1 | |
6079961f NC |
1964 | PPCODE: |
1965 | PUSHs(make_op_object(aTHX_ CvISXSUB(cv) ? NULL | |
1966 | : ix ? CvROOT(cv) : CvSTART(cv))); | |
a8a597b2 | 1967 | |
bb02a38f FC |
1968 | I32 |
1969 | CvDEPTH(cv) | |
1970 | B::CV cv | |
1971 | ||
7261499d FC |
1972 | B::PADLIST |
1973 | CvPADLIST(cv) | |
1974 | B::CV cv | |
eacbb379 DD |
1975 | CODE: |
1976 | RETVAL = CvISXSUB(cv) ? NULL : CvPADLIST(cv); | |
1977 | OUTPUT: | |
1978 | RETVAL | |
7261499d | 1979 | |
eacbb379 | 1980 | SV * |
db6e00bd | 1981 | CvHSCXT(cv) |
eacbb379 DD |
1982 | B::CV cv |
1983 | CODE: | |
db6e00bd | 1984 | RETVAL = newSVuv(CvISXSUB(cv) ? PTR2UV(CvHSCXT(cv)) : 0); |
eacbb379 DD |
1985 | OUTPUT: |
1986 | RETVAL | |
1987 | ||
a8a597b2 MB |
1988 | void |
1989 | CvXSUB(cv) | |
1990 | B::CV cv | |
96819e59 NC |
1991 | ALIAS: |
1992 | XSUBANY = 1 | |
a8a597b2 | 1993 | CODE: |
96819e59 | 1994 | ST(0) = ix && CvCONST(cv) |
0c74f67f | 1995 | ? make_sv_object(aTHX_ (SV *)CvXSUBANY(cv).any_ptr) |
96819e59 NC |
1996 | : sv_2mortal(newSViv(CvISXSUB(cv) |
1997 | ? (ix ? CvXSUBANY(cv).any_iv | |
1998 | : PTR2IV(CvXSUB(cv))) | |
1999 | : 0)); | |
a8a597b2 | 2000 | |
8ae5a962 NC |
2001 | void |
2002 | const_sv(cv) | |
de3f1649 | 2003 | B::CV cv |
8ae5a962 | 2004 | PPCODE: |
0c74f67f | 2005 | PUSHs(make_sv_object(aTHX_ (SV *)cv_const_sv(cv))); |
de3f1649 | 2006 | |
486b1e7f TC |
2007 | void |
2008 | GV(cv) | |
2009 | B::CV cv | |
486b1e7f | 2010 | CODE: |
f244b085 | 2011 | ST(0) = make_sv_object(aTHX_ (SV*)CvGV(cv)); |
486b1e7f | 2012 | |
486b1e7f TC |
2013 | SV * |
2014 | NAME_HEK(cv) | |
2015 | B::CV cv | |
2016 | CODE: | |
2017 | RETVAL = CvNAMED(cv) ? newSVhek(CvNAME_HEK(cv)) : &PL_sv_undef; | |
2018 | OUTPUT: | |
2019 | RETVAL | |
2020 | ||
a8a597b2 MB |
2021 | MODULE = B PACKAGE = B::HV PREFIX = Hv |
2022 | ||
2023 | STRLEN | |
2024 | HvFILL(hv) | |
2025 | B::HV hv | |
2026 | ||
a8a597b2 MB |
2027 | I32 |
2028 | HvRITER(hv) | |
2029 | B::HV hv | |
2030 | ||
a8a597b2 MB |
2031 | void |
2032 | HvARRAY(hv) | |
2033 | B::HV hv | |
2034 | PPCODE: | |
1b95d04f | 2035 | if (HvUSEDKEYS(hv) > 0) { |
fa0789a7 | 2036 | HE *he; |
052a7c76 | 2037 | SSize_t extend_size; |
a8a597b2 | 2038 | (void)hv_iterinit(hv); |
052a7c76 DM |
2039 | /* 2*HvUSEDKEYS() should never be big enough to truncate or wrap */ |
2040 | assert(HvUSEDKEYS(hv) <= (SSize_t_MAX >> 1)); | |
2041 | extend_size = (SSize_t)HvUSEDKEYS(hv) * 2; | |
2042 | EXTEND(sp, extend_size); | |
fa0789a7 RU |
2043 | while ((he = hv_iternext(hv))) { |
2044 | if (HeSVKEY(he)) { | |
2045 | mPUSHs(HeSVKEY(he)); | |
2046 | } else if (HeKUTF8(he)) { | |
2047 | PUSHs(newSVpvn_flags(HeKEY(he), HeKLEN(he), SVf_UTF8|SVs_TEMP)); | |
2048 | } else { | |
2049 | mPUSHp(HeKEY(he), HeKLEN(he)); | |
2050 | } | |
2051 | PUSHs(make_sv_object(aTHX_ HeVAL(he))); | |
a8a597b2 MB |
2052 | } |
2053 | } | |
fd9f6265 JJ |
2054 | |
2055 | MODULE = B PACKAGE = B::HE PREFIX = He | |
2056 | ||
8ae5a962 | 2057 | void |
fd9f6265 JJ |
2058 | HeVAL(he) |
2059 | B::HE he | |
b2619626 NC |
2060 | ALIAS: |
2061 | SVKEY_force = 1 | |
8ae5a962 | 2062 | PPCODE: |
0c74f67f | 2063 | PUSHs(make_sv_object(aTHX_ ix ? HeSVKEY_force(he) : HeVAL(he))); |
fd9f6265 JJ |
2064 | |
2065 | U32 | |
2066 | HeHASH(he) | |
2067 | B::HE he | |
2068 | ||
fdbacc68 | 2069 | MODULE = B PACKAGE = B::RHE |
fd9f6265 JJ |
2070 | |
2071 | SV* | |
fdbacc68 | 2072 | HASH(h) |
fd9f6265 JJ |
2073 | B::RHE h |
2074 | CODE: | |
4b6e9aa6 | 2075 | RETVAL = newRV_noinc( (SV*)cophh_2hv(h, 0) ); |
fd9f6265 JJ |
2076 | OUTPUT: |
2077 | RETVAL | |
e412117e | 2078 | |
7261499d | 2079 | |
86d2498c | 2080 | MODULE = B PACKAGE = B::PADLIST PREFIX = Padlist |
7261499d FC |
2081 | |
2082 | SSize_t | |
86d2498c | 2083 | PadlistMAX(padlist) |
7261499d | 2084 | B::PADLIST padlist |
9b7476d7 FC |
2085 | ALIAS: B::PADNAMELIST::MAX = 0 |
2086 | CODE: | |
2087 | PERL_UNUSED_VAR(ix); | |
2088 | RETVAL = PadlistMAX(padlist); | |
2089 | OUTPUT: | |
2090 | RETVAL | |
2091 | ||
2092 | B::PADNAMELIST | |
2093 | PadlistNAMES(padlist) | |
2094 | B::PADLIST padlist | |
7261499d FC |
2095 | |
2096 | void | |
86d2498c | 2097 | PadlistARRAY(padlist) |
7261499d FC |
2098 | B::PADLIST padlist |
2099 | PPCODE: | |
86d2498c | 2100 | if (PadlistMAX(padlist) >= 0) { |
9b7476d7 | 2101 | dXSTARG; |
86d2498c | 2102 | PAD **padp = PadlistARRAY(padlist); |
99639b5b | 2103 | SSize_t i; |
9b7476d7 FC |
2104 | sv_setiv(newSVrv(TARG, PadlistNAMES(padlist) |
2105 | ? "B::PADNAMELIST" | |
2106 | : "B::NULL"), | |
2107 | PTR2IV(PadlistNAMES(padlist))); | |
2108 | XPUSHTARG; | |
2109 | for (i = 1; i <= PadlistMAX(padlist); i++) | |
7261499d FC |
2110 | XPUSHs(make_sv_object(aTHX_ (SV *)padp[i])); |
2111 | } | |
2112 | ||
2113 | void | |
86d2498c | 2114 | PadlistARRAYelt(padlist, idx) |
7261499d | 2115 | B::PADLIST padlist |
99639b5b | 2116 | SSize_t idx |
7261499d | 2117 | PPCODE: |
9b7476d7 FC |
2118 | if (idx < 0 || idx > PadlistMAX(padlist)) |
2119 | XPUSHs(make_sv_object(aTHX_ NULL)); | |
2120 | else if (!idx) { | |
2121 | PL_stack_sp--; | |
2122 | PUSHMARK(PL_stack_sp-1); | |
2123 | XS_B__PADLIST_NAMES(aTHX_ cv); | |
2124 | return; | |
2125 | } | |
2126 | else | |
7261499d | 2127 | XPUSHs(make_sv_object(aTHX_ |
86d2498c | 2128 | (SV *)PadlistARRAY(padlist)[idx])); |
7261499d FC |
2129 | |
2130 | U32 | |
86d2498c | 2131 | PadlistREFCNT(padlist) |
7261499d FC |
2132 | B::PADLIST padlist |
2133 | CODE: | |
99639b5b | 2134 | PERL_UNUSED_VAR(padlist); |
86d2498c | 2135 | RETVAL = PadlistREFCNT(padlist); |
7261499d FC |
2136 | OUTPUT: |
2137 | RETVAL | |
2138 | ||
9b7476d7 FC |
2139 | MODULE = B PACKAGE = B::PADNAMELIST PREFIX = Padnamelist |
2140 | ||
2141 | void | |
2142 | PadnamelistARRAY(pnl) | |
2143 | B::PADNAMELIST pnl | |
2144 | PPCODE: | |
2145 | if (PadnamelistMAX(pnl) >= 0) { | |
2146 | PADNAME **padp = PadnamelistARRAY(pnl); | |
2147 | SSize_t i = 0; | |
2148 | for (; i <= PadnamelistMAX(pnl); i++) | |
0f94cb1f FC |
2149 | { |
2150 | SV *rv = sv_newmortal(); | |
2151 | sv_setiv(newSVrv(rv,padp[i] ? "B::PADNAME" : "B::SPECIAL"), | |
2152 | PTR2IV(padp[i])); | |
2153 | XPUSHs(rv); | |
2154 | } | |
9b7476d7 FC |
2155 | } |
2156 | ||
0f94cb1f | 2157 | B::PADNAME |
9b7476d7 FC |
2158 | PadnamelistARRAYelt(pnl, idx) |
2159 | B::PADNAMELIST pnl | |
2160 | SSize_t idx | |
0f94cb1f | 2161 | CODE: |
9b7476d7 | 2162 | if (idx < 0 || idx > PadnamelistMAX(pnl)) |
0f94cb1f | 2163 | RETVAL = NULL; |
9b7476d7 | 2164 | else |
0f94cb1f FC |
2165 | RETVAL = PadnamelistARRAY(pnl)[idx]; |
2166 | OUTPUT: | |
2167 | RETVAL | |
9b7476d7 | 2168 | |
0f94cb1f FC |
2169 | MODULE = B PACKAGE = B::PADNAME PREFIX = Padname |
2170 | ||
2171 | #define PN_type_ix \ | |
2172 | sv_SVp | STRUCT_OFFSET(struct padname,xpadn_type_u.xpadn_typestash) | |
2173 | #define PN_ourstash_ix \ | |
2174 | sv_SVp | STRUCT_OFFSET(struct padname,xpadn_ourstash) | |
2175 | #define PN_len_ix \ | |
2176 | sv_U8p | STRUCT_OFFSET(struct padname,xpadn_len) | |
2177 | #define PN_refcnt_ix \ | |
2178 | sv_U32p | STRUCT_OFFSET(struct padname, xpadn_refcnt) | |
2179 | #define PN_cop_seq_range_low_ix \ | |
2180 | sv_U32p | STRUCT_OFFSET(struct padname, xpadn_low) | |
2181 | #define PN_cop_seq_range_high_ix \ | |
2182 | sv_U32p | STRUCT_OFFSET(struct padname, xpadn_high) | |
d8fed09d FC |
2183 | #define PNL_refcnt_ix \ |
2184 | sv_U32p | STRUCT_OFFSET(struct padnamelist, xpadnl_refcnt) | |
58480c3b FC |
2185 | #define PL_id_ix \ |
2186 | sv_U32p | STRUCT_OFFSET(struct padlist, xpadl_id) | |
2187 | #define PL_outid_ix \ | |
2188 | sv_U32p | STRUCT_OFFSET(struct padlist, xpadl_outid) | |
2189 | ||
0f94cb1f FC |
2190 | |
2191 | void | |
2192 | PadnameTYPE(pn) | |
2193 | B::PADNAME pn | |
2194 | ALIAS: | |
2195 | B::PADNAME::TYPE = PN_type_ix | |
2196 | B::PADNAME::OURSTASH = PN_ourstash_ix | |
2197 | B::PADNAME::LEN = PN_len_ix | |
2198 | B::PADNAME::REFCNT = PN_refcnt_ix | |
2199 | B::PADNAME::COP_SEQ_RANGE_LOW = PN_cop_seq_range_low_ix | |
2200 | B::PADNAME::COP_SEQ_RANGE_HIGH = PN_cop_seq_range_high_ix | |
d8fed09d | 2201 | B::PADNAMELIST::REFCNT = PNL_refcnt_ix |
58480c3b FC |
2202 | B::PADLIST::id = PL_id_ix |
2203 | B::PADLIST::outid = PL_outid_ix | |
0f94cb1f FC |
2204 | PREINIT: |
2205 | char *ptr; | |
2206 | SV *ret; | |
2207 | PPCODE: | |
2208 | ptr = (ix & 0xFFFF) + (char *)pn; | |
2209 | switch ((U8)(ix >> 16)) { | |
2210 | case (U8)(sv_SVp >> 16): | |
2211 | ret = make_sv_object(aTHX_ *((SV **)ptr)); | |
2212 | break; | |
2213 | case (U8)(sv_U32p >> 16): | |
2214 | ret = sv_2mortal(newSVuv(*((U32 *)ptr))); | |
2215 | break; | |
2216 | case (U8)(sv_U8p >> 16): | |
2217 | ret = sv_2mortal(newSVuv(*((U8 *)ptr))); | |
2218 | break; | |
2219 | default: | |
2220 | NOT_REACHED; | |
2221 | } | |
2222 | ST(0) = ret; | |
2223 | XSRETURN(1); | |
2224 | ||
2225 | SV * | |
2226 | PadnamePV(pn) | |
2227 | B::PADNAME pn | |
2228 | PREINIT: | |
2229 | dXSTARG; | |
2230 | PPCODE: | |
2231 | PERL_UNUSED_ARG(RETVAL); | |
2232 | sv_setpvn(TARG, PadnamePV(pn), PadnameLEN(pn)); | |
2233 | SvUTF8_on(TARG); | |
2234 | XPUSHTARG; | |
2235 | ||
2236 | BOOT: | |
2237 | { | |
2238 | /* Uses less memory than an ALIAS. */ | |
2239 | GV *gv = gv_fetchpvs("B::PADNAME::TYPE", 1, SVt_PVGV); | |
2240 | sv_setsv((SV *)gv_fetchpvs("B::PADNAME::SvSTASH",1,SVt_PVGV),(SV *)gv); | |
2241 | sv_setsv((SV *)gv_fetchpvs("B::PADNAME::PROTOCV",1,SVt_PVGV),(SV *)gv); | |
2242 | sv_setsv((SV *)gv_fetchpvs("B::PADNAME::PVX",1,SVt_PVGV), | |
2243 | (SV *)gv_fetchpvs("B::PADNAME::PV" ,1,SVt_PVGV)); | |
43a4fb14 FC |
2244 | sv_setsv((SV *)gv_fetchpvs("B::PADNAME::PARENT_PAD_INDEX" ,1,SVt_PVGV), |
2245 | (SV *)gv_fetchpvs("B::PADNAME::COP_SEQ_RANGE_LOW",1, | |
2246 | SVt_PVGV)); | |
2247 | sv_setsv((SV *)gv_fetchpvs("B::PADNAME::PARENT_FAKELEX_FLAGS",1, | |
2248 | SVt_PVGV), | |
2249 | (SV *)gv_fetchpvs("B::PADNAME::COP_SEQ_RANGE_HIGH" ,1, | |
2250 | SVt_PVGV)); | |
0f94cb1f FC |
2251 | } |
2252 | ||
2253 | U32 | |
2254 | PadnameFLAGS(pn) | |
2255 | B::PADNAME pn | |
2256 | CODE: | |
2257 | RETVAL = PadnameFLAGS(pn); | |
2258 | /* backward-compatibility hack, which should be removed if the | |
2259 | flags field becomes large enough to hold SVf_FAKE (and | |
2260 | PADNAMEt_OUTER should be renumbered to match SVf_FAKE) */ | |
d28cce60 | 2261 | STATIC_ASSERT_STMT(SVf_FAKE >= 1<<(sizeof(PadnameFLAGS((B__PADNAME)NULL)) * 8)); |
0f94cb1f FC |
2262 | if (PadnameOUTER(pn)) |
2263 | RETVAL |= SVf_FAKE; | |
2264 | OUTPUT: | |
2265 | RETVAL |