From 531dd6cb7a91b9bb642368d792e9c5e0c1c72089 Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Fri, 2 Mar 2018 16:40:28 -0800 Subject: Fix for 792 (#793) Makes Builder.updateBundleStack a bit stricter in deciding how many stack frames to discard by additionally matching against method names and deleting stack frames at or above the frame currently being inserted.--- .../src/main/scala/chisel3/internal/Builder.scala | 23 +++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'chiselFrontend') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 2cb206d4..5e456030 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -173,8 +173,8 @@ private[chisel3] class DynamicContext() { var currentClockAndReset: Option[ClockAndReset] = None val errors = new ErrorLog val namingStack = new internal.naming.NamingStack - // Record the Bundle instance, class name, and reverse stack trace position of open Bundles - val bundleStack: ArrayBuffer[(Bundle, String, Int)] = ArrayBuffer() + // Record the Bundle instance, class name, method name, and reverse stack trace position of open Bundles + val bundleStack: ArrayBuffer[(Bundle, String, String, Int)] = ArrayBuffer() } private[chisel3] object Builder { @@ -247,13 +247,19 @@ private[chisel3] object Builder { // Returns the current stack of open Bundles // Note: elt will NOT have finished construction, its elements cannot be accessed def updateBundleStack(elt: Bundle): Seq[Bundle] = { - val stackClasses = Thread.currentThread().getStackTrace() - .map(_.getClassName) + val stackElts = Thread.currentThread().getStackTrace() .reverse // so stack frame numbers are deterministic across calls + .dropRight(2) // discard Thread.getStackTrace and updateBundleStack + + // Determine where we are in the Bundle stack + val eltClassName = elt.getClass.getName + val eltStackPos = stackElts.map(_.getClassName).lastIndexOf(eltClassName) // Prune the existing Bundle stack of closed Bundles - val pruneLength = dynamicContext.bundleStack.reverse.prefixLength { case (_, cname, pos) => - pos >= stackClasses.size || stackClasses(pos) != cname + // If we know where we are in the stack, discard frames above that + val stackEltsTop = if (eltStackPos >= 0) eltStackPos else stackElts.size + val pruneLength = dynamicContext.bundleStack.reverse.prefixLength { case (_, cname, mname, pos) => + pos >= stackEltsTop || stackElts(pos).getClassName != cname || stackElts(pos).getMethodName != mname } dynamicContext.bundleStack.trimEnd(pruneLength) @@ -261,10 +267,9 @@ private[chisel3] object Builder { val lastStack = dynamicContext.bundleStack.map(_._1).toSeq // Append the current Bundle to the stack, if it's on the stack trace - val eltClassName = elt.getClass.getName - val eltStackPos = stackClasses.lastIndexOf(eltClassName) if (eltStackPos >= 0) { - dynamicContext.bundleStack.append((elt, eltClassName, eltStackPos)) + val stackElt = stackElts(eltStackPos) + dynamicContext.bundleStack.append((elt, eltClassName, stackElt.getMethodName, eltStackPos)) } // Otherwise discard the stack frame, this shouldn't fail noisily -- cgit v1.2.3