Devel-MAT
view release on metacpan or search on metacpan
lib/Devel/MAT/SV.pm view on Meta::CPAN
# You may distribute under the terms of either the GNU General Public License
# or the Artistic License (the same terms as Perl itself)
#
# (C) Paul Evans, 2013-2024 -- leonerd@leonerd.org.uk
package Devel::MAT::SV 0.54;
use v5.14;
use warnings;
use Carp;
use Scalar::Util qw( weaken );
use Syntax::Keyword::Match;
# Load XS code
require Devel::MAT;
use constant immortal => 0;
use List::Util qw( first );
use Struct::Dumb 0.07 qw( readonly_struct );
readonly_struct Reference => [qw( name strength sv )];
readonly_struct Magic => [qw( type obj ptr vtbl )];
=head1 NAME
C<Devel::MAT::SV> - represent a single SV from a heap dump
=head1 DESCRIPTION
Objects in this class represent individual SV variables found in the arena
during a heap dump. Actual types of SV are represented by subclasses, which
are documented below.
=cut
my $CONSTANTS;
BEGIN {
$CONSTANTS = {
STRENGTH_STRONG => (1 << 0),
STRENGTH_WEAK => (1 << 1),
STRENGTH_INDIRECT => (1 << 2),
STRENGTH_INFERRED => (1 << 3),
};
$CONSTANTS->{STRENGTH_DIRECT} = $CONSTANTS->{STRENGTH_STRONG}|$CONSTANTS->{STRENGTH_WEAK};
$CONSTANTS->{STRENGTH_ALL} = $CONSTANTS->{STRENGTH_STRONG}|$CONSTANTS->{STRENGTH_WEAK}|$CONSTANTS->{STRENGTH_INDIRECT}|$CONSTANTS->{STRENGTH_INFERRED};
}
use constant $CONSTANTS;
my %types;
sub register_type
{
$types{$_[1]} = $_[0];
# generate the ->type constant method
( my $typename = $_[0] ) =~ s/^Devel::MAT::SV:://;
no strict 'refs';
*{"$_[0]::type"} = sub () { $typename } unless defined *{"$_[0]::type"}{CODE};
}
sub new
{
shift;
my ( $type, $df, $header, $ptrs, $strs ) = @_;
my $class = $types{$type} or croak "Cannot load unknown SV type $type";
my $self = bless {}, $class;
$self->_set_core_fields(
$type, $df,
lib/Devel/MAT/SV.pm view on Meta::CPAN
sub _outrefs
{
my $self = shift;
my ( $match, $no_desc ) = @_;
my @outrefs;
if( $match & STRENGTH_STRONG and my $ourstash = $self->ourstash ) {
push @outrefs, $no_desc ? ( strong => $ourstash ) :
Devel::MAT::SV::Reference( "the our stash", strong => $ourstash );
}
return @outrefs;
}
package Devel::MAT::SV::REF 0.54;
use base qw( Devel::MAT::SV );
__PACKAGE__->register_type( 3 );
use constant $CONSTANTS;
use constant basetype => "SV";
=head1 Devel::MAT::SV::REF
Represents a referential scalar; any SCALAR-type SV with the C<SvROK> flag
set.
=cut
sub load
{
my $self = shift;
my ( $header, $ptrs, $strs ) = @_;
( my $flags ) =
unpack "C", $header;
$self->_set_ref_fields(
@{$ptrs}[0,1], # RV, OURSTASH
$flags & 0x01, # RV_IS_WEAK
);
$flags &= ~0x01;
$flags and die sprintf "Unrecognised REF flags %02x\n", $flags;
}
=head2 rv
$svrv = $sv->rv;
Returns the SV referred to by the reference.
=cut
sub rv { my $self = shift; return $self->df->sv_at( $self->rv_at ) }
=head2 is_weak
$weak = $sv->is_weak;
Returns true if the SV is a weakened RV reference.
=cut
# XS accessor
=head2 ourstash
$stash = $sv->ourstash;
Returns the stash of the SCALAR, if it is an 'C<our>' variable.
=cut
sub ourstash { my $self = shift; return $self->df->sv_at( $self->ourstash_at ) }
sub desc
{
my $self = shift;
return sprintf "REF(%s)", $self->is_weak ? "W" : "";
}
*symname = \&Devel::MAT::SV::SCALAR::symname;
sub _outrefs
{
my $self = shift;
my ( $match, $no_desc ) = @_;
my @outrefs;
my $is_weak = $self->is_weak;
if( $match & ( $is_weak ? STRENGTH_WEAK : STRENGTH_STRONG ) and my $rv = $self->rv ) {
my $strength = $is_weak ? "weak" : "strong";
push @outrefs, $no_desc ? ( $strength => $rv ) :
Devel::MAT::SV::Reference( "the referrant", $strength => $rv );
}
if( $match & STRENGTH_STRONG and my $ourstash = $self->ourstash ) {
push @outrefs, $no_desc ? ( strong => $ourstash ) :
Devel::MAT::SV::Reference( "the our stash", strong => $ourstash );
}
return @outrefs;
}
package Devel::MAT::SV::BOOL 0.54;
use base qw( Devel::MAT::SV::SCALAR );
sub type { return "BOOL" }
sub desc
{
my $self = shift;
return "BOOL(YES)" if $self->uv;
return "BOOL(NO)";
}
package Devel::MAT::SV::ARRAY 0.54;
use base qw( Devel::MAT::SV );
( run in 1.355 second using v1.01-cache-2.11-cpan-5735350b133 )