185009909Smillert#!./perl -w 285009909Smillert 385009909Smillert$|=1; 485009909Smillert 585009909SmillertBEGIN { 685009909Smillert require Config; import Config; 785009909Smillert if ($Config{'extensions'} !~ /\bOpcode\b/ && $Config{'osname'} ne 'VMS') { 885009909Smillert print "1..0\n"; 985009909Smillert exit 0; 1085009909Smillert } 1185009909Smillert} 1285009909Smillert 13898184e3Ssthenuse strict; 14898184e3Ssthenuse Test::More; 15898184e3Ssthen 16898184e3Ssthen{ 17898184e3Ssthen my @warnings; 18898184e3Ssthen 19898184e3Ssthen BEGIN { 20898184e3Ssthen local $SIG{__WARN__} = sub { 21898184e3Ssthen push @warnings, "@_"; 22898184e3Ssthen }; 23898184e3Ssthen 24898184e3Ssthen use_ok('Opcode', qw( 2585009909Smillert opcodes opdesc opmask verify_opset 2685009909Smillert opset opset_to_ops opset_to_hex invert_opset 2785009909Smillert opmask_add full_opset empty_opset define_optag 28898184e3Ssthen )); 29898184e3Ssthen } 3085009909Smillert 31898184e3Ssthen is_deeply(\@warnings, [], "No warnings loading Opcode"); 32898184e3Ssthen} 3385009909Smillert 3485009909Smillert# --- opset_to_ops and opset 3585009909Smillert 3685009909Smillertmy @empty_l = opset_to_ops(empty_opset); 37898184e3Ssthenis_deeply (\@empty_l, []); 3885009909Smillert 3985009909Smillertmy @full_l1 = opset_to_ops(full_opset); 40898184e3Ssthenis (scalar @full_l1, scalar opcodes()); 41898184e3Ssthen 42898184e3Ssthen{ 43898184e3Ssthen local $::TODO = "opcodes in list context not yet implemented"; 44898184e3Ssthen my @full_l2 = eval {opcodes()}; 45898184e3Ssthen is($@, ''); 46898184e3Ssthen is_deeply(\@full_l1, \@full_l2); 47898184e3Ssthen} 4885009909Smillert 4985009909Smillert@empty_l = opset_to_ops(opset(':none')); 50898184e3Ssthenis_deeply(\@empty_l, []); 5185009909Smillert 5285009909Smillertmy @full_l3 = opset_to_ops(opset(':all')); 53898184e3Ssthenis_deeply(\@full_l1, \@full_l3); 5485009909Smillert 55898184e3Ssthenmy $s1 = opset( 'padsv'); 56898184e3Ssthenmy $s2 = opset($s1, 'padav'); 57898184e3Ssthenmy $s3 = opset($s2, '!padav'); 58898184e3Ssthenisnt($s1, $s2); 59898184e3Ssthenis($s1, $s3); 6085009909Smillert 6185009909Smillert# --- define_optag 6285009909Smillert 63898184e3Ssthenis(eval { opset(':_tst_') }, undef); 64898184e3Ssthenlike($@, qr/Unknown operator tag ":_tst_"/); 6585009909Smillertdefine_optag(":_tst_", opset(qw(padsv padav padhv))); 66898184e3Ssthenisnt(eval { opset(':_tst_') }, undef); 67898184e3Ssthenis($@, ''); 6885009909Smillert 6985009909Smillert# --- opdesc and opcodes 7085009909Smillert 71898184e3Ssthenis(opdesc("gv"), "glob value"); 7285009909Smillertmy @desc = opdesc(':_tst_','stub'); 73898184e3Ssthenis_deeply(\@desc, ['private variable', 'private array', 'private hash', 'stub']); 74898184e3Ssthenisnt(opcodes(), 0); 7585009909Smillert 7685009909Smillert# --- invert_opset 7785009909Smillert 7885009909Smillert$s1 = opset(qw(fileno padsv padav)); 79898184e3Ssthenmy @o1 = opset_to_ops(invert_opset($s1)); 80898184e3Ssthenis(scalar @o1, opcodes-3); 8185009909Smillert 8285009909Smillert# --- opmask 8385009909Smillert 84898184e3Ssthenis(opmask(), empty_opset()); 85898184e3Ssthenis(length opmask(), int((opcodes()+7)/8)); 8685009909Smillert 8785009909Smillert# --- verify_opset 8885009909Smillert 89898184e3Ssthenis(verify_opset($s1), 1); 90898184e3Ssthenis(verify_opset(42), 0); 9185009909Smillert 9285009909Smillert# --- opmask_add 9385009909Smillert 9485009909Smillertopmask_add(opset(qw(fileno))); # add to global op_mask 95898184e3Ssthenis(eval 'fileno STDOUT', undef); 96898184e3Ssthenlike($@, qr/'fileno' trapped/); 9785009909Smillert 9885009909Smillert# --- check use of bit vector ops on opsets 9985009909Smillert 10085009909Smillert$s1 = opset('padsv'); 10185009909Smillert$s2 = opset('padav'); 10285009909Smillert$s3 = opset('padsv', 'padav', 'padhv'); 10385009909Smillert 10485009909Smillert# Non-negated 105898184e3Ssthenis(($s1 | $s2), opset($s1,$s2)); 106898184e3Ssthenis(($s2 & $s3), opset($s2)); 107898184e3Ssthenis(($s2 ^ $s3), opset('padsv','padhv')); 10885009909Smillert 10985009909Smillert# Negated, e.g., with possible extra bits in last byte beyond last op bit. 11085009909Smillert# The extra bits mean we can't just say ~mask eq invert_opset(mask). 11185009909Smillert 11285009909Smillert@o1 = opset_to_ops( ~ $s3); 113898184e3Ssthenmy @o2 = opset_to_ops(invert_opset $s3); 114898184e3Ssthenis_deeply(\@o1, \@o2); 11585009909Smillert 116*b8851fccSafresh1# --- test context of undocumented _safe_call_sv (used by Safe.pm) 117*b8851fccSafresh1 118*b8851fccSafresh1my %inc = %INC; 119*b8851fccSafresh1my $expect; 120*b8851fccSafresh1sub f { 121*b8851fccSafresh1 %INC = %inc; 122*b8851fccSafresh1 no warnings 'uninitialized'; 123*b8851fccSafresh1 is wantarray, $expect, 124*b8851fccSafresh1 sprintf "_safe_call_sv gives %s context", 125*b8851fccSafresh1 qw[void scalar list][$expect + defined $expect] 126*b8851fccSafresh1}; 127*b8851fccSafresh1Opcode::_safe_call_sv("main", empty_opset, \&f); 128*b8851fccSafresh1$expect = !1; 129*b8851fccSafresh1$_ = Opcode::_safe_call_sv("main", empty_opset, \&f); 130*b8851fccSafresh1$expect = !0; 131*b8851fccSafresh1() = Opcode::_safe_call_sv("main", empty_opset, \&f); 132*b8851fccSafresh1 13385009909Smillert# --- finally, check some opname assertions 13485009909Smillert 135898184e3Ssthenforeach my $opname (@full_l1) { 136898184e3Ssthen unlike($opname, qr/\W/, "opname $opname has no non-'word' characters"); 137898184e3Ssthen unlike($opname, qr/^\d/, "opname $opname does not start with a digit"); 138898184e3Ssthen} 13985009909Smillert 140898184e3Ssthendone_testing(); 141