X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=misc%2Ftools%2Fprogs-analyzer.pl;h=e1594f1d7939eb028a5f1950f9eaabd78ab78062;hb=c10826e75fbc64afc7e69bda232d80e9517ffdde;hp=d05031c0fb31e1662fac0c4335eae5eb537d743f;hpb=34adbf6d4d2223552f796d13cd4b92789796428a;p=xonotic%2Fxonotic.git diff --git a/misc/tools/progs-analyzer.pl b/misc/tools/progs-analyzer.pl index d05031c0..e1594f1d 100644 --- a/misc/tools/progs-analyzer.pl +++ b/misc/tools/progs-analyzer.pl @@ -127,7 +127,7 @@ use constant TYPES => { int => ['V', 4, signed 32], ushort => ['v', 2, id], short => ['v', 2, signed 16], - opcode => ['v', 2, sub { OPCODE_E->[$_[0]] or die "Invalid opcode: $_[0]"; }], + opcode => ['v', 2, sub { OPCODE_E->[$_[0]] or do { warn "Invalid opcode: $_[0]"; "INVALID#$_[0]"; }; }], float => ['f', 4, id], uchar8 => ['a8', 8, sub { [unpack 'C8', $_[0]] }], global => ['i', 4, sub { { int => $_[0], float => unpack "f", pack "L", $_[0] }; }], @@ -249,16 +249,17 @@ sub run_nfa($$$$$$) no warnings 'recursion'; my ($ip, $state) = @_; + my $ret = 0; for(;;) { - return + return $ret if $state_checker->($ip, $state); my $s = $statements->[$ip]; my $c = checkop $s->{op}; - if($instruction_handler->($ip, $state, $s, $c)) + if(($ret = $instruction_handler->($ip, $state, $s, $c))) { # abort execution last; @@ -268,13 +269,29 @@ sub run_nfa($$$$$$) { last; } + elsif($c->{iscall}) + { + my $func = $s->{a}; + my $funcid = $progs->{globals}[$func]{v}{int}; + my $funcobj = $progs->{functions}[$funcid]; + if($funcobj && $funcobj->{first_statement} < 0) # builtin + { + my $def = $progs->{globaldef_byoffset}->($func); + last + if $def->{debugname} eq '_error'; + } + $ip += 1; + } elsif($c->{isjump}) { if($c->{isconditional}) { if(rand 2) { - $nfa->($ip+$s->{$c->{isjump}}, $copy_handler->($state)); + if(($ret = $nfa->($ip+$s->{$c->{isjump}}, $copy_handler->($state))) < 0) + { + last; + } $ip += 1; } else @@ -293,6 +310,8 @@ sub run_nfa($$$$$$) $ip += 1; } } + + return $ret; }; $nfa->($ip, $copy_handler->($state)); @@ -516,14 +535,6 @@ sub find_uninitialized_locals($$) { my ($progs, $func) = @_; -# TODO -# 21:04:25 divVerent | just wondering how I can best detect "temp value is never used" -# 21:04:33 divVerent | I know which vars are temps already -# 21:04:59 divVerent | basically, looks like for each write, I will not just have to track that the new value is valid -# 21:05:01 divVerent | but also its source -# 21:05:12 divVerent | on each read, I'll remember that this source statement's value has been used -# 21:05:21 divVerent | and will compare the list of sources in a step after "execution" -# 21:05:27 divVerent | to the list of total write statements to the temp return if $func->{first_statement} < 0; # builtin @@ -771,18 +782,11 @@ sub find_uninitialized_locals($$) } } } - else # builtin - { - my $def = $progs->{globaldef_byoffset}->($func); - return 1 - if $def->{debugname} eq 'error'; - } } return 0; }; - my %writeplace_seen = (); for my $ip(keys %write_places) { for my $operand(keys %{$write_places{$ip}}) @@ -791,6 +795,7 @@ sub find_uninitialized_locals($$) my %left = map { $_ => 1 } @{$write_places{$ip}{$operand}}; my $isread = 0; + my %writeplace_seen = (); run_nfa $progs, $ip+1, \%left, sub { @@ -1017,7 +1022,7 @@ sub parse_progs($) { next if $globaldefs{$_->{debugname}} <= 1; - print "Not unique: $_->{debugname} at $_->{ofs}\n"; + #print "Not unique: $_->{debugname} at $_->{ofs}\n"; $_->{debugname} .= "\@$_->{ofs}"; } $p{globaldef_byoffset} = sub