File Coverage

ext/B/B.xs
Criterion Covered Total %
statement 409 529 77.3
branch n/a
condition n/a
subroutine n/a
total 409 529 77.3


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