about summary refs log tree commit diff stats
path: root/036call_reply.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-10-19 15:07:54 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-10-19 15:45:55 -0700
commit77cdc6d03f7b5660f6df6e57a6e50b015e41e3ea (patch)
tree1cf49f61c1fb1056b7fda6a84f4f2f95bd95fbae /036call_reply.cc
parentf8aa4b17efed4f56b0c023cf40eb6d6000be1748 (diff)
downloadmu-77cdc6d03f7b5660f6df6e57a6e50b015e41e3ea.tar.gz
2271 - bugfix: traces cross-contaminating errors
There were several places where we push a call on to a routine without
incrementing call-stack depth, which was used to compute the depth at
which to trace an instruction. So sometimes you ended up one depth lower
than you started a call with. Do this enough times and instructions that
should be traced at level 100 end up at level 0 and pop up as errors.

Solution: since call-stack depth is only used for tracing, include it in
the trace stream and make sure we reset it along with the trace stream.
Then catch all places where we forget to increment call-stack depth and
make sure we catch such places in the future.

When I first ran into this with Caleb I thought there must be some way
that we're writing some output into the warnings result. I didn't
recognize that the spurious output as part of the trace, just at the
wrong level.
Diffstat (limited to '036call_reply.cc')
-rw-r--r--036call_reply.cc6
1 files changed, 5 insertions, 1 deletions
diff --git a/036call_reply.cc b/036call_reply.cc
index ccf18a2f..e2e34c06 100644
--- a/036call_reply.cc
+++ b/036call_reply.cc
@@ -25,7 +25,11 @@ case REPLY: {
   // Starting Reply
   const instruction& reply_inst = current_instruction();  // save pointer into recipe before pop
   const string& callee = current_recipe_name();
-  --Callstack_depth;
+  if (Trace_stream) {
+    trace("trace") << "reply: decrementing callstack depth from " << Trace_stream->callstack_depth << end();
+    --Trace_stream->callstack_depth;
+    assert(Trace_stream->callstack_depth >= 0);
+  }
   Current_routine->calls.pop_front();
   // just in case 'main' returns a value, drop it for now
   if (Current_routine->calls.empty()) goto stop_running_current_routine;
} /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
# example program: maintain multiple counters with isolated lexical scopes
# (spaces)

recipe new-counter n:number -> default-space:address:array:location [
  default-space <- new location:type, 30
  load-ingredients
]

recipe increment-counter outer:address:array:location/names:new-counter, x:number -> n:number/space:1 [
  local-scope
  load-ingredients
  0:address:array:location/names:new-counter <- copy outer  # setup outer space; it *must* come from 'new-counter'
  n/space:1 <- add n/space:1, x
]

recipe main [
  local-scope
  # counter A
  a:address:array:location <- new-counter 34
  # counter B
  b:address:array:location <- new-counter 23
  # increment both by 2 but in different ways
  increment-counter a, 1
  b-value:number <- increment-counter b, 2
  a-value:number <- increment-counter a, 1
  # check results
  $print [Contents of counters
]
  # trailing space in next line is to help with syntax highlighting
  $print [a: ], a-value, [ b: ], b-value, [ 
]
]