1use strict; 2use warnings; 3 4use Test::More; 5use B 'svref_2object'; 6BEGIN { $^P |= 0x210 } 7 8# This is a mess. The stash can supposedly handle Unicode but the behavior 9# is literally undefined before 5.16 (with crashes beyond the basic plane), 10# and remains unclear past 5.16 with evalbytes and feature unicode_eval 11# In any case - Sub::Name needs to *somehow* work with this, so we will do 12# a heuristic with ambiguous eval and looking for octets in the stash 13use if $] >= 5.016, feature => 'unicode_eval'; 14 15if ($] >= 5.008) { 16 my $builder = Test::More->builder; 17 binmode $builder->output, ":encoding(utf8)"; 18 binmode $builder->failure_output, ":encoding(utf8)"; 19 binmode $builder->todo_output, ":encoding(utf8)"; 20} 21 22sub compile_named_sub { 23 my ( $fullname, $body ) = @_; 24 my $sub = eval "sub $fullname { $body }" . '\\&{$fullname}'; 25 return $sub if $sub; 26 my $e = $@; 27 require Carp; 28 Carp::croak $e; 29} 30 31sub caller3_ok { 32 my ( $sub, $expected, $type, $ord ) = @_; 33 34 local $Test::Builder::Level = $Test::Builder::Level + 1; 35 36 my $for_what = sprintf "when it contains \\x%s ( %s )", ( 37 ( ($ord > 255) 38 ? sprintf "{%X}", $ord 39 : sprintf "%02X", $ord 40 ), 41 ( 42 $ord > 255 ? unpack('H*', pack 'C0U', $ord ) 43 : ($ord > 0x1f and $ord < 0x7f) ? sprintf "%c", $ord 44 : sprintf '\%o', $ord 45 ), 46 ); 47 48 $expected =~ s/'/::/g; 49 50 # this is apparently how things worked before 5.16 51 utf8::encode($expected) if $] < 5.016 and $ord > 255; 52 53 my $stash_name = join '::', map { $_->STASH->NAME, $_->NAME } svref_2object($sub)->GV; 54 55 is $stash_name, $expected, "stash name for $type is correct $for_what"; 56 is $sub->(), $expected, "caller() in $type returns correct name $for_what"; 57 SKIP: { 58 skip '%DB::sub not populated when enabled at runtime', 1 59 unless keys %DB::sub; 60 my ($prefix) = $expected =~ /^(.*?test::[^:]+::)/; 61 my ($db_found) = grep /^$prefix/, keys %DB::sub; 62 is $db_found, $expected, "%DB::sub entry for $type is correct $for_what"; 63 } 64} 65 66####################################################################### 67 68use Sub::Util 'set_subname'; 69 70my @ordinal = ( 1 .. 255 ); 71 72# 5.14 is the first perl to start properly handling \0 in identifiers 73unshift @ordinal, 0 74 unless $] < 5.014; 75 76# Unicode in 5.6 is not sane (crashes etc) 77push @ordinal, 78 0x100, # LATIN CAPITAL LETTER A WITH MACRON 79 0x498, # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER 80 0x2122, # TRADE MARK SIGN 81 0x1f4a9, # PILE OF POO 82 unless $] < 5.008; 83 84plan tests => @ordinal * 2 * 3; 85 86my $legal_ident_char = "A-Z_a-z0-9'"; 87$legal_ident_char .= join '', map chr, 0x100, 0x498 88 unless $] < 5.008; 89 90my $uniq = 'A000'; 91for my $ord (@ordinal) { 92 my $sub; 93 $uniq++; 94 my $pkg = sprintf 'test::%s::SOME_%c_STASH', $uniq, $ord; 95 my $subname = sprintf 'SOME_%s_%c_NAME', $uniq, $ord; 96 my $fullname = join '::', $pkg, $subname; 97 98 $sub = set_subname $fullname => sub { (caller(0))[3] }; 99 caller3_ok $sub, $fullname, 'renamed closure', $ord; 100 101 # test that we can *always* compile at least within the correct package 102 my $expected; 103 if ( chr($ord) =~ m/^[$legal_ident_char]$/o ) { # compile directly 104 $expected = "native::$fullname"; 105 $sub = compile_named_sub $expected => '(caller(0))[3]'; 106 } 107 else { # not a legal identifier but at least test the package name by aliasing 108 $expected = "aliased::native::$fullname"; 109 { 110 no strict 'refs'; 111 *palatable:: = *{"aliased::native::${pkg}::"}; 112 # now palatable:: literally means aliased::native::${pkg}:: 113 my $encoded_sub = $subname; 114 utf8::encode($encoded_sub) if "$]" < 5.016 and $ord > 255; 115 ${"palatable::$encoded_sub"} = 1; 116 ${"palatable::"}{"sub"} = ${"palatable::"}{$encoded_sub}; 117 # and palatable::sub means aliased::native::${pkg}::${subname} 118 } 119 $sub = compile_named_sub 'palatable::sub' => '(caller(0))[3]'; 120 } 121 caller3_ok $sub, $expected, 'natively compiled sub', $ord; 122} 123