Skip to content

Expects: getfield but INVOKEINTERFACE when using trait parameters #23053

@He-Pin

Description

@He-Pin
  • Scala version 3.3.5
  • feature: trait parameter
  • bug: I expect the bytecode to be a getfield but got an INVOKEINTERFACE

background:

I am doing performance optimization, where I need to access a _tag field.
see:

But I got:

  // access flags 0x1
  public visitExpr(Lsjsonnet/Expr;[Lsjsonnet/Lazy;)Lsjsonnet/Val;
    // parameter final  e
    // parameter final  scope
    TRYCATCHBLOCK L0 L1 L2 java/lang/Throwable
    TRYCATCHBLOCK L3 L4 L2 java/lang/Throwable
   L0
    LINENUMBER 33 L0
    ALOAD 1
    INVOKEINTERFACE sjsonnet/Expr._tag ()I (itf) //I would like this to be a getfield.

My local change is :

trait Expr (private[sjsonnet] val _tag :Int = ExprTags.UNTAGGED){
  def pos: Position

  /** The name of this expression type to be shown in error messages */
  def exprErrorString: String = {
    val n = getClass.getName
    if(n.startsWith("sjsonnet.Expr$")) n.substring(14) else n
  }

  override def toString: String = s"$exprErrorString@$pos"
}

and then something like:

case class ImportStr(pos: Position, value: String) extends Expr(ExprTags.ImportStr)

But when I use it as code below, it still INVOKEINTERFACE sjsonnet/Expr._tag ()I (itf)

  override def visitExpr(e: Expr)(implicit scope: ValScope): Val = try {
    (e._tag: @switch) match {
      case ExprTags.ValidId => visitValidId(e.asInstanceOf[ValidId])
      case ExprTags.BinaryOp => visitBinaryOp(e.asInstanceOf[BinaryOp])

refs: databricks/sjsonnet#313

btw, as Scala is now using Java 17, there is a https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/runtime/SwitchBootstraps.html

Will Scala leverage that?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions