Skip to content

VerifyError: Inconsistent stackmap frames at branch target #12993

Open
@danissimo

Description

@danissimo

Reproduction steps

Java: Oracle HotSpot 17.0.6+9-LTS-190, OpenJDK Temurin-17.0.8+7.
Scala versions: 2.13.10, 2.13.14.

I faced the behaviour using spray json ("io.spray" %% "spray-json" % "1.3.6"), and I couldn't minimise the snippet to clean scala, but the hint to the nature of the bug is the two workarounds at the bottom of this report.

import spray.json.DefaultJsonProtocol._
import spray.json._

object BadScalac {
  def main(args: Array[String]): Unit = {
    val msg = (
      try Map("block" -> "try").toJson
      catch { case _: Throwable => Map("block" -> "catch").toJson }
    ).prettyPrint + "\n"
    println(msg)
  }
}

Problem

It gets compiled successfully, but when I run I get

Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 152
Exception Details:
  Location:
    BadScalac$.main([Ljava/lang/String;)V @149: goto
  Reason:
    Current frame's stack size doesn't match stackmap.
  Current Frame:
    bci: @149
    flags: { }
    locals: { 'BadScalac$', '[Ljava/lang/String;' }
    stack: { 'spray/json/JsValue' }
  Stackmap Frame:
    bci: @152
    flags: { }
    locals: { 'BadScalac$', '[Ljava/lang/String;' }
    stack: { 'java/lang/Object', 'spray/json/JsValue' }
  Bytecode:
    0000000: bb00 1f59 1220 b700 23b2 0028 b200 2db6
    0000010: 0031 b200 3604 bd00 3859 03b2 003b b200
    0000020: 2d12 3db6 0041 1243 b600 4753 c000 49b6
    0000030: 004d b600 53b6 0057 b200 5cb2 005c b600
    0000040: 60b2 005c b600 60b6 0064 b600 6aa7 004b
    0000050: 57b2 0028 b200 2db6 0031 b200 3604 bd00
    0000060: 3859 03b2 003b b200 2d12 3db6 0041 126c
    0000070: b600 4753 c000 49b6 004d b600 53b6 0057
    0000080: b200 5cb2 005c b600 60b2 005c b600 60b6
    0000090: 0064 b600 6aa7 0003 b600 72b6 0076 1278
    00000a0: b600 76b6 007b 4db2 002d 2cb6 007f b1  
  Exception Handler Table:
    bci [9, 77] => handler: 80
  Stackmap Table:
    same_locals_1_stack_item_extended(@80,Object[#29])
    full_frame(@152,{Object[#2],Object[#132]},{Object[#4],Object[#110]})

	at BadScalac.main(BadScalac.scala)

But it goes away when I rewrite the source code as

import spray.json.DefaultJsonProtocol._
import spray.json._

object BadScalac extends App {
  val msg = (
    try Map("block" -> "try").toJson
    catch { case _: Throwable => Map("block" -> "catch").toJson }
  ).prettyPrint + "\n"
  println(msg)
}

or even when I drop the last addition of the "\n" string:

object BadScalac {
  def main(args: Array[String]): Unit = {
    val msg = (
      try Map("block" -> "try").toJson
      catch { case _: Throwable => Map("block" -> "catch").toJson }
    ).prettyPrint
    println(msg)
  }
}

The both snippets above yield

{
  "block": "try"
}

with and without the last newline respectively.

Metadata

Metadata

Assignees

No one assigned

    Labels

    fixed in Scala 3This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)help wanted

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions