aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJack Koenig2020-05-22 12:13:08 -0700
committerJack Koenig2020-05-22 16:50:15 -0700
commitdb7928a44e737222524519be9d9b1cf3b2d7804a (patch)
treeed217aac5cf13c7da710294214c7182dbb2c58e0 /src
parent1930b7b0655028bd81707d8cfefba2310d3a1bbb (diff)
Do not throw NonFatal exceptions in annotation logging
If an annotation cannot be serialized by json4s, we should not throw exceptions when doing trace-level logging.
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/Compiler.scala11
-rw-r--r--src/test/scala/firrtlTests/annotationTests/JsonProtocolSpec.scala31
2 files changed, 38 insertions, 4 deletions
diff --git a/src/main/scala/firrtl/Compiler.scala b/src/main/scala/firrtl/Compiler.scala
index 5a7dd4c8..6f921189 100644
--- a/src/main/scala/firrtl/Compiler.scala
+++ b/src/main/scala/firrtl/Compiler.scala
@@ -6,6 +6,8 @@ import logger._
import java.io.Writer
import scala.collection.mutable
+import scala.util.Try
+import scala.util.control.NonFatal
import firrtl.annotations._
import firrtl.ir.Circuit
@@ -211,7 +213,14 @@ private[firrtl] object Transform {
logger.info(s"Form: ${after.form}")
logger.trace(s"Annotations:")
- logger.trace(JsonProtocol.serialize(remappedAnnotations))
+ logger.trace {
+ JsonProtocol.serializeTry(remappedAnnotations).recoverWith {
+ case NonFatal(e) =>
+ val msg = s"Exception thrown during Annotation serialization:\n " +
+ e.toString.replaceAll("\n", "\n ")
+ Try(msg)
+ }.get
+ }
logger.trace(s"Circuit:\n${after.circuit.serialize}")
logger.info(s"======== Finished Transform $name ========\n")
diff --git a/src/test/scala/firrtlTests/annotationTests/JsonProtocolSpec.scala b/src/test/scala/firrtlTests/annotationTests/JsonProtocolSpec.scala
index 507c5291..d1bd1fb2 100644
--- a/src/test/scala/firrtlTests/annotationTests/JsonProtocolSpec.scala
+++ b/src/test/scala/firrtlTests/annotationTests/JsonProtocolSpec.scala
@@ -2,10 +2,12 @@
package firrtlTests.annotationTests
-import firrtl.Parser
-import firrtl.annotations.{Annotation, JsonProtocol, NoTargetAnnotation}
+import firrtl._
+import firrtl.annotations.{JsonProtocol, NoTargetAnnotation}
import firrtl.ir._
-import org.scalatest.{FlatSpec, Matchers, PropSpec}
+import firrtl.options.Dependency
+import _root_.logger.{Logger, LogLevel, LogLevelAnnotation}
+import org.scalatest.{FlatSpec, Matchers}
case class AnAnnotation(
info: Info,
@@ -18,6 +20,16 @@ case class AnAnnotation(
groundType: GroundType
) extends NoTargetAnnotation
+class AnnoInjector extends Transform with DependencyAPIMigration {
+ override def optionalPrerequisiteOf = Dependency[ChirrtlEmitter] :: Nil
+ override def invalidates(a: Transform): Boolean = false
+ def execute(state: CircuitState): CircuitState = {
+ // Classes defined in method bodies can't be serialized by json4s
+ case class MyAnno(x: Int) extends NoTargetAnnotation
+ state.copy(annotations = MyAnno(3) +: state.annotations)
+ }
+}
+
class JsonProtocolSpec extends FlatSpec with Matchers {
"JsonProtocol" should "serialize and deserialize FIRRTL types" in {
@@ -40,4 +52,17 @@ class JsonProtocolSpec extends FlatSpec with Matchers {
val outputAnnos = JsonProtocol.deserialize(annosString)
inputAnnos should be (outputAnnos)
}
+
+ "Annotation serialization during logging" should "not throw an exception" in {
+ val compiler = new firrtl.stage.transforms.Compiler(Seq(Dependency[AnnoInjector]))
+ val circuit = Parser.parse("""
+ |circuit test :
+ | module test :
+ | output out : UInt<1>
+ | out <= UInt(0)
+ """.stripMargin)
+ Logger.makeScope(LogLevelAnnotation(LogLevel.Trace) :: Nil) {
+ compiler.execute(CircuitState(circuit, Nil))
+ }
+ }
}