summaryrefslogtreecommitdiff
path: root/chiselFrontend
diff options
context:
space:
mode:
authorRichard Lin2018-03-02 16:40:28 -0800
committerGitHub2018-03-02 16:40:28 -0800
commit531dd6cb7a91b9bb642368d792e9c5e0c1c72089 (patch)
tree378224bf443a21d821d51138e68b458c009950ce /chiselFrontend
parent46553432aaf65cff131e59081d57dabe16c2ab55 (diff)
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.
Diffstat (limited to 'chiselFrontend')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/Builder.scala23
1 files changed, 14 insertions, 9 deletions
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