B#

📦 min

Inspect a running Perl program’s own optree, symbol table, and compiled subs.

B is the compiler back-end interface. It hands a script introspective access to the data structures the interpreter already holds: the root of the main optree, every compiled sub’s CV, the symbol table (stash) graph, and the SV/AV/HV/GV objects those structures point at. Subclasses such as B::OP, B::CV, B::GV, B::SV (and its type-specific children) wrap those pointers as blessed Perl objects with accessor methods.

Common callers are back-end modules like B::Deparse, B::Concise, and B::Xref; debugging tooling that walks the optree; and scripts that introspect the symbol table to generate code or diagnostics.

use B qw(svref_2object class);

sub add { my ($x, $y) = @_; return $x + $y }

my $cv = svref_2object(\&add);                 # a B::CV
printf "%s defined in %s at line %d\n", $cv->GV->NAME, $cv->FILE =~ s{.*/}{}r,
    $cv->START->line;                          # add defined in add.pl at line 3

# Walk the sub's ops in execution order.
my @ops;
for (my $op = $cv->START; $$op; $op = $op->next) {
    push @ops, $op->name;
}
print "@ops\n";
# nextstate padrange aassign nextstate padsv padsv add leavesub

my $sv = svref_2object(\"text");
printf "%s, PV %s, length %d\n", class($sv), $sv->PV, $sv->CUR;   # PV, PV text, length 4
print "main program: ", class(B::main_cv()), ", root ", B::main_root()->name, "\n";
# main program: CV, root leave

The ops are pperl’s own, the ones perl 5.44 builds for the same source: the names, flags, order and tree shape that B::Concise and B::Deparse read are perl5’s.

This is a native implementation of the XS half of B 1.92; its B.pm and the B::* modules built on it are used unchanged. B exports nothing by default; on request, its functions (svref_2object, class, main_root, main_start, main_cv, walkoptree, walksymtable, ppname, opnumber, begin_av …) and its constants - the SVf_*, OPf_*, OPp*, CVf_*, GVf_*, PMf_* flags and the rest.

Differences from upstream#

One, where perl 5.44 with B.xs crashes: a B::OP method called on a B::NULL - the object for a missing op, such as the ROOT of an XSUB - as B::OP::name($null) answers as for the null op (name is “null”, an op or SV field is a B::NULL, a number is 0). B.xs follows the NULL pointer and crashes (t/81-xs-native/B/470-or-better.t).

Modules#

Functions#

Entry points#

svref_2object#

Wrap a reference’s referent as a B::* object.

opnumber#

Return the numeric op-type for an op name, or -1 if unknown.

ppname#

Return the pp_-prefixed name for a numeric op-type.

Synopsis

my $name = B::ppname($op->type);   # e.g. "pp_print"

Inverse of B::opnumber. Returns undef if the number is out of range.

sv_undef#

Return a B::SPECIAL wrapping perl’s shared PL_sv_undef.

sv_yes#

Return a B::SPECIAL wrapping perl’s shared PL_sv_yes.

sv_no#

Return a B::SPECIAL wrapping perl’s shared PL_sv_no.

main_root#

Return a B::OP for the root of the program’s main optree.

main_start#

Return a B::OP for the first op executed in the main program.

Synopsis

my $start = B::main_start;

Where B::main_root gives the syntactic root, B::main_start gives the head of the linked list perl follows at run time via op_next.

cast_I32#

Truncate $i to a signed 32-bit integer.

Synopsis

B::cast_I32(0x1_0000_0001);   # 1 (low 32 bits, sign-extended)

Exists so Perl back-ends can reproduce perl’s own I32 truncation when they need to emit exact values for an op field typed I32 in C.

amagic_generation#

Return the overload-magic generation counter (always 0 in modern perl).

comppadlist#

Return the padlist of the currently-compiling unit as a B::PADLIST.

formfeed#

Return $^L, the form-feed string, as a B::SV.

address#

Return the memory address of an SV as an integer.

Synopsis

my $addr = B::address(\$x);

Mostly useful as an identity key: two B::* objects wrapping the same underlying SV will report the same address.

threadsv_names#

Return the list of thread-local special-variable names (empty).

minus_c#

Request that compilation stop after the compile phase (-c).

save_BEGINs#

Request that BEGIN blocks be saved rather than freed (save_BEGINs).

Walking the optree#

walkoptree#

Recursively walk an optree, calling $method on each op.

walkoptree_debug#

Get or set the walkoptree debug flag.

String and hash helpers#

cstring#

Return $sv’s contents as a double-quoted C-style string literal.

perlstring#

Return $sv’s contents as a double-quoted Perl string literal.

Synopsis

B::perlstring('say $x@y');    # "say \$x\@y"

Like B::cstring, but also escapes $ and @ so the result can be pasted back into Perl source without interpolation surprises.

cchar#

Return the first character of $sv as a single-quoted C character literal.

hash#

Return perl’s hash of a string, formatted as 0xNNNNNNNN.

safename#

Return a string with a leading control character rendered as ^X.

B::GV methods#

B::GV::SAFENAME#

Return the GV’s name with a leading control character rendered as ^X.

Interpreter globals#

sub_generation#

B::sub_generation(): perl’s global method-cache generation (PL_sub_generation). It goes up when every method cache is invalidated at once - a change to UNIVERSAL or one of its parents, among a few others; ordinary sub definitions and @ISA changes only invalidate their own classes and leave it alone. B::dowarn() is perl’s warning switch word (PL_dowarn): 0 normally, 1 under -w, 3 under -W, 4 under -X.

Also available as B::dowarn.

main_cv#

Return a B::CV for the implicit CV of the main program.

inc_gv#

Return a B::GV for *INC, the module-loading search list.

defstash#

Return a B::HV for %main::, the default stash.

curstash#

Return a B::HV for the currently active compile-time stash.

warnhook#

Return a B::SV for the current $SIG{__WARN__} handler.

diehook#

Return a B::SV for the current $SIG{__DIE__} handler.

init_av#

Return a B::AV of the INIT blocks queued for execution.

check_av#

Return a B::AV of CHECK blocks queued for execution.

unitcheck_av#

Return a B::AV of UNITCHECK blocks queued for execution.

begin_av#

Return a B::AV of BEGIN blocks already executed.

end_av#

Return a B::AV of END blocks queued to run at interpreter exit.