Skip to content

Commit

Permalink
rewrite backtrace iteration to eliminate special-case for top stack e…
Browse files Browse the repository at this point in the history
…lement

this eliminates essentially duplicate code
  • Loading branch information
plobsing committed Sep 2, 2011
1 parent d52dba8 commit bab687c
Showing 1 changed file with 21 additions and 77 deletions.
98 changes: 21 additions & 77 deletions src/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -3651,94 +3651,45 @@ Returns an string with the backtrace of interpreter's call chain for the given c
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
static STRING *
PDB_get_continuation_backtrace(PARROT_INTERP, ARGMOD(PMC * ctx))
PDB_get_continuation_backtrace(PARROT_INTERP, ARGIN(PMC *ctx))
{
ASSERT_ARGS(PDB_get_continuation_backtrace)
PMC *sub = Parrot_pcc_get_sub(interp, ctx);
STRING *str;
PMC *old = PMCNULL;
PMC *output = Parrot_pmc_new(interp, enum_class_StringBuilder);
int rec_level = 0;
int limit_count = 0;

if (!PMC_IS_NULL(sub)) {
str = Parrot_sub_Context_infostr(interp, ctx);
if (str) {
PackFile_ByteCode *seg = PARROT_SUB(CONTEXT_STRUCT(ctx)->current_sub)->seg;
VTABLE_push_string(interp, output, str);
if (seg->annotations) {
PMC *annot = PackFile_Annotations_lookup(interp, seg->annotations,
Parrot_pcc_get_pc(interp, ctx) - seg->base.data + 1, NULL);
if (!PMC_IS_NULL(annot)) {
PMC *pfile = VTABLE_get_pmc_keyed_str(interp, annot,
Parrot_str_new_constant(interp, "file"));
PMC *pline = VTABLE_get_pmc_keyed_str(interp, annot,
Parrot_str_new_constant(interp, "line"));
if ((!PMC_IS_NULL(pfile)) && (!PMC_IS_NULL(pline))) {
STRING * const file = VTABLE_get_string(interp, pfile);
INTVAL line = VTABLE_get_integer(interp, pline);
STRING * const fmt =
Parrot_sprintf_c(interp, " (%Ss:%li)", file, (long)line);
VTABLE_push_string(interp, output, fmt);
}
}
}
VTABLE_push_string(interp, output, CONST_STRING(interp, "\n"));
}
}
PMC *output = Parrot_pmc_new(interp, enum_class_StringBuilder);
int rec_level = 0;
int loop_count;
PMC *prev_ctx;

/* backtrace: follow the continuation chain */
while (1) {
Parrot_Continuation_attributes *sub_cont;

/* Limit the levels dumped, no segfault on infinite recursion */
if (++limit_count > RECURSION_LIMIT)
for (prev_ctx = PMCNULL, loop_count = 0;
ctx && loop_count < RECURSION_LIMIT;
loop_count++, prev_ctx = ctx, ctx = Parrot_pcc_get_caller_ctx(interp, ctx)) {
STRING *info_str = Parrot_sub_Context_infostr(interp, ctx);
if (!info_str)
break;

sub = Parrot_pcc_get_continuation(interp, ctx);

if (PMC_IS_NULL(sub))
break;


sub_cont = PARROT_CONTINUATION(sub);

if (!sub_cont)
break;


str = Parrot_sub_Context_infostr(interp, Parrot_pcc_get_caller_ctx(interp, ctx));


if (!str)
break;


/* recursion detection */
if (ctx == sub_cont->to_ctx) {
if (ctx == prev_ctx) {
++rec_level;
}
else if (!PMC_IS_NULL(old) && PMC_cont(old) &&
Parrot_pcc_get_pc(interp, PMC_cont(old)->to_ctx) ==
Parrot_pcc_get_pc(interp, PMC_cont(sub)->to_ctx) &&
Parrot_pcc_get_sub(interp, PMC_cont(old)->to_ctx) ==
Parrot_pcc_get_sub(interp, PMC_cont(sub)->to_ctx)) {
++rec_level;
else if (!PMC_IS_NULL(prev_ctx)
&& Parrot_pcc_get_pc(interp, ctx) == Parrot_pcc_get_pc(interp, prev_ctx)
&& Parrot_pcc_get_sub(interp, ctx) == Parrot_pcc_get_sub(interp, prev_ctx)) {
++rec_level;
}
else if (rec_level != 0) {
STRING * const fmt =
Parrot_sprintf_c(interp, "... call repeated %d times\n", rec_level);
VTABLE_push_string(interp, output, fmt);
rec_level = 0;
}

/* print the context description */
if (rec_level == 0) {
PackFile_ByteCode *seg = sub_cont->seg;
VTABLE_push_string(interp, output, str);
else {
/* print the context description */
PMC *sub = Parrot_pcc_get_sub(interp, ctx);
PackFile_ByteCode *seg = PARROT_SUB(sub)->seg;
VTABLE_push_string(interp, output, info_str);
if (seg->annotations) {
PMC *annot = PackFile_Annotations_lookup(interp, seg->annotations,
Parrot_pcc_get_pc(interp, sub_cont->to_ctx) - seg->base.data,
Parrot_pcc_get_pc(interp, ctx) - seg->base.data,
NULL);

if (!PMC_IS_NULL(annot)) {
Expand All @@ -3757,13 +3708,6 @@ PDB_get_continuation_backtrace(PARROT_INTERP, ARGMOD(PMC * ctx))
}
VTABLE_push_string(interp, output, CONST_STRING(interp, "\n"));
}

/* get the next Continuation */
ctx = Parrot_pcc_get_caller_ctx(interp, ctx);
old = sub;

if (!ctx)
break;
}

if (rec_level != 0) {
Expand Down

0 comments on commit bab687c

Please sign in to comment.