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 |
a8a597b2 MB |
11 | #include "EXTERN.h" |
12 | #include "perl.h" | |
13 | #include "XSUB.h" | |
a8a597b2 | 14 | |
51aa15f3 GS |
15 | #ifdef PerlIO |
16 | typedef PerlIO * InputStream; | |
17 | #else | |
18 | typedef FILE * InputStream; | |
19 | #endif | |
20 | ||
21 | ||
27da23d5 | 22 | static const char* const svclassnames[] = { |
a8a597b2 | 23 | "B::NULL", |
cecf5685 | 24 | "B::BIND", |
1cb9cd50 | 25 | "B::IV", |
b53eecb4 | 26 | "B::NV", |
4df7f6af NC |
27 | #if PERL_VERSION <= 10 |
28 | "B::RV", | |
29 | #endif | |
a8a597b2 MB |
30 | "B::PV", |
31 | "B::PVIV", | |
32 | "B::PVNV", | |
33 | "B::PVMG", | |
4df7f6af | 34 | #if PERL_VERSION >= 11 |
5c35adbb | 35 | "B::REGEXP", |
4df7f6af | 36 | #endif |
4ce457a6 | 37 | "B::GV", |
a8a597b2 MB |
38 | "B::PVLV", |
39 | "B::AV", | |
40 | "B::HV", | |
41 | "B::CV", | |
a8a597b2 MB |
42 | "B::FM", |
43 | "B::IO", | |
44 | }; | |
45 | ||
46 | typedef enum { | |
47 | OPc_NULL, /* 0 */ | |
48 | OPc_BASEOP, /* 1 */ | |
49 | OPc_UNOP, /* 2 */ | |
50 | OPc_BINOP, /* 3 */ | |
51 | OPc_LOGOP, /* 4 */ | |
1a67a97c SM |
52 | OPc_LISTOP, /* 5 */ |
53 | OPc_PMOP, /* 6 */ | |
54 | OPc_SVOP, /* 7 */ | |
7934575e | 55 | OPc_PADOP, /* 8 */ |
1a67a97c | 56 | OPc_PVOP, /* 9 */ |
651aa52e AE |
57 | OPc_LOOP, /* 10 */ |
58 | OPc_COP /* 11 */ | |
a8a597b2 MB |
59 | } opclass; |
60 | ||
27da23d5 | 61 | static const char* const opclassnames[] = { |
a8a597b2 MB |
62 | "B::NULL", |
63 | "B::OP", | |
64 | "B::UNOP", | |
65 | "B::BINOP", | |
66 | "B::LOGOP", | |
a8a597b2 MB |
67 | "B::LISTOP", |
68 | "B::PMOP", | |
69 | "B::SVOP", | |
7934575e | 70 | "B::PADOP", |
a8a597b2 | 71 | "B::PVOP", |
a8a597b2 MB |
72 | "B::LOOP", |
73 | "B::COP" | |
74 | }; | |
75 | ||
27da23d5 | 76 | static const size_t opsizes[] = { |
651aa52e AE |
77 | 0, |
78 | sizeof(OP), | |
79 | sizeof(UNOP), | |
80 | sizeof(BINOP), | |
81 | sizeof(LOGOP), | |
82 | sizeof(LISTOP), | |
83 | sizeof(PMOP), | |
84 | sizeof(SVOP), | |
85 | sizeof(PADOP), | |
86 | sizeof(PVOP), | |
87 | sizeof(LOOP), | |
88 | sizeof(COP) | |
89 | }; | |
90 | ||
df3728a2 | 91 | #define MY_CXT_KEY "B::_guts" XS_VERSION |
a8a597b2 | 92 | |
89ca4ac7 JH |
93 | typedef struct { |
94 | int x_walkoptree_debug; /* Flag for walkoptree debug hook */ | |
b326da91 | 95 | SV * x_specialsv_list[7]; |
89ca4ac7 JH |
96 | } my_cxt_t; |
97 | ||
98 | START_MY_CXT | |
99 | ||
100 | #define walkoptree_debug (MY_CXT.x_walkoptree_debug) | |
101 | #define specialsv_list (MY_CXT.x_specialsv_list) | |
e8edd1e6 | 102 | |
a8a597b2 | 103 | static opclass |
5d7488b2 | 104 | cc_opclass(pTHX_ const OP *o) |
a8a597b2 | 105 | { |
1830b3d9 BM |
106 | bool custom = 0; |
107 | ||
a8a597b2 MB |
108 | if (!o) |
109 | return OPc_NULL; | |
110 | ||
111 | if (o->op_type == 0) | |
112 | return (o->op_flags & OPf_KIDS) ? OPc_UNOP : OPc_BASEOP; | |
113 | ||
114 | if (o->op_type == OP_SASSIGN) | |
115 | return ((o->op_private & OPpASSIGN_BACKWARDS) ? OPc_UNOP : OPc_BINOP); | |
116 | ||
c60fdceb | 117 | if (o->op_type == OP_AELEMFAST) { |
93bad3fd | 118 | #if PERL_VERSION <= 14 |
c60fdceb SM |
119 | if (o->op_flags & OPf_SPECIAL) |
120 | return OPc_BASEOP; | |
121 | else | |
93bad3fd | 122 | #endif |
c60fdceb SM |
123 | #ifdef USE_ITHREADS |
124 | return OPc_PADOP; | |
125 | #else | |
126 | return OPc_SVOP; | |
127 | #endif | |
128 | } | |
129 | ||
18228111 | 130 | #ifdef USE_ITHREADS |
31b49ad4 | 131 | if (o->op_type == OP_GV || o->op_type == OP_GVSV || |
c60fdceb | 132 | o->op_type == OP_RCATLINE) |
18228111 GS |
133 | return OPc_PADOP; |
134 | #endif | |
135 | ||
1830b3d9 BM |
136 | if (o->op_type == OP_CUSTOM) |
137 | custom = 1; | |
138 | ||
139 | switch (OP_CLASS(o)) { | |
a8a597b2 MB |
140 | case OA_BASEOP: |
141 | return OPc_BASEOP; | |
142 | ||
143 | case OA_UNOP: | |
144 | return OPc_UNOP; | |
145 | ||
146 | case OA_BINOP: | |
147 | return OPc_BINOP; | |
148 | ||
149 | case OA_LOGOP: | |
150 | return OPc_LOGOP; | |
151 | ||
a8a597b2 MB |
152 | case OA_LISTOP: |
153 | return OPc_LISTOP; | |
154 | ||
155 | case OA_PMOP: | |
156 | return OPc_PMOP; | |
157 | ||
158 | case OA_SVOP: | |
159 | return OPc_SVOP; | |
160 | ||
7934575e GS |
161 | case OA_PADOP: |
162 | return OPc_PADOP; | |
a8a597b2 | 163 | |
293d3ffa SM |
164 | case OA_PVOP_OR_SVOP: |
165 | /* | |
166 | * Character translations (tr///) are usually a PVOP, keeping a | |
167 | * pointer to a table of shorts used to look up translations. | |
168 | * Under utf8, however, a simple table isn't practical; instead, | |
512ba29b FC |
169 | * the OP is an SVOP (or, under threads, a PADOP), |
170 | * and the SV is a reference to a swash | |
293d3ffa SM |
171 | * (i.e., an RV pointing to an HV). |
172 | */ | |
1830b3d9 BM |
173 | return (!custom && |
174 | (o->op_private & (OPpTRANS_TO_UTF|OPpTRANS_FROM_UTF)) | |
175 | ) | |
35633035 | 176 | #if defined(USE_ITHREADS) |
512ba29b FC |
177 | ? OPc_PADOP : OPc_PVOP; |
178 | #else | |
293d3ffa | 179 | ? OPc_SVOP : OPc_PVOP; |
512ba29b | 180 | #endif |
a8a597b2 MB |
181 | |
182 | case OA_LOOP: | |
183 | return OPc_LOOP; | |
184 | ||
185 | case OA_COP: | |
186 | return OPc_COP; | |
187 | ||
188 | case OA_BASEOP_OR_UNOP: | |
189 | /* | |
190 | * UNI(OP_foo) in toke.c returns token UNI or FUNC1 depending on | |
45f6cd40 SM |
191 | * whether parens were seen. perly.y uses OPf_SPECIAL to |
192 | * signal whether a BASEOP had empty parens or none. | |
193 | * Some other UNOPs are created later, though, so the best | |
194 | * test is OPf_KIDS, which is set in newUNOP. | |
a8a597b2 | 195 | */ |
45f6cd40 | 196 | return (o->op_flags & OPf_KIDS) ? OPc_UNOP : OPc_BASEOP; |
a8a597b2 MB |
197 | |
198 | case OA_FILESTATOP: | |
199 | /* | |
200 | * The file stat OPs are created via UNI(OP_foo) in toke.c but use | |
201 | * the OPf_REF flag to distinguish between OP types instead of the | |
202 | * usual OPf_SPECIAL flag. As usual, if OPf_KIDS is set, then we | |
203 | * return OPc_UNOP so that walkoptree can find our children. If | |
204 | * OPf_KIDS is not set then we check OPf_REF. Without OPf_REF set | |
205 | * (no argument to the operator) it's an OP; with OPf_REF set it's | |
7934575e | 206 | * an SVOP (and op_sv is the GV for the filehandle argument). |
a8a597b2 MB |
207 | */ |
208 | return ((o->op_flags & OPf_KIDS) ? OPc_UNOP : | |
93865851 GS |
209 | #ifdef USE_ITHREADS |
210 | (o->op_flags & OPf_REF) ? OPc_PADOP : OPc_BASEOP); | |
211 | #else | |
7934575e | 212 | (o->op_flags & OPf_REF) ? OPc_SVOP : OPc_BASEOP); |
93865851 | 213 | #endif |
a8a597b2 MB |
214 | case OA_LOOPEXOP: |
215 | /* | |
216 | * next, last, redo, dump and goto use OPf_SPECIAL to indicate that a | |
217 | * label was omitted (in which case it's a BASEOP) or else a term was | |
218 | * seen. In this last case, all except goto are definitely PVOP but | |
219 | * goto is either a PVOP (with an ordinary constant label), an UNOP | |
220 | * with OPf_STACKED (with a non-constant non-sub) or an UNOP for | |
221 | * OP_REFGEN (with goto &sub) in which case OPf_STACKED also seems to | |
222 | * get set. | |
223 | */ | |
224 | if (o->op_flags & OPf_STACKED) | |
225 | return OPc_UNOP; | |
226 | else if (o->op_flags & OPf_SPECIAL) | |
227 | return OPc_BASEOP; | |
228 | else | |
229 | return OPc_PVOP; | |
230 | } | |
231 | warn("can't determine class of operator %s, assuming BASEOP\n", | |
1830b3d9 | 232 | OP_NAME(o)); |
a8a597b2 MB |
233 | return OPc_BASEOP; |
234 | } | |
235 | ||
6079961f NC |
236 | static SV * |
237 | make_op_object(pTHX_ const OP *o) | |
a8a597b2 | 238 | { |
6079961f NC |
239 | SV *opsv = sv_newmortal(); |
240 | sv_setiv(newSVrv(opsv, opclassnames[cc_opclass(aTHX_ o)]), PTR2IV(o)); | |
241 | return opsv; | |
a8a597b2 MB |
242 | } |
243 | ||
244 | static SV * | |
0c74f67f | 245 | make_sv_object(pTHX_ SV *sv) |
a8a597b2 | 246 | { |
0c74f67f | 247 | SV *const arg = sv_newmortal(); |
27da23d5 | 248 | const char *type = 0; |
a8a597b2 | 249 | IV iv; |
89ca4ac7 | 250 | dMY_CXT; |
9496d2e5 | 251 | |
c33e8be1 | 252 | for (iv = 0; iv < (IV)(sizeof(specialsv_list)/sizeof(SV*)); iv++) { |
e8edd1e6 | 253 | if (sv == specialsv_list[iv]) { |
a8a597b2 MB |
254 | type = "B::SPECIAL"; |
255 | break; | |
256 | } | |
257 | } | |
258 | if (!type) { | |
259 | type = svclassnames[SvTYPE(sv)]; | |
56431972 | 260 | iv = PTR2IV(sv); |
a8a597b2 MB |
261 | } |
262 | sv_setiv(newSVrv(arg, type), iv); | |
263 | return arg; | |
264 | } | |
265 | ||
266 | static SV * | |
9496d2e5 | 267 | make_temp_object(pTHX_ SV *temp) |
8e01d9a6 NC |
268 | { |
269 | SV *target; | |
9496d2e5 | 270 | SV *arg = sv_newmortal(); |
8e01d9a6 NC |
271 | const char *const type = svclassnames[SvTYPE(temp)]; |
272 | const IV iv = PTR2IV(temp); | |
273 | ||
274 | target = newSVrv(arg, type); | |
275 | sv_setiv(target, iv); | |
276 | ||
277 | /* Need to keep our "temp" around as long as the target exists. | |
278 | Simplest way seems to be to hang it from magic, and let that clear | |
279 | it up. No vtable, so won't actually get in the way of anything. */ | |
280 | sv_magicext(target, temp, PERL_MAGIC_sv, NULL, NULL, 0); | |
281 | /* magic object has had its reference count increased, so we must drop | |
282 | our reference. */ | |
283 | SvREFCNT_dec(temp); | |
284 | return arg; | |
285 | } | |
286 | ||
287 | static SV * | |
d2b4c688 | 288 | make_warnings_object(pTHX_ const COP *const cop) |
5c3c3f81 | 289 | { |
d2b4c688 | 290 | const STRLEN *const warnings = cop->cop_warnings; |
5c3c3f81 NC |
291 | const char *type = 0; |
292 | dMY_CXT; | |
293 | IV iv = sizeof(specialsv_list)/sizeof(SV*); | |
294 | ||
295 | /* Counting down is deliberate. Before the split between make_sv_object | |
296 | and make_warnings_obj there appeared to be a bug - Nullsv and pWARN_STD | |
297 | were both 0, so you could never get a B::SPECIAL for pWARN_STD */ | |
298 | ||
299 | while (iv--) { | |
300 | if ((SV*)warnings == specialsv_list[iv]) { | |
301 | type = "B::SPECIAL"; | |
302 | break; | |
303 | } | |
304 | } | |
305 | if (type) { | |
9496d2e5 | 306 | SV *arg = sv_newmortal(); |
5c3c3f81 | 307 | sv_setiv(newSVrv(arg, type), iv); |
8e01d9a6 | 308 | return arg; |
5c3c3f81 NC |
309 | } else { |
310 | /* B assumes that warnings are a regular SV. Seems easier to keep it | |
311 | happy by making them into a regular SV. */ | |
9496d2e5 | 312 | return make_temp_object(aTHX_ newSVpvn((char *)(warnings + 1), *warnings)); |
8e01d9a6 NC |
313 | } |
314 | } | |
315 | ||
316 | static SV * | |
9496d2e5 | 317 | make_cop_io_object(pTHX_ COP *cop) |
8e01d9a6 | 318 | { |
8b850bd5 NC |
319 | SV *const value = newSV(0); |
320 | ||
33972ad6 | 321 | Perl_emulate_cop_io(aTHX_ cop, value); |
8b850bd5 NC |
322 | |
323 | if(SvOK(value)) { | |
0c74f67f | 324 | return make_sv_object(aTHX_ value); |
8e01d9a6 | 325 | } else { |
8b850bd5 | 326 | SvREFCNT_dec(value); |
0c74f67f | 327 | return make_sv_object(aTHX_ NULL); |
5c3c3f81 | 328 | } |
5c3c3f81 NC |
329 | } |
330 | ||
331 | static SV * | |
9496d2e5 | 332 | make_mg_object(pTHX_ MAGIC *mg) |
a8a597b2 | 333 | { |
9496d2e5 | 334 | SV *arg = sv_newmortal(); |
56431972 | 335 | sv_setiv(newSVrv(arg, "B::MAGIC"), PTR2IV(mg)); |
a8a597b2 MB |
336 | return arg; |
337 | } | |
338 | ||
339 | static SV * | |
52ad86de | 340 | cstring(pTHX_ SV *sv, bool perlstyle) |
a8a597b2 | 341 | { |
09e97b95 | 342 | SV *sstr; |
a8a597b2 MB |
343 | |
344 | if (!SvOK(sv)) | |
09e97b95 NC |
345 | return newSVpvs_flags("0", SVs_TEMP); |
346 | ||
347 | sstr = newSVpvs_flags("\"", SVs_TEMP); | |
348 | ||
349 | if (perlstyle && SvUTF8(sv)) { | |
d79a7a3d | 350 | SV *tmpsv = sv_newmortal(); /* Temporary SV to feed sv_uni_display */ |
5d7488b2 AL |
351 | const STRLEN len = SvCUR(sv); |
352 | const char *s = sv_uni_display(tmpsv, sv, 8*len, UNI_DISPLAY_QQ); | |
d79a7a3d RGS |
353 | while (*s) |
354 | { | |
355 | if (*s == '"') | |
6beb30a6 | 356 | sv_catpvs(sstr, "\\\""); |
d79a7a3d | 357 | else if (*s == '$') |
6beb30a6 | 358 | sv_catpvs(sstr, "\\$"); |
d79a7a3d | 359 | else if (*s == '@') |
6beb30a6 | 360 | sv_catpvs(sstr, "\\@"); |
d79a7a3d RGS |
361 | else if (*s == '\\') |
362 | { | |
363 | if (strchr("nrftax\\",*(s+1))) | |
364 | sv_catpvn(sstr, s++, 2); | |
365 | else | |
6beb30a6 | 366 | sv_catpvs(sstr, "\\\\"); |
d79a7a3d RGS |
367 | } |
368 | else /* should always be printable */ | |
369 | sv_catpvn(sstr, s, 1); | |
370 | ++s; | |
371 | } | |
d79a7a3d | 372 | } |
a8a597b2 MB |
373 | else |
374 | { | |
375 | /* XXX Optimise? */ | |
5d7488b2 AL |
376 | STRLEN len; |
377 | const char *s = SvPV(sv, len); | |
a8a597b2 MB |
378 | for (; len; len--, s++) |
379 | { | |
380 | /* At least try a little for readability */ | |
381 | if (*s == '"') | |
6beb30a6 | 382 | sv_catpvs(sstr, "\\\""); |
a8a597b2 | 383 | else if (*s == '\\') |
6beb30a6 | 384 | sv_catpvs(sstr, "\\\\"); |
b326da91 | 385 | /* trigraphs - bleagh */ |
5d7488b2 | 386 | else if (!perlstyle && *s == '?' && len>=3 && s[1] == '?') { |
47bf35fa | 387 | Perl_sv_catpvf(aTHX_ sstr, "\\%03o", '?'); |
b326da91 | 388 | } |
52ad86de | 389 | else if (perlstyle && *s == '$') |
6beb30a6 | 390 | sv_catpvs(sstr, "\\$"); |
52ad86de | 391 | else if (perlstyle && *s == '@') |
6beb30a6 | 392 | sv_catpvs(sstr, "\\@"); |
ce561ef2 | 393 | else if (isPRINT(*s)) |
a8a597b2 MB |
394 | sv_catpvn(sstr, s, 1); |
395 | else if (*s == '\n') | |
6beb30a6 | 396 | sv_catpvs(sstr, "\\n"); |
a8a597b2 | 397 | else if (*s == '\r') |
6beb30a6 | 398 | sv_catpvs(sstr, "\\r"); |
a8a597b2 | 399 | else if (*s == '\t') |
6beb30a6 | 400 | sv_catpvs(sstr, "\\t"); |
a8a597b2 | 401 | else if (*s == '\a') |
6beb30a6 | 402 | sv_catpvs(sstr, "\\a"); |
a8a597b2 | 403 | else if (*s == '\b') |
6beb30a6 | 404 | sv_catpvs(sstr, "\\b"); |
a8a597b2 | 405 | else if (*s == '\f') |
6beb30a6 | 406 | sv_catpvs(sstr, "\\f"); |
52ad86de | 407 | else if (!perlstyle && *s == '\v') |
6beb30a6 | 408 | sv_catpvs(sstr, "\\v"); |
a8a597b2 MB |
409 | else |
410 | { | |
a8a597b2 | 411 | /* Don't want promotion of a signed -1 char in sprintf args */ |
5d7488b2 | 412 | const unsigned char c = (unsigned char) *s; |
47bf35fa | 413 | Perl_sv_catpvf(aTHX_ sstr, "\\%03o", c); |
a8a597b2 MB |
414 | } |
415 | /* XXX Add line breaks if string is long */ | |
416 | } | |
a8a597b2 | 417 | } |
09e97b95 | 418 | sv_catpvs(sstr, "\""); |
a8a597b2 MB |
419 | return sstr; |
420 | } | |
421 | ||
422 | static SV * | |
cea2e8a9 | 423 | cchar(pTHX_ SV *sv) |
a8a597b2 | 424 | { |
422d053b | 425 | SV *sstr = newSVpvs_flags("'", SVs_TEMP); |
5d7488b2 | 426 | const char *s = SvPV_nolen(sv); |
422d053b NC |
427 | /* Don't want promotion of a signed -1 char in sprintf args */ |
428 | const unsigned char c = (unsigned char) *s; | |
a8a597b2 | 429 | |
422d053b | 430 | if (c == '\'') |
6beb30a6 | 431 | sv_catpvs(sstr, "\\'"); |
422d053b | 432 | else if (c == '\\') |
6beb30a6 | 433 | sv_catpvs(sstr, "\\\\"); |
422d053b | 434 | else if (isPRINT(c)) |
a8a597b2 | 435 | sv_catpvn(sstr, s, 1); |
422d053b | 436 | else if (c == '\n') |
6beb30a6 | 437 | sv_catpvs(sstr, "\\n"); |
422d053b | 438 | else if (c == '\r') |
6beb30a6 | 439 | sv_catpvs(sstr, "\\r"); |
422d053b | 440 | else if (c == '\t') |
6beb30a6 | 441 | sv_catpvs(sstr, "\\t"); |
422d053b | 442 | else if (c == '\a') |
6beb30a6 | 443 | sv_catpvs(sstr, "\\a"); |
422d053b | 444 | else if (c == '\b') |
6beb30a6 | 445 | sv_catpvs(sstr, "\\b"); |
422d053b | 446 | else if (c == '\f') |
6beb30a6 | 447 | sv_catpvs(sstr, "\\f"); |
422d053b | 448 | else if (c == '\v') |
6beb30a6 | 449 | sv_catpvs(sstr, "\\v"); |
a8a597b2 | 450 | else |
422d053b | 451 | Perl_sv_catpvf(aTHX_ sstr, "\\%03o", c); |
6beb30a6 | 452 | sv_catpvs(sstr, "'"); |
a8a597b2 MB |
453 | return sstr; |
454 | } | |
455 | ||
35633035 DM |
456 | #define PMOP_pmreplstart(o) o->op_pmstashstartu.op_pmreplstart |
457 | #define PMOP_pmreplroot(o) o->op_pmreplrootu.op_pmreplroot | |
8f3d514b | 458 | |
20f7624e NC |
459 | static SV * |
460 | walkoptree(pTHX_ OP *o, const char *method, SV *ref) | |
a8a597b2 MB |
461 | { |
462 | dSP; | |
20f7624e NC |
463 | OP *kid; |
464 | SV *object; | |
6079961f | 465 | const char *const classname = opclassnames[cc_opclass(aTHX_ o)]; |
89ca4ac7 JH |
466 | dMY_CXT; |
467 | ||
20f7624e NC |
468 | /* Check that no-one has changed our reference, or is holding a reference |
469 | to it. */ | |
470 | if (SvREFCNT(ref) == 1 && SvROK(ref) && SvTYPE(ref) == SVt_RV | |
471 | && (object = SvRV(ref)) && SvREFCNT(object) == 1 | |
472 | && SvTYPE(object) == SVt_PVMG && SvIOK_only(object) | |
473 | && !SvMAGICAL(object) && !SvMAGIC(object) && SvSTASH(object)) { | |
474 | /* Looks good, so rebless it for the class we need: */ | |
475 | sv_bless(ref, gv_stashpv(classname, GV_ADD)); | |
476 | } else { | |
477 | /* Need to make a new one. */ | |
478 | ref = sv_newmortal(); | |
479 | object = newSVrv(ref, classname); | |
480 | } | |
481 | sv_setiv(object, PTR2IV(o)); | |
482 | ||
a8a597b2 MB |
483 | if (walkoptree_debug) { |
484 | PUSHMARK(sp); | |
20f7624e | 485 | XPUSHs(ref); |
a8a597b2 MB |
486 | PUTBACK; |
487 | perl_call_method("walkoptree_debug", G_DISCARD); | |
488 | } | |
489 | PUSHMARK(sp); | |
20f7624e | 490 | XPUSHs(ref); |
a8a597b2 MB |
491 | PUTBACK; |
492 | perl_call_method(method, G_DISCARD); | |
493 | if (o && (o->op_flags & OPf_KIDS)) { | |
a8a597b2 | 494 | for (kid = ((UNOP*)o)->op_first; kid; kid = kid->op_sibling) { |
20f7624e | 495 | ref = walkoptree(aTHX_ kid, method, ref); |
a8a597b2 MB |
496 | } |
497 | } | |
5464c149 | 498 | if (o && (cc_opclass(aTHX_ o) == OPc_PMOP) && o->op_type != OP_PUSHRE |
8f3d514b | 499 | && (kid = PMOP_pmreplroot(cPMOPo))) |
f3be9b72 | 500 | { |
20f7624e | 501 | ref = walkoptree(aTHX_ kid, method, ref); |
f3be9b72 | 502 | } |
20f7624e | 503 | return ref; |
a8a597b2 MB |
504 | } |
505 | ||
5d7488b2 | 506 | static SV ** |
1df34986 AE |
507 | oplist(pTHX_ OP *o, SV **SP) |
508 | { | |
509 | for(; o; o = o->op_next) { | |
7252851f | 510 | if (o->op_opt == 0) |
1df34986 | 511 | break; |
2814eb74 | 512 | o->op_opt = 0; |
6079961f | 513 | XPUSHs(make_op_object(aTHX_ o)); |
1df34986 AE |
514 | switch (o->op_type) { |
515 | case OP_SUBST: | |
8f3d514b | 516 | SP = oplist(aTHX_ PMOP_pmreplstart(cPMOPo), SP); |
1df34986 AE |
517 | continue; |
518 | case OP_SORT: | |
f66c782a | 519 | if (o->op_flags & OPf_STACKED && o->op_flags & OPf_SPECIAL) { |
1df34986 AE |
520 | OP *kid = cLISTOPo->op_first->op_sibling; /* pass pushmark */ |
521 | kid = kUNOP->op_first; /* pass rv2gv */ | |
522 | kid = kUNOP->op_first; /* pass leave */ | |
f66c782a | 523 | SP = oplist(aTHX_ kid->op_next, SP); |
1df34986 AE |
524 | } |
525 | continue; | |
526 | } | |
527 | switch (PL_opargs[o->op_type] & OA_CLASS_MASK) { | |
528 | case OA_LOGOP: | |
529 | SP = oplist(aTHX_ cLOGOPo->op_other, SP); | |
530 | break; | |
531 | case OA_LOOP: | |
532 | SP = oplist(aTHX_ cLOOPo->op_lastop, SP); | |
533 | SP = oplist(aTHX_ cLOOPo->op_nextop, SP); | |
534 | SP = oplist(aTHX_ cLOOPo->op_redoop, SP); | |
535 | break; | |
536 | } | |
537 | } | |
538 | return SP; | |
539 | } | |
540 | ||
a8a597b2 MB |
541 | typedef OP *B__OP; |
542 | typedef UNOP *B__UNOP; | |
543 | typedef BINOP *B__BINOP; | |
544 | typedef LOGOP *B__LOGOP; | |
a8a597b2 MB |
545 | typedef LISTOP *B__LISTOP; |
546 | typedef PMOP *B__PMOP; | |
547 | typedef SVOP *B__SVOP; | |
7934575e | 548 | typedef PADOP *B__PADOP; |
a8a597b2 MB |
549 | typedef PVOP *B__PVOP; |
550 | typedef LOOP *B__LOOP; | |
551 | typedef COP *B__COP; | |
552 | ||
553 | typedef SV *B__SV; | |
554 | typedef SV *B__IV; | |
555 | typedef SV *B__PV; | |
556 | typedef SV *B__NV; | |
557 | typedef SV *B__PVMG; | |
5c35adbb NC |
558 | #if PERL_VERSION >= 11 |
559 | typedef SV *B__REGEXP; | |
560 | #endif | |
a8a597b2 MB |
561 | typedef SV *B__PVLV; |
562 | typedef SV *B__BM; | |
563 | typedef SV *B__RV; | |
1df34986 | 564 | typedef SV *B__FM; |
a8a597b2 MB |
565 | typedef AV *B__AV; |
566 | typedef HV *B__HV; | |
567 | typedef CV *B__CV; | |
568 | typedef GV *B__GV; | |
569 | typedef IO *B__IO; | |
570 | ||
571 | typedef MAGIC *B__MAGIC; | |
fd9f6265 JJ |
572 | typedef HE *B__HE; |
573 | typedef struct refcounted_he *B__RHE; | |
86d2498c | 574 | #ifdef PadlistARRAY |
7261499d FC |
575 | typedef PADLIST *B__PADLIST; |
576 | #endif | |
a8a597b2 | 577 | |
3486ec84 | 578 | #ifdef MULTIPLICITY |
115ff745 NC |
579 | # define ASSIGN_COMMON_ALIAS(prefix, var) \ |
580 | STMT_START { XSANY.any_i32 = offsetof(struct interpreter, prefix##var); } STMT_END | |
32855229 | 581 | #else |
115ff745 | 582 | # define ASSIGN_COMMON_ALIAS(prefix, var) \ |
32855229 NC |
583 | STMT_START { XSANY.any_ptr = (void *)&PL_##var; } STMT_END |
584 | #endif | |
585 | ||
586 | /* This needs to be ALIASed in a custom way, hence can't easily be defined as | |
587 | a regular XSUB. */ | |
588 | static XSPROTO(intrpvar_sv_common); /* prototype to pass -Wmissing-prototypes */ | |
589 | static XSPROTO(intrpvar_sv_common) | |
590 | { | |
591 | dVAR; | |
592 | dXSARGS; | |
593 | SV *ret; | |
594 | if (items != 0) | |
595 | croak_xs_usage(cv, ""); | |
3486ec84 | 596 | #ifdef MULTIPLICITY |
32855229 NC |
597 | ret = *(SV **)(XSANY.any_i32 + (char *)my_perl); |
598 | #else | |
599 | ret = *(SV **)(XSANY.any_ptr); | |
600 | #endif | |
0c74f67f | 601 | ST(0) = make_sv_object(aTHX_ ret); |
32855229 NC |
602 | XSRETURN(1); |
603 | } | |
604 | ||
bec746fe DM |
605 | |
606 | ||
607 | #define SVp 0x00000 | |
608 | #define U32p 0x10000 | |
609 | #define line_tp 0x20000 | |
610 | #define OPp 0x30000 | |
611 | #define PADOFFSETp 0x40000 | |
612 | #define U8p 0x50000 | |
613 | #define IVp 0x60000 | |
614 | #define char_pp 0x70000 | |
615 | ||
616 | /* table that drives most of the B::*OP methods */ | |
617 | ||
618 | struct OP_methods { | |
619 | const char *name; | |
620 | STRLEN namelen; | |
621 | I32 type; | |
622 | size_t offset; /* if -1, access is handled on a case-by-case basis */ | |
623 | } op_methods[] = { | |
624 | STR_WITH_LEN("next"), OPp, offsetof(struct op, op_next), /* 0*/ | |
625 | STR_WITH_LEN("sibling"), OPp, offsetof(struct op, op_sibling), /* 1*/ | |
626 | STR_WITH_LEN("targ"), PADOFFSETp, offsetof(struct op, op_targ), /* 2*/ | |
627 | STR_WITH_LEN("flags"), U8p, offsetof(struct op, op_flags), /* 3*/ | |
628 | STR_WITH_LEN("private"), U8p, offsetof(struct op, op_private), /* 4*/ | |
629 | STR_WITH_LEN("first"), OPp, offsetof(struct unop, op_first), /* 5*/ | |
630 | STR_WITH_LEN("last"), OPp, offsetof(struct binop, op_last), /* 6*/ | |
631 | STR_WITH_LEN("other"), OPp, offsetof(struct logop, op_other), /* 7*/ | |
632 | STR_WITH_LEN("pmreplstart"), OPp, | |
633 | offsetof(struct pmop, op_pmstashstartu.op_pmreplstart), /* 8*/ | |
634 | STR_WITH_LEN("redoop"), OPp, offsetof(struct loop, op_redoop), /* 9*/ | |
635 | STR_WITH_LEN("nextop"), OPp, offsetof(struct loop, op_nextop), /*10*/ | |
636 | STR_WITH_LEN("lastop"), OPp, offsetof(struct loop, op_lastop), /*11*/ | |
637 | STR_WITH_LEN("pmflags"), U32p, offsetof(struct pmop, op_pmflags), /*12*/ | |
638 | #if PERL_VERSION >= 17 | |
639 | STR_WITH_LEN("code_list"),OPp, offsetof(struct pmop, op_code_list),/*13*/ | |
640 | #else | |
641 | STR_WITH_LEN("code_list"),0, -1, | |
642 | #endif | |
643 | STR_WITH_LEN("sv"), SVp, offsetof(struct svop, op_sv), /*14*/ | |
644 | STR_WITH_LEN("gv"), SVp, offsetof(struct svop, op_sv), /*15*/ | |
645 | STR_WITH_LEN("padix"), PADOFFSETp,offsetof(struct padop, op_padix),/*16*/ | |
646 | STR_WITH_LEN("cop_seq"), U32p, offsetof(struct cop, cop_seq), /*17*/ | |
647 | STR_WITH_LEN("line"), line_tp, offsetof(struct cop, cop_line), /*18*/ | |
648 | STR_WITH_LEN("hints"), U32p, offsetof(struct cop, cop_hints), /*19*/ | |
649 | #ifdef USE_ITHREADS | |
650 | STR_WITH_LEN("pmoffset"),IVp, offsetof(struct pmop, op_pmoffset),/*20*/ | |
651 | STR_WITH_LEN("filegv"), 0, -1, /*21*/ | |
652 | STR_WITH_LEN("file"), char_pp, offsetof(struct cop, cop_file), /*22*/ | |
653 | STR_WITH_LEN("stash"), 0, -1, /*23*/ | |
654 | # if PERL_VERSION < 17 | |
655 | STR_WITH_LEN("stashpv"), char_pp, offsetof(struct cop, cop_stashpv), /*24*/ | |
656 | STR_WITH_LEN("stashoff"),0, -1, /*25*/ | |
657 | # else | |
658 | STR_WITH_LEN("stashpv"), 0, -1, /*24*/ | |
659 | STR_WITH_LEN("stashoff"),PADOFFSETp,offsetof(struct cop, cop_stashoff),/*25*/ | |
660 | # endif | |
661 | #else | |
662 | STR_WITH_LEN("pmoffset"),0, -1, /*20*/ | |
663 | STR_WITH_LEN("filegv"), SVp, offsetof(struct cop, cop_filegv), /*21*/ | |
664 | STR_WITH_LEN("file"), 0, -1, /*22*/ | |
665 | STR_WITH_LEN("stash"), SVp, offsetof(struct cop, cop_stash), /*23*/ | |
666 | STR_WITH_LEN("stashpv"), 0, -1, /*24*/ | |
667 | STR_WITH_LEN("stashoff"),0, -1, /*25*/ | |
668 | #endif | |
669 | }; | |
670 | ||
b1826b71 NC |
671 | #include "const-c.inc" |
672 | ||
7a2c16aa | 673 | MODULE = B PACKAGE = B |
a8a597b2 | 674 | |
b1826b71 NC |
675 | INCLUDE: const-xs.inc |
676 | ||
a8a597b2 MB |
677 | PROTOTYPES: DISABLE |
678 | ||
679 | BOOT: | |
4c1f658f | 680 | { |
7a2c16aa NC |
681 | CV *cv; |
682 | const char *file = __FILE__; | |
89ca4ac7 | 683 | MY_CXT_INIT; |
e8edd1e6 TH |
684 | specialsv_list[0] = Nullsv; |
685 | specialsv_list[1] = &PL_sv_undef; | |
686 | specialsv_list[2] = &PL_sv_yes; | |
687 | specialsv_list[3] = &PL_sv_no; | |
5c3c3f81 NC |
688 | specialsv_list[4] = (SV *) pWARN_ALL; |
689 | specialsv_list[5] = (SV *) pWARN_NONE; | |
690 | specialsv_list[6] = (SV *) pWARN_STD; | |
32855229 NC |
691 | |
692 | cv = newXS("B::init_av", intrpvar_sv_common, file); | |
115ff745 | 693 | ASSIGN_COMMON_ALIAS(I, initav); |
32855229 | 694 | cv = newXS("B::check_av", intrpvar_sv_common, file); |
115ff745 | 695 | ASSIGN_COMMON_ALIAS(I, checkav_save); |
32855229 | 696 | cv = newXS("B::unitcheck_av", intrpvar_sv_common, file); |
115ff745 | 697 | ASSIGN_COMMON_ALIAS(I, unitcheckav_save); |
32855229 | 698 | cv = newXS("B::begin_av", intrpvar_sv_common, file); |
115ff745 | 699 | ASSIGN_COMMON_ALIAS(I, beginav_save); |
32855229 | 700 | cv = newXS("B::end_av", intrpvar_sv_common, file); |
115ff745 | 701 | ASSIGN_COMMON_ALIAS(I, endav); |
32855229 | 702 | cv = newXS("B::main_cv", intrpvar_sv_common, file); |
115ff745 | 703 | ASSIGN_COMMON_ALIAS(I, main_cv); |
32855229 | 704 | cv = newXS("B::inc_gv", intrpvar_sv_common, file); |
115ff745 | 705 | ASSIGN_COMMON_ALIAS(I, incgv); |
32855229 | 706 | cv = newXS("B::defstash", intrpvar_sv_common, file); |
115ff745 | 707 | ASSIGN_COMMON_ALIAS(I, defstash); |
32855229 | 708 | cv = newXS("B::curstash", intrpvar_sv_common, file); |
115ff745 | 709 | ASSIGN_COMMON_ALIAS(I, curstash); |
5f7e30c4 | 710 | #ifdef PL_formfeed |
32855229 | 711 | cv = newXS("B::formfeed", intrpvar_sv_common, file); |
115ff745 | 712 | ASSIGN_COMMON_ALIAS(I, formfeed); |
5f7e30c4 | 713 | #endif |
32855229 NC |
714 | #ifdef USE_ITHREADS |
715 | cv = newXS("B::regex_padav", intrpvar_sv_common, file); | |
115ff745 | 716 | ASSIGN_COMMON_ALIAS(I, regex_padav); |
32855229 NC |
717 | #endif |
718 | cv = newXS("B::warnhook", intrpvar_sv_common, file); | |
115ff745 | 719 | ASSIGN_COMMON_ALIAS(I, warnhook); |
32855229 | 720 | cv = newXS("B::diehook", intrpvar_sv_common, file); |
115ff745 | 721 | ASSIGN_COMMON_ALIAS(I, diehook); |
32855229 NC |
722 | } |
723 | ||
5f7e30c4 NC |
724 | #ifndef PL_formfeed |
725 | ||
726 | void | |
727 | formfeed() | |
728 | PPCODE: | |
729 | PUSHs(make_sv_object(aTHX_ GvSV(gv_fetchpvs("\f", GV_ADD, SVt_PV)))); | |
730 | ||
731 | #endif | |
732 | ||
7a2c16aa NC |
733 | long |
734 | amagic_generation() | |
735 | CODE: | |
736 | RETVAL = PL_amagic_generation; | |
737 | OUTPUT: | |
738 | RETVAL | |
739 | ||
8ae5a962 | 740 | void |
7a2c16aa | 741 | comppadlist() |
7261499d FC |
742 | PREINIT: |
743 | PADLIST *padlist = CvPADLIST(PL_main_cv ? PL_main_cv : PL_compcv); | |
8ae5a962 | 744 | PPCODE: |
86d2498c | 745 | #ifdef PadlistARRAY |
7261499d FC |
746 | { |
747 | SV * const rv = sv_newmortal(); | |
748 | sv_setiv(newSVrv(rv, padlist ? "B::PADLIST" : "B::NULL"), | |
749 | PTR2IV(padlist)); | |
750 | PUSHs(rv); | |
751 | } | |
752 | #else | |
753 | PUSHs(make_sv_object(aTHX_ (SV *)padlist)); | |
754 | #endif | |
7a2c16aa | 755 | |
8ae5a962 | 756 | void |
a4aabc83 NC |
757 | sv_undef() |
758 | ALIAS: | |
759 | sv_no = 1 | |
760 | sv_yes = 2 | |
8ae5a962 | 761 | PPCODE: |
0c74f67f NC |
762 | PUSHs(make_sv_object(aTHX_ ix > 1 ? &PL_sv_yes |
763 | : ix < 1 ? &PL_sv_undef | |
764 | : &PL_sv_no)); | |
a4aabc83 | 765 | |
6079961f | 766 | void |
e97701b4 NC |
767 | main_root() |
768 | ALIAS: | |
769 | main_start = 1 | |
6079961f NC |
770 | PPCODE: |
771 | PUSHs(make_op_object(aTHX_ ix ? PL_main_start : PL_main_root)); | |
e97701b4 | 772 | |
2edf0c1d NC |
773 | UV |
774 | sub_generation() | |
775 | ALIAS: | |
776 | dowarn = 1 | |
777 | CODE: | |
778 | RETVAL = ix ? PL_dowarn : PL_sub_generation; | |
779 | OUTPUT: | |
780 | RETVAL | |
781 | ||
a8a597b2 | 782 | void |
20f7624e NC |
783 | walkoptree(op, method) |
784 | B::OP op | |
5d7488b2 | 785 | const char * method |
cea2e8a9 | 786 | CODE: |
20f7624e | 787 | (void) walkoptree(aTHX_ op, method, &PL_sv_undef); |
a8a597b2 MB |
788 | |
789 | int | |
790 | walkoptree_debug(...) | |
791 | CODE: | |
89ca4ac7 | 792 | dMY_CXT; |
a8a597b2 MB |
793 | RETVAL = walkoptree_debug; |
794 | if (items > 0 && SvTRUE(ST(1))) | |
795 | walkoptree_debug = 1; | |
796 | OUTPUT: | |
797 | RETVAL | |
798 | ||
56431972 | 799 | #define address(sv) PTR2IV(sv) |
a8a597b2 MB |
800 | |
801 | IV | |
802 | address(sv) | |
803 | SV * sv | |
804 | ||
8ae5a962 | 805 | void |
a8a597b2 MB |
806 | svref_2object(sv) |
807 | SV * sv | |
8ae5a962 | 808 | PPCODE: |
a8a597b2 MB |
809 | if (!SvROK(sv)) |
810 | croak("argument is not a reference"); | |
0c74f67f | 811 | PUSHs(make_sv_object(aTHX_ SvRV(sv))); |
0cc1d052 NIS |
812 | |
813 | void | |
814 | opnumber(name) | |
5d7488b2 | 815 | const char * name |
0cc1d052 NIS |
816 | CODE: |
817 | { | |
818 | int i; | |
819 | IV result = -1; | |
820 | ST(0) = sv_newmortal(); | |
821 | if (strncmp(name,"pp_",3) == 0) | |
822 | name += 3; | |
823 | for (i = 0; i < PL_maxo; i++) | |
824 | { | |
825 | if (strcmp(name, PL_op_name[i]) == 0) | |
826 | { | |
827 | result = i; | |
828 | break; | |
829 | } | |
830 | } | |
831 | sv_setiv(ST(0),result); | |
832 | } | |
a8a597b2 MB |
833 | |
834 | void | |
835 | ppname(opnum) | |
836 | int opnum | |
837 | CODE: | |
838 | ST(0) = sv_newmortal(); | |
cc5b6bab NC |
839 | if (opnum >= 0 && opnum < PL_maxo) |
840 | Perl_sv_setpvf(aTHX_ ST(0), "pp_%s", PL_op_name[opnum]); | |
a8a597b2 MB |
841 | |
842 | void | |
843 | hash(sv) | |
844 | SV * sv | |
845 | CODE: | |
a8a597b2 MB |
846 | STRLEN len; |
847 | U32 hash = 0; | |
8c5b7c71 | 848 | const char *s = SvPVbyte(sv, len); |
c32d3395 | 849 | PERL_HASH(hash, s, len); |
90b16320 | 850 | ST(0) = sv_2mortal(Perl_newSVpvf(aTHX_ "0x%"UVxf, (UV)hash)); |
a8a597b2 MB |
851 | |
852 | #define cast_I32(foo) (I32)foo | |
853 | IV | |
854 | cast_I32(i) | |
855 | IV i | |
856 | ||
857 | void | |
858 | minus_c() | |
651233d2 NC |
859 | ALIAS: |
860 | save_BEGINs = 1 | |
a8a597b2 | 861 | CODE: |
651233d2 NC |
862 | if (ix) |
863 | PL_savebegin = TRUE; | |
864 | else | |
865 | PL_minus_c = TRUE; | |
059a8bb7 | 866 | |
847ded71 | 867 | void |
a8a597b2 MB |
868 | cstring(sv) |
869 | SV * sv | |
84556172 NC |
870 | ALIAS: |
871 | perlstring = 1 | |
9e380ad4 | 872 | cchar = 2 |
09e97b95 | 873 | PPCODE: |
847ded71 | 874 | PUSHs(ix == 2 ? cchar(aTHX_ sv) : cstring(aTHX_ sv, (bool)ix)); |
a8a597b2 MB |
875 | |
876 | void | |
877 | threadsv_names() | |
878 | PPCODE: | |
f5ba1307 | 879 | |
a8a597b2 | 880 | |
9488fb36 | 881 | |
a9ed1a44 | 882 | |
fdbacc68 | 883 | MODULE = B PACKAGE = B::OP |
a8a597b2 | 884 | |
651aa52e | 885 | size_t |
fdbacc68 | 886 | size(o) |
651aa52e AE |
887 | B::OP o |
888 | CODE: | |
889 | RETVAL = opsizes[cc_opclass(aTHX_ o)]; | |
890 | OUTPUT: | |
891 | RETVAL | |
892 | ||
9b1961be NC |
893 | # The type checking code in B has always been identical for all OP types, |
894 | # irrespective of whether the action is actually defined on that OP. | |
895 | # We should fix this | |
086f9b42 | 896 | void |
9b1961be | 897 | next(o) |
a8a597b2 | 898 | B::OP o |
9b1961be | 899 | ALIAS: |
bec746fe DM |
900 | B::OP::next = 0 |
901 | B::OP::sibling = 1 | |
902 | B::OP::targ = 2 | |
903 | B::OP::flags = 3 | |
904 | B::OP::private = 4 | |
905 | B::UNOP::first = 5 | |
906 | B::BINOP::last = 6 | |
907 | B::LOGOP::other = 7 | |
908 | B::PMOP::pmreplstart = 8 | |
909 | B::LOOP::redoop = 9 | |
910 | B::LOOP::nextop = 10 | |
911 | B::LOOP::lastop = 11 | |
912 | B::PMOP::pmflags = 12 | |
913 | B::PMOP::code_list = 13 | |
914 | B::SVOP::sv = 14 | |
915 | B::SVOP::gv = 15 | |
916 | B::PADOP::padix = 16 | |
917 | B::COP::cop_seq = 17 | |
918 | B::COP::line = 18 | |
919 | B::COP::hints = 19 | |
920 | B::PMOP::pmoffset = 20 | |
921 | B::COP::filegv = 21 | |
922 | B::COP::file = 22 | |
923 | B::COP::stash = 23 | |
924 | B::COP::stashpv = 24 | |
925 | B::COP::stashoff = 25 | |
9b1961be NC |
926 | PREINIT: |
927 | char *ptr; | |
086f9b42 | 928 | SV *ret; |
bec746fe DM |
929 | I32 type; |
930 | I32 offset; | |
931 | STRLEN len; | |
086f9b42 | 932 | PPCODE: |
bec746fe DM |
933 | if (ix < 0 || ix > 25) |
934 | croak("Illegal alias %d for B::*next", (int)ix); | |
935 | offset = op_methods[ix].offset; | |
936 | ||
937 | /* handle non-direct field access */ | |
938 | ||
939 | if (offset < 0) { | |
940 | switch (ix) { | |
941 | #ifdef USE_ITHREADS | |
942 | case 21: /* filegv */ | |
943 | ret = make_sv_object(aTHX_ (SV *)CopFILEGV((COP*)o)); | |
944 | break; | |
945 | #endif | |
946 | #ifndef USE_ITHREADS | |
947 | case 22: /* file */ | |
948 | ret = sv_2mortal(newSVpv(CopFILE((COP*)o), 0)); | |
949 | break; | |
950 | #endif | |
951 | #ifdef USE_ITHREADS | |
952 | case 23: /* stash */ | |
953 | ret = make_sv_object(aTHX_ (SV *)CopSTASH((COP*)o)); | |
954 | break; | |
955 | #endif | |
956 | #if PERL_VERSION >= 17 || !defined USE_ITHREADS | |
957 | case 24: /* stashpv */ | |
958 | # if PERL_VERSION >= 17 | |
959 | ret = sv_2mortal(CopSTASH((COP*)o) | |
960 | && SvTYPE(CopSTASH((COP*)o)) == SVt_PVHV | |
961 | ? newSVhek(HvNAME_HEK(CopSTASH((COP*)o))) | |
962 | : &PL_sv_undef); | |
963 | # else | |
964 | ret = sv_2mortal(newSVpv(CopSTASHPV((COP*)o), 0)); | |
965 | # endif | |
966 | break; | |
967 | #endif | |
968 | default: | |
969 | croak("method %s not implemented", op_methods[ix].name); | |
970 | } | |
971 | ST(0) = ret; | |
972 | XSRETURN(1); | |
973 | } | |
974 | ||
975 | /* do a direct structure offset lookup */ | |
976 | ||
977 | ptr = (char *)o + offset; | |
978 | type = op_methods[ix].type; | |
979 | switch ((U8)(type >> 16)) { | |
980 | case (U8)(OPp >> 16): | |
6079961f NC |
981 | ret = make_op_object(aTHX_ *((OP **)ptr)); |
982 | break; | |
bec746fe | 983 | case (U8)(PADOFFSETp >> 16): |
086f9b42 NC |
984 | ret = sv_2mortal(newSVuv(*((PADOFFSET*)ptr))); |
985 | break; | |
986 | case (U8)(U8p >> 16): | |
987 | ret = sv_2mortal(newSVuv(*((U8*)ptr))); | |
988 | break; | |
a78b89ef NC |
989 | case (U8)(U32p >> 16): |
990 | ret = sv_2mortal(newSVuv(*((U32*)ptr))); | |
991 | break; | |
ba7298e3 | 992 | case (U8)(SVp >> 16): |
0c74f67f | 993 | ret = make_sv_object(aTHX_ *((SV **)ptr)); |
ba7298e3 | 994 | break; |
39e120c1 NC |
995 | case (U8)(line_tp >> 16): |
996 | ret = sv_2mortal(newSVuv(*((line_t *)ptr))); | |
997 | break; | |
657e3fc2 NC |
998 | case (U8)(IVp >> 16): |
999 | ret = sv_2mortal(newSViv(*((IV*)ptr))); | |
1000 | break; | |
a9ed1a44 NC |
1001 | case (U8)(char_pp >> 16): |
1002 | ret = sv_2mortal(newSVpv(*((char **)ptr), 0)); | |
1003 | break; | |
c33e8be1 | 1004 | default: |
bec746fe | 1005 | croak("Illegal type 0x%08x for B::*next", (unsigned)type); |
c33e8be1 | 1006 | |
086f9b42 NC |
1007 | } |
1008 | ST(0) = ret; | |
1009 | XSRETURN(1); | |
a8a597b2 MB |
1010 | |
1011 | char * | |
fdbacc68 | 1012 | name(o) |
3f872cb9 | 1013 | B::OP o |
d2b33dc1 NC |
1014 | ALIAS: |
1015 | desc = 1 | |
3f872cb9 | 1016 | CODE: |
1830b3d9 | 1017 | RETVAL = (char *)(ix ? OP_DESC(o) : OP_NAME(o)); |
8063af02 DM |
1018 | OUTPUT: |
1019 | RETVAL | |
3f872cb9 | 1020 | |
8063af02 | 1021 | void |
fdbacc68 | 1022 | ppaddr(o) |
a8a597b2 | 1023 | B::OP o |
dc333d64 GS |
1024 | PREINIT: |
1025 | int i; | |
cc5b6bab | 1026 | SV *sv; |
a8a597b2 | 1027 | CODE: |
cc5b6bab NC |
1028 | sv = sv_2mortal(Perl_newSVpvf(aTHX_ "PL_ppaddr[OP_%s]", |
1029 | PL_op_name[o->op_type])); | |
7c436af3 | 1030 | for (i=13; (STRLEN)i < SvCUR(sv); ++i) |
dc333d64 | 1031 | SvPVX(sv)[i] = toUPPER(SvPVX(sv)[i]); |
dc333d64 | 1032 | ST(0) = sv; |
a8a597b2 | 1033 | |
dd8be0e4 NC |
1034 | # These 3 are all bitfields, so we can't take their addresses. |
1035 | UV | |
fdbacc68 | 1036 | type(o) |
2814eb74 | 1037 | B::OP o |
dd8be0e4 NC |
1038 | ALIAS: |
1039 | opt = 1 | |
1040 | spare = 2 | |
1041 | CODE: | |
1042 | switch(ix) { | |
1043 | case 1: | |
1044 | RETVAL = o->op_opt; | |
1045 | break; | |
1046 | case 2: | |
1047 | RETVAL = o->op_spare; | |
1048 | break; | |
1049 | default: | |
1050 | RETVAL = o->op_type; | |
1051 | } | |
1052 | OUTPUT: | |
1053 | RETVAL | |
2814eb74 | 1054 | |
7252851f | 1055 | |
1df34986 | 1056 | void |
fdbacc68 | 1057 | oplist(o) |
1df34986 AE |
1058 | B::OP o |
1059 | PPCODE: | |
1060 | SP = oplist(aTHX_ o, SP); | |
1061 | ||
fdbacc68 | 1062 | MODULE = B PACKAGE = B::LISTOP |
a8a597b2 | 1063 | |
c03c2844 | 1064 | U32 |
fdbacc68 | 1065 | children(o) |
c03c2844 SM |
1066 | B::LISTOP o |
1067 | OP * kid = NO_INIT | |
1068 | int i = NO_INIT | |
1069 | CODE: | |
c03c2844 SM |
1070 | i = 0; |
1071 | for (kid = o->op_first; kid; kid = kid->op_sibling) | |
1072 | i++; | |
8063af02 DM |
1073 | RETVAL = i; |
1074 | OUTPUT: | |
016e8ce0 | 1075 | RETVAL |
a8a597b2 MB |
1076 | |
1077 | MODULE = B PACKAGE = B::PMOP PREFIX = PMOP_ | |
1078 | ||
20e98b0f | 1079 | |
a8a597b2 MB |
1080 | void |
1081 | PMOP_pmreplroot(o) | |
1082 | B::PMOP o | |
a8a597b2 | 1083 | CODE: |
a8a597b2 | 1084 | if (o->op_type == OP_PUSHRE) { |
35633035 | 1085 | #ifdef USE_ITHREADS |
9fdb8483 | 1086 | ST(0) = sv_newmortal(); |
20e98b0f | 1087 | sv_setiv(ST(0), o->op_pmreplrootu.op_pmtargetoff); |
35633035 | 1088 | #else |
20e98b0f | 1089 | GV *const target = o->op_pmreplrootu.op_pmtargetgv; |
9fdb8483 | 1090 | ST(0) = sv_newmortal(); |
20e98b0f NC |
1091 | sv_setiv(newSVrv(ST(0), target ? |
1092 | svclassnames[SvTYPE((SV*)target)] : "B::SV"), | |
1093 | PTR2IV(target)); | |
35633035 | 1094 | #endif |
20e98b0f NC |
1095 | } |
1096 | else { | |
1097 | OP *const root = o->op_pmreplrootu.op_pmreplroot; | |
6079961f | 1098 | ST(0) = make_op_object(aTHX_ root); |
20e98b0f NC |
1099 | } |
1100 | ||
20e98b0f | 1101 | |
9d2bbe64 | 1102 | #ifdef USE_ITHREADS |
016e8ce0 | 1103 | #define PMOP_pmstashpv(o) PmopSTASHPV(o); |
9d2bbe64 | 1104 | |
651aa52e AE |
1105 | char* |
1106 | PMOP_pmstashpv(o) | |
1107 | B::PMOP o | |
1108 | ||
1109 | #else | |
1110 | ||
8ae5a962 | 1111 | void |
651aa52e AE |
1112 | PMOP_pmstash(o) |
1113 | B::PMOP o | |
8ae5a962 | 1114 | PPCODE: |
0c74f67f | 1115 | PUSHs(make_sv_object(aTHX_ (SV *) PmopSTASH(o))); |
651aa52e | 1116 | |
9d2bbe64 MB |
1117 | #endif |
1118 | ||
7c1f70cb | 1119 | |
a8a597b2 MB |
1120 | void |
1121 | PMOP_precomp(o) | |
1122 | B::PMOP o | |
021d294f NC |
1123 | PREINIT: |
1124 | dXSI32; | |
1125 | REGEXP *rx; | |
a8a597b2 | 1126 | CODE: |
aaa362c4 | 1127 | rx = PM_GETRE(o); |
c737faaf | 1128 | ST(0) = sv_newmortal(); |
021d294f | 1129 | if (rx) { |
021d294f NC |
1130 | if (ix) { |
1131 | sv_setuv(ST(0), RX_EXTFLAGS(rx)); | |
35633035 DM |
1132 | } |
1133 | else { | |
021d294f NC |
1134 | sv_setpvn(ST(0), RX_PRECOMP(rx), RX_PRELEN(rx)); |
1135 | } | |
1136 | } | |
c737faaf | 1137 | |
021d294f NC |
1138 | BOOT: |
1139 | { | |
1140 | CV *cv; | |
021d294f NC |
1141 | cv = newXS("B::PMOP::reflags", XS_B__PMOP_precomp, __FILE__); |
1142 | XSANY.any_i32 = 1; | |
021d294f NC |
1143 | } |
1144 | ||
c518d492 | 1145 | MODULE = B PACKAGE = B::PADOP |
7934575e | 1146 | |
8ae5a962 | 1147 | void |
c518d492 | 1148 | sv(o) |
7934575e | 1149 | B::PADOP o |
8ae5a962 NC |
1150 | PREINIT: |
1151 | SV *ret; | |
c518d492 NC |
1152 | ALIAS: |
1153 | gv = 1 | |
8ae5a962 | 1154 | PPCODE: |
c518d492 NC |
1155 | /* It happens that the output typemaps for B::SV and B::GV are |
1156 | identical. The "smarts" are in make_sv_object(), which determines | |
1157 | which class to use based on SvTYPE(), rather than anything baked in | |
1158 | at compile time. */ | |
1159 | if (o->op_padix) { | |
8ae5a962 NC |
1160 | ret = PAD_SVl(o->op_padix); |
1161 | if (ix && SvTYPE(ret) != SVt_PVGV) | |
1162 | ret = NULL; | |
c518d492 | 1163 | } else { |
8ae5a962 | 1164 | ret = NULL; |
c518d492 | 1165 | } |
0c74f67f | 1166 | PUSHs(make_sv_object(aTHX_ ret)); |
a8a597b2 | 1167 | |
fdbacc68 | 1168 | MODULE = B PACKAGE = B::PVOP |
a8a597b2 MB |
1169 | |
1170 | void | |
fdbacc68 | 1171 | pv(o) |
a8a597b2 MB |
1172 | B::PVOP o |
1173 | CODE: | |
1174 | /* | |
bec89253 | 1175 | * OP_TRANS uses op_pv to point to a table of 256 or >=258 shorts |
a8a597b2 MB |
1176 | * whereas other PVOPs point to a null terminated string. |
1177 | */ | |
bb16bae8 | 1178 | if ((o->op_type == OP_TRANS || o->op_type == OP_TRANSR) && |
bec89253 RH |
1179 | (o->op_private & OPpTRANS_COMPLEMENT) && |
1180 | !(o->op_private & OPpTRANS_DELETE)) | |
1181 | { | |
5d7488b2 AL |
1182 | const short* const tbl = (short*)o->op_pv; |
1183 | const short entries = 257 + tbl[256]; | |
d3d34884 | 1184 | ST(0) = newSVpvn_flags(o->op_pv, entries * sizeof(short), SVs_TEMP); |
bec89253 | 1185 | } |
bb16bae8 | 1186 | else if (o->op_type == OP_TRANS || o->op_type == OP_TRANSR) { |
d3d34884 | 1187 | ST(0) = newSVpvn_flags(o->op_pv, 256 * sizeof(short), SVs_TEMP); |
bec89253 RH |
1188 | } |
1189 | else | |
d3d34884 | 1190 | ST(0) = newSVpvn_flags(o->op_pv, strlen(o->op_pv), SVs_TEMP); |
a8a597b2 | 1191 | |
4b65a919 | 1192 | #define COP_label(o) CopLABEL(o) |
a8a597b2 MB |
1193 | |
1194 | MODULE = B PACKAGE = B::COP PREFIX = COP_ | |
1195 | ||
d5b8ed54 NC |
1196 | const char * |
1197 | COP_label(o) | |
1198 | B::COP o | |
1199 | ||
a9ed1a44 | 1200 | |
1df34986 | 1201 | |
a8a597b2 MB |
1202 | I32 |
1203 | COP_arybase(o) | |
1204 | B::COP o | |
e1dccc0d Z |
1205 | CODE: |
1206 | RETVAL = 0; | |
1207 | OUTPUT: | |
1208 | RETVAL | |
a8a597b2 | 1209 | |
5c3c3f81 | 1210 | void |
b295d113 TH |
1211 | COP_warnings(o) |
1212 | B::COP o | |
0a49bb24 NC |
1213 | ALIAS: |
1214 | io = 1 | |
1215 | PPCODE: | |
0a49bb24 | 1216 | ST(0) = ix ? make_cop_io_object(aTHX_ o) : make_warnings_object(aTHX_ o); |
11bcd5da | 1217 | XSRETURN(1); |
6e6a1aef | 1218 | |
13d356f3 | 1219 | |
fd9f6265 JJ |
1220 | B::RHE |
1221 | COP_hints_hash(o) | |
1222 | B::COP o | |
1223 | CODE: | |
20439bc7 | 1224 | RETVAL = CopHINTHASH_get(o); |
fd9f6265 JJ |
1225 | OUTPUT: |
1226 | RETVAL | |
1227 | ||
e412117e | 1228 | |
651aa52e AE |
1229 | MODULE = B PACKAGE = B::SV |
1230 | ||
de64752d NC |
1231 | #define MAGICAL_FLAG_BITS (SVs_GMG|SVs_SMG|SVs_RMG) |
1232 | ||
651aa52e | 1233 | U32 |
de64752d | 1234 | REFCNT(sv) |
651aa52e | 1235 | B::SV sv |
de64752d NC |
1236 | ALIAS: |
1237 | FLAGS = 0xFFFFFFFF | |
1238 | SvTYPE = SVTYPEMASK | |
1239 | POK = SVf_POK | |
1240 | ROK = SVf_ROK | |
1241 | MAGICAL = MAGICAL_FLAG_BITS | |
1242 | CODE: | |
1243 | RETVAL = ix ? (SvFLAGS(sv) & (U32)ix) : SvREFCNT(sv); | |
1244 | OUTPUT: | |
1245 | RETVAL | |
651aa52e | 1246 | |
9efba5c8 | 1247 | void |
429a5ce7 SM |
1248 | object_2svref(sv) |
1249 | B::SV sv | |
9efba5c8 NC |
1250 | PPCODE: |
1251 | ST(0) = sv_2mortal(newRV(sv)); | |
1252 | XSRETURN(1); | |
1253 | ||
a8a597b2 MB |
1254 | MODULE = B PACKAGE = B::IV PREFIX = Sv |
1255 | ||
1256 | IV | |
1257 | SvIV(sv) | |
1258 | B::IV sv | |
1259 | ||
e4da9d6a | 1260 | MODULE = B PACKAGE = B::IV |
a8a597b2 | 1261 | |
e4da9d6a NC |
1262 | #define sv_SVp 0x00000 |
1263 | #define sv_IVp 0x10000 | |
1264 | #define sv_UVp 0x20000 | |
1265 | #define sv_STRLENp 0x30000 | |
1266 | #define sv_U32p 0x40000 | |
1267 | #define sv_U8p 0x50000 | |
1268 | #define sv_char_pp 0x60000 | |
1269 | #define sv_NVp 0x70000 | |
6782c6e0 | 1270 | #define sv_char_p 0x80000 |
3da43c35 | 1271 | #define sv_SSize_tp 0x90000 |
ffc5d9fc NC |
1272 | #define sv_I32p 0xA0000 |
1273 | #define sv_U16p 0xB0000 | |
e4da9d6a NC |
1274 | |
1275 | #define IV_ivx_ix sv_IVp | offsetof(struct xpviv, xiv_iv) | |
1276 | #define IV_uvx_ix sv_UVp | offsetof(struct xpvuv, xuv_uv) | |
1277 | #define NV_nvx_ix sv_NVp | offsetof(struct xpvnv, xnv_u.xnv_nv) | |
1278 | ||
e4da9d6a NC |
1279 | #define NV_cop_seq_range_low_ix \ |
1280 | sv_U32p | offsetof(struct xpvnv, xnv_u.xpad_cop_seq.xlow) | |
1281 | #define NV_cop_seq_range_high_ix \ | |
1282 | sv_U32p | offsetof(struct xpvnv, xnv_u.xpad_cop_seq.xhigh) | |
1283 | #define NV_parent_pad_index_ix \ | |
1284 | sv_U32p | offsetof(struct xpvnv, xnv_u.xpad_cop_seq.xlow) | |
1285 | #define NV_parent_fakelex_flags_ix \ | |
1286 | sv_U32p | offsetof(struct xpvnv, xnv_u.xpad_cop_seq.xhigh) | |
0ca04487 | 1287 | |
6782c6e0 NC |
1288 | #define PV_cur_ix sv_STRLENp | offsetof(struct xpv, xpv_cur) |
1289 | #define PV_len_ix sv_STRLENp | offsetof(struct xpv, xpv_len) | |
1290 | ||
1291 | #define PVMG_stash_ix sv_SVp | offsetof(struct xpvmg, xmg_stash) | |
1292 | ||
35633035 | 1293 | #if PERL_VERSION > 14 |
ced45495 NC |
1294 | # define PVBM_useful_ix sv_I32p | offsetof(struct xpvgv, xnv_u.xbm_s.xbm_useful) |
1295 | # define PVBM_previous_ix sv_UVp | offsetof(struct xpvuv, xuv_uv) | |
35633035 | 1296 | #else |
91a71e08 NC |
1297 | #define PVBM_useful_ix sv_I32p | offsetof(struct xpvgv, xiv_u.xivu_i32) |
1298 | #define PVBM_previous_ix sv_U32p | offsetof(struct xpvgv, xnv_u.xbm_s.xbm_previous) | |
91a71e08 NC |
1299 | #endif |
1300 | ||
35633035 DM |
1301 | #define PVBM_rare_ix sv_U8p | offsetof(struct xpvgv, xnv_u.xbm_s.xbm_rare) |
1302 | ||
6782c6e0 NC |
1303 | #define PVLV_targoff_ix sv_U32p | offsetof(struct xpvlv, xlv_targoff) |
1304 | #define PVLV_targlen_ix sv_U32p | offsetof(struct xpvlv, xlv_targlen) | |
1305 | #define PVLV_targ_ix sv_SVp | offsetof(struct xpvlv, xlv_targ) | |
1306 | #define PVLV_type_ix sv_char_p | offsetof(struct xpvlv, xlv_type) | |
1307 | ||
f1f19364 NC |
1308 | #define PVGV_stash_ix sv_SVp | offsetof(struct xpvgv, xnv_u.xgv_stash) |
1309 | #define PVGV_flags_ix sv_STRLENp | offsetof(struct xpvgv, xpv_cur) | |
55440d31 | 1310 | #define PVIO_lines_ix sv_IVp | offsetof(struct xpvio, xiv_iv) |
f1f19364 | 1311 | |
55440d31 NC |
1312 | #define PVIO_page_ix sv_IVp | offsetof(struct xpvio, xio_page) |
1313 | #define PVIO_page_len_ix sv_IVp | offsetof(struct xpvio, xio_page_len) | |
1314 | #define PVIO_lines_left_ix sv_IVp | offsetof(struct xpvio, xio_lines_left) | |
1315 | #define PVIO_top_name_ix sv_char_pp | offsetof(struct xpvio, xio_top_name) | |
1316 | #define PVIO_top_gv_ix sv_SVp | offsetof(struct xpvio, xio_top_gv) | |
1317 | #define PVIO_fmt_name_ix sv_char_pp | offsetof(struct xpvio, xio_fmt_name) | |
1318 | #define PVIO_fmt_gv_ix sv_SVp | offsetof(struct xpvio, xio_fmt_gv) | |
1319 | #define PVIO_bottom_name_ix sv_char_pp | offsetof(struct xpvio, xio_bottom_name) | |
1320 | #define PVIO_bottom_gv_ix sv_SVp | offsetof(struct xpvio, xio_bottom_gv) | |
1321 | #define PVIO_type_ix sv_char_p | offsetof(struct xpvio, xio_type) | |
1322 | #define PVIO_flags_ix sv_U8p | offsetof(struct xpvio, xio_flags) | |
1323 | ||
3da43c35 NC |
1324 | #define PVAV_max_ix sv_SSize_tp | offsetof(struct xpvav, xav_max) |
1325 | ||
ffc5d9fc | 1326 | #define PVCV_stash_ix sv_SVp | offsetof(struct xpvcv, xcv_stash) |
b290562e FC |
1327 | #if PERL_VERSION > 17 || (PERL_VERSION == 17 && PERL_SUBVERSION >= 3) |
1328 | # define PVCV_gv_ix sv_SVp | offsetof(struct xpvcv, xcv_gv_u.xcv_gv) | |
1329 | #else | |
1330 | # define PVCV_gv_ix sv_SVp | offsetof(struct xpvcv, xcv_gv) | |
1331 | #endif | |
ffc5d9fc | 1332 | #define PVCV_file_ix sv_char_pp | offsetof(struct xpvcv, xcv_file) |
ffc5d9fc NC |
1333 | #define PVCV_outside_ix sv_SVp | offsetof(struct xpvcv, xcv_outside) |
1334 | #define PVCV_outside_seq_ix sv_U32p | offsetof(struct xpvcv, xcv_outside_seq) | |
1335 | #define PVCV_flags_ix sv_U16p | offsetof(struct xpvcv, xcv_flags) | |
1336 | ||
d65a2b0a NC |
1337 | #define PVHV_max_ix sv_STRLENp | offsetof(struct xpvhv, xhv_max) |
1338 | ||
1339 | #if PERL_VERSION > 12 | |
1340 | #define PVHV_keys_ix sv_STRLENp | offsetof(struct xpvhv, xhv_keys) | |
1341 | #else | |
1342 | #define PVHV_keys_ix sv_IVp | offsetof(struct xpvhv, xhv_keys) | |
1343 | #endif | |
1344 | ||
e4da9d6a NC |
1345 | # The type checking code in B has always been identical for all SV types, |
1346 | # irrespective of whether the action is actually defined on that SV. | |
1347 | # We should fix this | |
1348 | void | |
1349 | IVX(sv) | |
1350 | B::SV sv | |
1351 | ALIAS: | |
1352 | B::IV::IVX = IV_ivx_ix | |
1353 | B::IV::UVX = IV_uvx_ix | |
1354 | B::NV::NVX = NV_nvx_ix | |
1355 | B::NV::COP_SEQ_RANGE_LOW = NV_cop_seq_range_low_ix | |
1356 | B::NV::COP_SEQ_RANGE_HIGH = NV_cop_seq_range_high_ix | |
1357 | B::NV::PARENT_PAD_INDEX = NV_parent_pad_index_ix | |
1358 | B::NV::PARENT_FAKELEX_FLAGS = NV_parent_fakelex_flags_ix | |
6782c6e0 NC |
1359 | B::PV::CUR = PV_cur_ix |
1360 | B::PV::LEN = PV_len_ix | |
1361 | B::PVMG::SvSTASH = PVMG_stash_ix | |
1362 | B::PVLV::TARGOFF = PVLV_targoff_ix | |
1363 | B::PVLV::TARGLEN = PVLV_targlen_ix | |
1364 | B::PVLV::TARG = PVLV_targ_ix | |
1365 | B::PVLV::TYPE = PVLV_type_ix | |
f1f19364 NC |
1366 | B::GV::STASH = PVGV_stash_ix |
1367 | B::GV::GvFLAGS = PVGV_flags_ix | |
91a71e08 NC |
1368 | B::BM::USEFUL = PVBM_useful_ix |
1369 | B::BM::PREVIOUS = PVBM_previous_ix | |
1370 | B::BM::RARE = PVBM_rare_ix | |
55440d31 NC |
1371 | B::IO::LINES = PVIO_lines_ix |
1372 | B::IO::PAGE = PVIO_page_ix | |
1373 | B::IO::PAGE_LEN = PVIO_page_len_ix | |
1374 | B::IO::LINES_LEFT = PVIO_lines_left_ix | |
1375 | B::IO::TOP_NAME = PVIO_top_name_ix | |
1376 | B::IO::TOP_GV = PVIO_top_gv_ix | |
1377 | B::IO::FMT_NAME = PVIO_fmt_name_ix | |
1378 | B::IO::FMT_GV = PVIO_fmt_gv_ix | |
1379 | B::IO::BOTTOM_NAME = PVIO_bottom_name_ix | |
1380 | B::IO::BOTTOM_GV = PVIO_bottom_gv_ix | |
1381 | B::IO::IoTYPE = PVIO_type_ix | |
1382 | B::IO::IoFLAGS = PVIO_flags_ix | |
3da43c35 | 1383 | B::AV::MAX = PVAV_max_ix |
ffc5d9fc NC |
1384 | B::CV::STASH = PVCV_stash_ix |
1385 | B::CV::GV = PVCV_gv_ix | |
1386 | B::CV::FILE = PVCV_file_ix | |
ffc5d9fc NC |
1387 | B::CV::OUTSIDE = PVCV_outside_ix |
1388 | B::CV::OUTSIDE_SEQ = PVCV_outside_seq_ix | |
1389 | B::CV::CvFLAGS = PVCV_flags_ix | |
d65a2b0a NC |
1390 | B::HV::MAX = PVHV_max_ix |
1391 | B::HV::KEYS = PVHV_keys_ix | |
e4da9d6a NC |
1392 | PREINIT: |
1393 | char *ptr; | |
1394 | SV *ret; | |
1395 | PPCODE: | |
1396 | ptr = (ix & 0xFFFF) + (char *)SvANY(sv); | |
1397 | switch ((U8)(ix >> 16)) { | |
1398 | case (U8)(sv_SVp >> 16): | |
0c74f67f | 1399 | ret = make_sv_object(aTHX_ *((SV **)ptr)); |
e4da9d6a NC |
1400 | break; |
1401 | case (U8)(sv_IVp >> 16): | |
1402 | ret = sv_2mortal(newSViv(*((IV *)ptr))); | |
1403 | break; | |
1404 | case (U8)(sv_UVp >> 16): | |
1405 | ret = sv_2mortal(newSVuv(*((UV *)ptr))); | |
1406 | break; | |
6782c6e0 NC |
1407 | case (U8)(sv_STRLENp >> 16): |
1408 | ret = sv_2mortal(newSVuv(*((STRLEN *)ptr))); | |
1409 | break; | |
e4da9d6a NC |
1410 | case (U8)(sv_U32p >> 16): |
1411 | ret = sv_2mortal(newSVuv(*((U32 *)ptr))); | |
1412 | break; | |
1413 | case (U8)(sv_U8p >> 16): | |
1414 | ret = sv_2mortal(newSVuv(*((U8 *)ptr))); | |
1415 | break; | |
1416 | case (U8)(sv_char_pp >> 16): | |
1417 | ret = sv_2mortal(newSVpv(*((char **)ptr), 0)); | |
1418 | break; | |
1419 | case (U8)(sv_NVp >> 16): | |
1420 | ret = sv_2mortal(newSVnv(*((NV *)ptr))); | |
1421 | break; | |
6782c6e0 NC |
1422 | case (U8)(sv_char_p >> 16): |
1423 | ret = newSVpvn_flags((char *)ptr, 1, SVs_TEMP); | |
1424 | break; | |
3da43c35 NC |
1425 | case (U8)(sv_SSize_tp >> 16): |
1426 | ret = sv_2mortal(newSViv(*((SSize_t *)ptr))); | |
1427 | break; | |
ffc5d9fc NC |
1428 | case (U8)(sv_I32p >> 16): |
1429 | ret = sv_2mortal(newSVuv(*((I32 *)ptr))); | |
1430 | break; | |
1431 | case (U8)(sv_U16p >> 16): | |
1432 | ret = sv_2mortal(newSVuv(*((U16 *)ptr))); | |
1433 | break; | |
c33e8be1 Z |
1434 | default: |
1435 | croak("Illegal alias 0x%08x for B::*IVX", (unsigned)ix); | |
e4da9d6a NC |
1436 | } |
1437 | ST(0) = ret; | |
1438 | XSRETURN(1); | |
a8a597b2 | 1439 | |
a8a597b2 MB |
1440 | void |
1441 | packiv(sv) | |
1442 | B::IV sv | |
6829f5e2 NC |
1443 | ALIAS: |
1444 | needs64bits = 1 | |
a8a597b2 | 1445 | CODE: |
6829f5e2 NC |
1446 | if (ix) { |
1447 | ST(0) = boolSV((I32)SvIVX(sv) != SvIVX(sv)); | |
1448 | } else if (sizeof(IV) == 8) { | |
a8a597b2 | 1449 | U32 wp[2]; |
5d7488b2 | 1450 | const IV iv = SvIVX(sv); |
a8a597b2 MB |
1451 | /* |
1452 | * The following way of spelling 32 is to stop compilers on | |
1453 | * 32-bit architectures from moaning about the shift count | |
1454 | * being >= the width of the type. Such architectures don't | |
1455 | * reach this code anyway (unless sizeof(IV) > 8 but then | |
1456 | * everything else breaks too so I'm not fussed at the moment). | |
1457 | */ | |
42718184 RB |
1458 | #ifdef UV_IS_QUAD |
1459 | wp[0] = htonl(((UV)iv) >> (sizeof(UV)*4)); | |
1460 | #else | |
1461 | wp[0] = htonl(((U32)iv) >> (sizeof(UV)*4)); | |
1462 | #endif | |
a8a597b2 | 1463 | wp[1] = htonl(iv & 0xffffffff); |
d3d34884 | 1464 | ST(0) = newSVpvn_flags((char *)wp, 8, SVs_TEMP); |
a8a597b2 MB |
1465 | } else { |
1466 | U32 w = htonl((U32)SvIVX(sv)); | |
d3d34884 | 1467 | ST(0) = newSVpvn_flags((char *)&w, 4, SVs_TEMP); |
a8a597b2 MB |
1468 | } |
1469 | ||
1470 | MODULE = B PACKAGE = B::NV PREFIX = Sv | |
1471 | ||
76ef7183 | 1472 | NV |
a8a597b2 MB |
1473 | SvNV(sv) |
1474 | B::NV sv | |
1475 | ||
4df7f6af NC |
1476 | #if PERL_VERSION < 11 |
1477 | ||
a8a597b2 MB |
1478 | MODULE = B PACKAGE = B::RV PREFIX = Sv |
1479 | ||
8ae5a962 | 1480 | void |
a8a597b2 MB |
1481 | SvRV(sv) |
1482 | B::RV sv | |
8ae5a962 | 1483 | PPCODE: |
0c74f67f | 1484 | PUSHs(make_sv_object(aTHX_ SvRV(sv))); |
a8a597b2 | 1485 | |
89c6bc13 NC |
1486 | #else |
1487 | ||
1488 | MODULE = B PACKAGE = B::REGEXP | |
1489 | ||
154b8842 | 1490 | void |
81e413dd | 1491 | REGEX(sv) |
89c6bc13 | 1492 | B::REGEXP sv |
81e413dd NC |
1493 | ALIAS: |
1494 | precomp = 1 | |
154b8842 | 1495 | PPCODE: |
81e413dd NC |
1496 | if (ix) { |
1497 | PUSHs(newSVpvn_flags(RX_PRECOMP(sv), RX_PRELEN(sv), SVs_TEMP)); | |
1498 | } else { | |
1499 | dXSTARG; | |
1500 | /* FIXME - can we code this method more efficiently? */ | |
1501 | PUSHi(PTR2IV(sv)); | |
1502 | } | |
89c6bc13 | 1503 | |
4df7f6af NC |
1504 | #endif |
1505 | ||
fdbacc68 | 1506 | MODULE = B PACKAGE = B::PV |
a8a597b2 | 1507 | |
8ae5a962 | 1508 | void |
fdbacc68 | 1509 | RV(sv) |
b326da91 | 1510 | B::PV sv |
8ae5a962 NC |
1511 | PPCODE: |
1512 | if (!SvROK(sv)) | |
b326da91 | 1513 | croak( "argument is not SvROK" ); |
0c74f67f | 1514 | PUSHs(make_sv_object(aTHX_ SvRV(sv))); |
b326da91 | 1515 | |
a8a597b2 | 1516 | void |
fdbacc68 | 1517 | PV(sv) |
a8a597b2 | 1518 | B::PV sv |
3d665704 NC |
1519 | ALIAS: |
1520 | PVX = 1 | |
f4c36584 | 1521 | PVBM = 2 |
84fea184 | 1522 | B::BM::TABLE = 3 |
a804b0fe NC |
1523 | PREINIT: |
1524 | const char *p; | |
1525 | STRLEN len = 0; | |
1526 | U32 utf8 = 0; | |
a8a597b2 | 1527 | CODE: |
84fea184 | 1528 | if (ix == 3) { |
2bda37ba NC |
1529 | #ifndef PERL_FBM_TABLE_OFFSET |
1530 | const MAGIC *const mg = mg_find(sv, PERL_MAGIC_bm); | |
1531 | ||
1532 | if (!mg) | |
1533 | croak("argument to B::BM::TABLE is not a PVBM"); | |
1534 | p = mg->mg_ptr; | |
1535 | len = mg->mg_len; | |
1536 | #else | |
84fea184 NC |
1537 | p = SvPV(sv, len); |
1538 | /* Boyer-Moore table is just after string and its safety-margin \0 */ | |
1539 | p += len + PERL_FBM_TABLE_OFFSET; | |
1540 | len = 256; | |
2bda37ba | 1541 | #endif |
84fea184 | 1542 | } else if (ix == 2) { |
f4c36584 | 1543 | /* This used to read 257. I think that that was buggy - should have |
26ec7981 NC |
1544 | been 258. (The "\0", the flags byte, and 256 for the table.) |
1545 | The only user of this method is B::Bytecode in B::PV::bsave. | |
1546 | I'm guessing that nothing tested the runtime correctness of | |
1547 | output of bytecompiled string constant arguments to index (etc). | |
1548 | ||
1549 | Note the start pointer is and has always been SvPVX(sv), not | |
1550 | SvPVX(sv) + SvCUR(sv) PVBM was added in 651aa52ea1faa806, and | |
1551 | first used by the compiler in 651aa52ea1faa806. It's used to | |
1552 | get a "complete" dump of the buffer at SvPVX(), not just the | |
1553 | PVBM table. This permits the generated bytecode to "load" | |
2bda37ba NC |
1554 | SvPVX in "one" hit. |
1555 | ||
1556 | 5.15 and later store the BM table via MAGIC, so the compiler | |
1557 | should handle this just fine without changes if PVBM now | |
1558 | always returns the SvPVX() buffer. */ | |
f4c36584 | 1559 | p = SvPVX_const(sv); |
2bda37ba | 1560 | #ifdef PERL_FBM_TABLE_OFFSET |
f4c36584 | 1561 | len = SvCUR(sv) + (SvVALID(sv) ? 256 + PERL_FBM_TABLE_OFFSET : 0); |
2bda37ba NC |
1562 | #else |
1563 | len = SvCUR(sv); | |
1564 | #endif | |
f4c36584 | 1565 | } else if (ix) { |
3d665704 NC |
1566 | p = SvPVX(sv); |
1567 | len = strlen(p); | |
1568 | } else if (SvPOK(sv)) { | |
a804b0fe NC |
1569 | len = SvCUR(sv); |
1570 | p = SvPVX_const(sv); | |
1571 | utf8 = SvUTF8(sv); | |
b326da91 MB |
1572 | } |
1573 | else { | |
1574 | /* XXX for backward compatibility, but should fail */ | |
1575 | /* croak( "argument is not SvPOK" ); */ | |
a804b0fe | 1576 | p = NULL; |
b326da91 | 1577 | } |
a804b0fe | 1578 | ST(0) = newSVpvn_flags(p, len, SVs_TEMP | utf8); |
a8a597b2 | 1579 | |
fdbacc68 | 1580 | MODULE = B PACKAGE = B::PVMG |
a8a597b2 MB |
1581 | |
1582 | void | |
fdbacc68 | 1583 | MAGIC(sv) |
a8a597b2 MB |
1584 | B::PVMG sv |
1585 | MAGIC * mg = NO_INIT | |
1586 | PPCODE: | |
1587 | for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) | |
9496d2e5 | 1588 | XPUSHs(make_mg_object(aTHX_ mg)); |
a8a597b2 | 1589 | |
b2adfa9b | 1590 | MODULE = B PACKAGE = B::MAGIC |
a8a597b2 MB |
1591 | |
1592 | void | |
b2adfa9b | 1593 | MOREMAGIC(mg) |
a8a597b2 | 1594 | B::MAGIC mg |
b2adfa9b NC |
1595 | ALIAS: |
1596 | PRIVATE = 1 | |
1597 | TYPE = 2 | |
1598 | FLAGS = 3 | |
fb6620c6 | 1599 | LENGTH = 4 |
b2adfa9b NC |
1600 | OBJ = 5 |
1601 | PTR = 6 | |
1602 | REGEX = 7 | |
1603 | precomp = 8 | |
1604 | PPCODE: | |
1605 | switch (ix) { | |
1606 | case 0: | |
1607 | XPUSHs(mg->mg_moremagic ? make_mg_object(aTHX_ mg->mg_moremagic) | |
1608 | : &PL_sv_undef); | |
1609 | break; | |
1610 | case 1: | |
1611 | mPUSHu(mg->mg_private); | |
1612 | break; | |
1613 | case 2: | |
1614 | PUSHs(newSVpvn_flags(&(mg->mg_type), 1, SVs_TEMP)); | |
1615 | break; | |
1616 | case 3: | |
1617 | mPUSHu(mg->mg_flags); | |
1618 | break; | |
1619 | case 4: | |
1620 | mPUSHi(mg->mg_len); | |
1621 | break; | |
1622 | case 5: | |
0c74f67f | 1623 | PUSHs(make_sv_object(aTHX_ mg->mg_obj)); |
b2adfa9b NC |
1624 | break; |
1625 | case 6: | |
1626 | if (mg->mg_ptr) { | |
1627 | if (mg->mg_len >= 0) { | |
1628 | PUSHs(newSVpvn_flags(mg->mg_ptr, mg->mg_len, SVs_TEMP)); | |
651aa52e | 1629 | } else if (mg->mg_len == HEf_SVKEY) { |
0c74f67f | 1630 | PUSHs(make_sv_object(aTHX_ (SV*)mg->mg_ptr)); |
fdbd1d64 | 1631 | } else |
b2adfa9b NC |
1632 | PUSHs(sv_newmortal()); |
1633 | } else | |
1634 | PUSHs(sv_newmortal()); | |
1635 | break; | |
1636 | case 7: | |
1637 | if(mg->mg_type == PERL_MAGIC_qr) { | |
1638 | mPUSHi(PTR2IV(mg->mg_obj)); | |
1639 | } else { | |
1640 | croak("REGEX is only meaningful on r-magic"); | |
1641 | } | |
1642 | break; | |
1643 | case 8: | |
1644 | if (mg->mg_type == PERL_MAGIC_qr) { | |
1645 | REGEXP *rx = (REGEXP *)mg->mg_obj; | |
227aaa42 NC |
1646 | PUSHs(newSVpvn_flags(rx ? RX_PRECOMP(rx) : NULL, |
1647 | rx ? RX_PRELEN(rx) : 0, SVs_TEMP)); | |
b2adfa9b NC |
1648 | } else { |
1649 | croak( "precomp is only meaningful on r-magic" ); | |
1650 | } | |
1651 | break; | |
1652 | } | |
a8a597b2 | 1653 | |
a8a597b2 MB |
1654 | MODULE = B PACKAGE = B::GV PREFIX = Gv |
1655 | ||
1656 | void | |
1657 | GvNAME(gv) | |
1658 | B::GV gv | |
cbf9c13f NC |
1659 | ALIAS: |
1660 | FILE = 1 | |
435e8dd0 | 1661 | B::HV::NAME = 2 |
a8a597b2 | 1662 | CODE: |
435e8dd0 NC |
1663 | ST(0) = sv_2mortal(newSVhek(!ix ? GvNAME_HEK(gv) |
1664 | : (ix == 1 ? GvFILE_HEK(gv) | |
1665 | : HvNAME_HEK((HV *)gv)))); | |
a8a597b2 | 1666 | |
87d7fd28 GS |
1667 | bool |
1668 | is_empty(gv) | |
1669 | B::GV gv | |
711fbbf0 NC |
1670 | ALIAS: |
1671 | isGV_with_GP = 1 | |
87d7fd28 | 1672 | CODE: |
711fbbf0 | 1673 | if (ix) { |
711fbbf0 | 1674 | RETVAL = isGV_with_GP(gv) ? TRUE : FALSE; |
711fbbf0 NC |
1675 | } else { |
1676 | RETVAL = GvGP(gv) == Null(GP*); | |
1677 | } | |
50786ba8 | 1678 | OUTPUT: |
711fbbf0 | 1679 | RETVAL |
50786ba8 | 1680 | |
651aa52e AE |
1681 | void* |
1682 | GvGP(gv) | |
1683 | B::GV gv | |
1684 | ||
257e0650 NC |
1685 | #define GP_sv_ix SVp | offsetof(struct gp, gp_sv) |
1686 | #define GP_io_ix SVp | offsetof(struct gp, gp_io) | |
1687 | #define GP_cv_ix SVp | offsetof(struct gp, gp_cv) | |
1688 | #define GP_cvgen_ix U32p | offsetof(struct gp, gp_cvgen) | |
1689 | #define GP_refcnt_ix U32p | offsetof(struct gp, gp_refcnt) | |
1690 | #define GP_hv_ix SVp | offsetof(struct gp, gp_hv) | |
1691 | #define GP_av_ix SVp | offsetof(struct gp, gp_av) | |
1692 | #define GP_form_ix SVp | offsetof(struct gp, gp_form) | |
1693 | #define GP_egv_ix SVp | offsetof(struct gp, gp_egv) | |
1694 | #define GP_line_ix line_tp | offsetof(struct gp, gp_line) | |
a8a597b2 | 1695 | |
257e0650 NC |
1696 | void |
1697 | SV(gv) | |
a8a597b2 | 1698 | B::GV gv |
257e0650 NC |
1699 | ALIAS: |
1700 | SV = GP_sv_ix | |
1701 | IO = GP_io_ix | |
1702 | CV = GP_cv_ix | |
1703 | CVGEN = GP_cvgen_ix | |
1704 | GvREFCNT = GP_refcnt_ix | |
1705 | HV = GP_hv_ix | |
1706 | AV = GP_av_ix | |
1707 | FORM = GP_form_ix | |
1708 | EGV = GP_egv_ix | |
1709 | LINE = GP_line_ix | |
1710 | PREINIT: | |
1711 | GP *gp; | |
1712 | char *ptr; | |
1713 | SV *ret; | |
1714 | PPCODE: | |
1715 | gp = GvGP(gv); | |
1716 | if (!gp) { | |
1717 | const GV *const gv = CvGV(cv); | |
46c3f339 | 1718 | Perl_croak(aTHX_ "NULL gp in B::GV::%s", gv ? GvNAME(gv) : "???"); |
257e0650 NC |
1719 | } |
1720 | ptr = (ix & 0xFFFF) + (char *)gp; | |
1721 | switch ((U8)(ix >> 16)) { | |
1722 | case (U8)(SVp >> 16): | |
0c74f67f | 1723 | ret = make_sv_object(aTHX_ *((SV **)ptr)); |
257e0650 NC |
1724 | break; |
1725 | case (U8)(U32p >> 16): | |
1726 | ret = sv_2mortal(newSVuv(*((U32*)ptr))); | |
1727 | break; | |
1728 | case (U8)(line_tp >> 16): | |
1729 | ret = sv_2mortal(newSVuv(*((line_t *)ptr))); | |
1730 | break; | |
c33e8be1 Z |
1731 | default: |
1732 | croak("Illegal alias 0x%08x for B::*SV", (unsigned)ix); | |
257e0650 NC |
1733 | } |
1734 | ST(0) = ret; | |
1735 | XSRETURN(1); | |
a8a597b2 | 1736 | |
8ae5a962 NC |
1737 | void |
1738 | FILEGV(gv) | |
a8a597b2 | 1739 | B::GV gv |
8ae5a962 | 1740 | PPCODE: |
0c74f67f | 1741 | PUSHs(make_sv_object(aTHX_ (SV *)GvFILEGV(gv))); |
a8a597b2 | 1742 | |
a8a597b2 MB |
1743 | MODULE = B PACKAGE = B::IO PREFIX = Io |
1744 | ||
04071355 | 1745 | |
b326da91 MB |
1746 | bool |
1747 | IsSTD(io,name) | |
1748 | B::IO io | |
5d7488b2 | 1749 | const char* name |
b326da91 MB |
1750 | PREINIT: |
1751 | PerlIO* handle = 0; | |
1752 | CODE: | |
1753 | if( strEQ( name, "stdin" ) ) { | |
1754 | handle = PerlIO_stdin(); | |
1755 | } | |
1756 | else if( strEQ( name, "stdout" ) ) { | |
1757 | handle = PerlIO_stdout(); | |
1758 | } | |
1759 | else if( strEQ( name, "stderr" ) ) { | |
1760 | handle = PerlIO_stderr(); | |
1761 | } | |
1762 | else { | |
1763 | croak( "Invalid value '%s'", name ); | |
1764 | } | |
1765 | RETVAL = handle == IoIFP(io); | |
1766 | OUTPUT: | |
1767 | RETVAL | |
1768 | ||
a8a597b2 MB |
1769 | MODULE = B PACKAGE = B::AV PREFIX = Av |
1770 | ||
1771 | SSize_t | |
1772 | AvFILL(av) | |
1773 | B::AV av | |
1774 | ||
a8a597b2 MB |
1775 | void |
1776 | AvARRAY(av) | |
1777 | B::AV av | |
1778 | PPCODE: | |
1779 | if (AvFILL(av) >= 0) { | |
1780 | SV **svp = AvARRAY(av); | |
1781 | I32 i; | |
1782 | for (i = 0; i <= AvFILL(av); i++) | |
0c74f67f | 1783 | XPUSHs(make_sv_object(aTHX_ svp[i])); |
a8a597b2 MB |
1784 | } |
1785 | ||
429a5ce7 SM |
1786 | void |
1787 | AvARRAYelt(av, idx) | |
1788 | B::AV av | |
1789 | int idx | |
1790 | PPCODE: | |
1791 | if (idx >= 0 && AvFILL(av) >= 0 && idx <= AvFILL(av)) | |
0c74f67f | 1792 | XPUSHs(make_sv_object(aTHX_ (AvARRAY(av)[idx]))); |
429a5ce7 | 1793 | else |
0c74f67f | 1794 | XPUSHs(make_sv_object(aTHX_ NULL)); |
429a5ce7 | 1795 | |
edcc7c74 | 1796 | |
f2da823f FC |
1797 | MODULE = B PACKAGE = B::FM PREFIX = Fm |
1798 | ||
35633035 DM |
1799 | #undef FmLINES |
1800 | #define FmLINES(sv) 0 | |
f2da823f FC |
1801 | |
1802 | IV | |
1803 | FmLINES(form) | |
1804 | B::FM form | |
1805 | ||
a8a597b2 MB |
1806 | MODULE = B PACKAGE = B::CV PREFIX = Cv |
1807 | ||
651aa52e AE |
1808 | U32 |
1809 | CvCONST(cv) | |
1810 | B::CV cv | |
1811 | ||
6079961f | 1812 | void |
a8a597b2 MB |
1813 | CvSTART(cv) |
1814 | B::CV cv | |
a0da4400 NC |
1815 | ALIAS: |
1816 | ROOT = 1 | |
6079961f NC |
1817 | PPCODE: |
1818 | PUSHs(make_op_object(aTHX_ CvISXSUB(cv) ? NULL | |
1819 | : ix ? CvROOT(cv) : CvSTART(cv))); | |
a8a597b2 | 1820 | |
bb02a38f FC |
1821 | I32 |
1822 | CvDEPTH(cv) | |
1823 | B::CV cv | |
1824 | ||
86d2498c | 1825 | #ifdef PadlistARRAY |
7261499d FC |
1826 | |
1827 | B::PADLIST | |
1828 | CvPADLIST(cv) | |
1829 | B::CV cv | |
1830 | ||
1831 | #else | |
1832 | ||
1833 | B::AV | |
1834 | CvPADLIST(cv) | |
1835 | B::CV cv | |
82aeefe1 DM |
1836 | PPCODE: |
1837 | PUSHs(make_sv_object(aTHX_ (SV *)CvPADLIST(cv))); | |
1838 | ||
7261499d FC |
1839 | |
1840 | #endif | |
1841 | ||
a8a597b2 MB |
1842 | void |
1843 | CvXSUB(cv) | |
1844 | B::CV cv | |
96819e59 NC |
1845 | ALIAS: |
1846 | XSUBANY = 1 | |
a8a597b2 | 1847 | CODE: |
96819e59 | 1848 | ST(0) = ix && CvCONST(cv) |
0c74f67f | 1849 | ? make_sv_object(aTHX_ (SV *)CvXSUBANY(cv).any_ptr) |
96819e59 NC |
1850 | : sv_2mortal(newSViv(CvISXSUB(cv) |
1851 | ? (ix ? CvXSUBANY(cv).any_iv | |
1852 | : PTR2IV(CvXSUB(cv))) | |
1853 | : 0)); | |
a8a597b2 | 1854 | |
8ae5a962 NC |
1855 | void |
1856 | const_sv(cv) | |
de3f1649 | 1857 | B::CV cv |
8ae5a962 | 1858 | PPCODE: |
0c74f67f | 1859 | PUSHs(make_sv_object(aTHX_ (SV *)cv_const_sv(cv))); |
de3f1649 | 1860 | |
a8a597b2 MB |
1861 | MODULE = B PACKAGE = B::HV PREFIX = Hv |
1862 | ||
1863 | STRLEN | |
1864 | HvFILL(hv) | |
1865 | B::HV hv | |
1866 | ||
a8a597b2 MB |
1867 | I32 |
1868 | HvRITER(hv) | |
1869 | B::HV hv | |
1870 | ||
a8a597b2 MB |
1871 | void |
1872 | HvARRAY(hv) | |
1873 | B::HV hv | |
1874 | PPCODE: | |
1b95d04f | 1875 | if (HvUSEDKEYS(hv) > 0) { |
a8a597b2 MB |
1876 | SV *sv; |
1877 | char *key; | |
1878 | I32 len; | |
1879 | (void)hv_iterinit(hv); | |
1b95d04f | 1880 | EXTEND(sp, HvUSEDKEYS(hv) * 2); |
8063af02 | 1881 | while ((sv = hv_iternextsv(hv, &key, &len))) { |
22f1178f | 1882 | mPUSHp(key, len); |
0c74f67f | 1883 | PUSHs(make_sv_object(aTHX_ sv)); |
a8a597b2 MB |
1884 | } |
1885 | } | |
fd9f6265 JJ |
1886 | |
1887 | MODULE = B PACKAGE = B::HE PREFIX = He | |
1888 | ||
8ae5a962 | 1889 | void |
fd9f6265 JJ |
1890 | HeVAL(he) |
1891 | B::HE he | |
b2619626 NC |
1892 | ALIAS: |
1893 | SVKEY_force = 1 | |
8ae5a962 | 1894 | PPCODE: |
0c74f67f | 1895 | PUSHs(make_sv_object(aTHX_ ix ? HeSVKEY_force(he) : HeVAL(he))); |
fd9f6265 JJ |
1896 | |
1897 | U32 | |
1898 | HeHASH(he) | |
1899 | B::HE he | |
1900 | ||
fdbacc68 | 1901 | MODULE = B PACKAGE = B::RHE |
fd9f6265 JJ |
1902 | |
1903 | SV* | |
fdbacc68 | 1904 | HASH(h) |
fd9f6265 JJ |
1905 | B::RHE h |
1906 | CODE: | |
20439bc7 | 1907 | RETVAL = newRV( (SV*)cophh_2hv(h, 0) ); |
fd9f6265 JJ |
1908 | OUTPUT: |
1909 | RETVAL | |
e412117e | 1910 | |
7261499d | 1911 | |
86d2498c | 1912 | #ifdef PadlistARRAY |
7261499d | 1913 | |
86d2498c | 1914 | MODULE = B PACKAGE = B::PADLIST PREFIX = Padlist |
7261499d FC |
1915 | |
1916 | SSize_t | |
86d2498c | 1917 | PadlistMAX(padlist) |
7261499d FC |
1918 | B::PADLIST padlist |
1919 | ||
1920 | void | |
86d2498c | 1921 | PadlistARRAY(padlist) |
7261499d FC |
1922 | B::PADLIST padlist |
1923 | PPCODE: | |
86d2498c FC |
1924 | if (PadlistMAX(padlist) >= 0) { |
1925 | PAD **padp = PadlistARRAY(padlist); | |
7261499d | 1926 | PADOFFSET i; |
86d2498c | 1927 | for (i = 0; i <= PadlistMAX(padlist); i++) |
7261499d FC |
1928 | XPUSHs(make_sv_object(aTHX_ (SV *)padp[i])); |
1929 | } | |
1930 | ||
1931 | void | |
86d2498c | 1932 | PadlistARRAYelt(padlist, idx) |
7261499d FC |
1933 | B::PADLIST padlist |
1934 | PADOFFSET idx | |
1935 | PPCODE: | |
86d2498c FC |
1936 | if (idx >= 0 && PadlistMAX(padlist) >= 0 |
1937 | && idx <= PadlistMAX(padlist)) | |
7261499d | 1938 | XPUSHs(make_sv_object(aTHX_ |
86d2498c | 1939 | (SV *)PadlistARRAY(padlist)[idx])); |
7261499d FC |
1940 | else |
1941 | XPUSHs(make_sv_object(aTHX_ NULL)); | |
1942 | ||
1943 | U32 | |
86d2498c | 1944 | PadlistREFCNT(padlist) |
7261499d FC |
1945 | B::PADLIST padlist |
1946 | CODE: | |
86d2498c | 1947 | RETVAL = PadlistREFCNT(padlist); |
7261499d FC |
1948 | OUTPUT: |
1949 | RETVAL | |
1950 | ||
1951 | #endif |