Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
improved backtrace printer
When encountering a a non-Routine, it searches for an outer Routine that
also appears in the call chain, and takes their name, but the line number
of the block. The idea comes from jnthn++

Testing welcome, not sure yet how well it interacts with lazy lists. At
least for normal for-loops it cuts all those eager/reify methods.
  • Loading branch information
moritz committed Feb 12, 2012
1 parent 9435a07 commit 941a305
Showing 1 changed file with 59 additions and 1 deletion.
60 changes: 59 additions & 1 deletion src/core/Backtrace.pm
Expand Up @@ -59,15 +59,73 @@ my class Backtrace is List {
$new;
}

method next-interesting-index(Int $idx is copy = 0) {
++$idx;
# NOTE: the < $.end looks like an off-by-one error
# but it turns out that a simple perl6 -e 'die "foo"'
# has two bt frames from the mainline; so it's OK to never
# consider the last one
loop (; $idx < $.end; ++$idx) {
my $cand = $.at_pos($idx);
return $idx unless $cand.is-hidden || $cand.is-setting;
}
Int;
}

method outer-caller-idx(Int $startidx) {
my %print;
my $start = $.at_pos($startidx).code;
my $current = $start.outer;
my %outers;
while $current {
%outers{$current.static_id} = $start;
$current = $current.outer;
}
my @outers;
loop (my Int $i = $startidx; $i < $.end; ++$i) {
if $.at_pos($i) && %outers{%.at_pos($i).code.static_id} {
@outers.push: $i;
return @outers if $.at_pos($i).is-routine;
}
}

return @outers;
}

method nice() {
my Int $i = self.next-interesting-index(-1);
my @frames;
while $i.defined {
my $prev = self.at_pos($i);
if $prev.is-routine {
@frames.push: $prev;
} else {
my @outer_callers := self.outer-caller-idx($i);
my ($target_idx) = @outer_callers.keys.grep({self.at_pos($i).code.^isa(Routine)});
$target_idx ||= @outer_callers[0] || $i;
my $current = self.at_pos($target_idx);
@frames.push: $current.clone(line => $prev.line);
$i = $target_idx;
}
$i = self.next-interesting-index($i);
}
return @frames.join;
}


method concise(Backtrace:D:) {
self.grep({ !.is-hidden && .is-routine && !.is-setting }).join
}

multi method Str(Backtrace:D:) {
self.grep({ !.is-hidden && (.is-routine || !.is-setting )}).join
self.nice;
}

method full(Backtrace:D:) {
self.join
}

method summary(Backtrace:D:) {
self.grep({ !.is-hidden && (.is-routine || !.is-setting )}).join
}
}

0 comments on commit 941a305

Please sign in to comment.