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] }; }],
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;
{
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
$ip += 1;
}
}
+
+ return $ret;
};
$nfa->($ip, $copy_handler->($state));
{
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
}
}
}
- 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}})
my %left = map { $_ => 1 } @{$write_places{$ip}{$operand}};
my $isread = 0;
+ my %writeplace_seen = ();
run_nfa $progs, $ip+1, \%left,
sub
{
{
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