Skip to content

Commit

Permalink
Merge pull request #10735 from lrytz/staticQualifier
Browse files Browse the repository at this point in the history
Emit missing `POP` in backend when accessing static fields
  • Loading branch information
SethTisue committed Apr 8, 2024
2 parents 5a6caca + 911d375 commit ef341f4
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 3 deletions.
Expand Up @@ -381,7 +381,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
val sym = tree.symbol
generatedType = symInfoTK(sym)
val qualSafeToElide = treeInfo isQualifierSafeToElide qualifier
def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree) } }
def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree, drop = true) } }
// receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError, scala/bug#4283
def receiverClass = qualifier.tpe.typeSymbol
if (sym.isModule) {
Expand Down Expand Up @@ -1054,10 +1054,10 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
}

/* Emit code to Load the qualifier of `tree` on top of the stack. */
def genLoadQualifier(tree: Tree): Unit = {
def genLoadQualifier(tree: Tree, drop: Boolean = false): Unit = {
lineNumber(tree)
tree match {
case Select(qualifier, _) => genLoad(qualifier)
case Select(qualifier, _) => genLoad(qualifier, if (drop) UNIT else tpeTK(qualifier))
case _ => abort(s"Unknown qualifier $tree")
}
}
Expand Down
3 changes: 3 additions & 0 deletions test/files/run/staticQualifier.check
@@ -0,0 +1,3 @@
42
hai
42
21 changes: 21 additions & 0 deletions test/files/run/staticQualifier/A_1.scala
@@ -0,0 +1,21 @@
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object A {
def foo(x: Int): Int = macro foo_impl

def foo_impl(c: Context)(x: c.Expr[Int]): c.Tree = {
val g = c.universe.asInstanceOf[scala.tools.nsc.Global]
import g._
import scala.tools.nsc.symtab.Flags._

val t = x.tree.asInstanceOf[Tree] match {
case s @ Select(_, n) if n.toString == "f2" =>
val field = s.symbol.accessed
field.setFlag(STATIC).resetFlag(PRIVATE | LOCAL)
s.setSymbol(field)
}

t.asInstanceOf[c.Tree]
}
}
24 changes: 24 additions & 0 deletions test/files/run/staticQualifier/Test_2.scala
@@ -0,0 +1,24 @@
import scala.tools.partest.BytecodeTest
import scala.tools.testkit.ASMConverters._
import scala.tools.asm.Opcodes._

object Test extends BytecodeTest {
val f2 = 42

def getT: Test.type = {
println("hai")
Test
}

def show(): Unit = {
println(A.foo(Test.f2))
println(A.foo(getT.f2))

val ins = instructionsFromMethod(getMethod(loadClassNode("Test$"), "show"))
val gs = ins.count {
case Field(GETSTATIC, "Test$", "f2", _) => true
case _ => false
}
assert(gs == 2)
}
}

0 comments on commit ef341f4

Please sign in to comment.