Skip to content

Commit

Permalink
Merge pull request #4983 from sjrd/fix-hijacked-class-refl-proxy-this…
Browse files Browse the repository at this point in the history
…-type

Fix #4982: Synthesize This nodes with primitive types in hijacked classes.
  • Loading branch information
gzm0 committed May 16, 2024
2 parents 94c63fd + 69baff1 commit db4d46c
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.scalajs.ir.Types._
import org.scalajs.logging._

import org.scalajs.linker.checker.ErrorReporter._
import org.scalajs.linker.standard.LinkedClass

/** Checker for the validity of the IR. */
private final class ClassDefChecker(classDef: ClassDef,
Expand Down Expand Up @@ -925,6 +926,30 @@ object ClassDefChecker {
reporter.errorCount
}

def check(linkedClass: LinkedClass, postOptimizer: Boolean, logger: Logger): Int = {
// Rebuild a ClassDef out of the LinkedClass
import linkedClass._
implicit val pos = linkedClass.pos
val classDef = ClassDef(
name,
OriginalName.NoOriginalName,
kind,
jsClassCaptures,
superClass,
interfaces,
jsSuperClass,
jsNativeLoadSpec,
fields,
methods,
jsConstructorDef,
exportedMembers,
jsNativeMembers,
topLevelExportDefs = Nil
)(optimizerHints)

check(classDef, postBaseLinker = true, postOptimizer, logger)
}

private class Env(
/** Whether there is a valid `new.target` in scope. */
val hasNewTarget: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ private[frontend] final class MethodSynthesizer(
val targetIdent = targetMDef.name.copy() // for the new pos
val proxyIdent = MethodIdent(methodName)
val params = targetMDef.args.map(_.copy()) // for the new pos
val currentClassType = ClassType(classInfo.className)
val instanceThisType =
BoxedClassToPrimType.getOrElse(classInfo.className, ClassType(classInfo.className))

val call = Apply(ApplyFlags.empty, This()(currentClassType),
val call = Apply(ApplyFlags.empty, This()(instanceThisType),
targetIdent, params.map(_.ref))(targetMDef.resultType)

val body = if (targetName.resultTypeRef == VoidRef) {
Expand Down Expand Up @@ -100,10 +101,11 @@ private[frontend] final class MethodSynthesizer(
val targetIdent = targetMDef.name.copy() // for the new pos
val bridgeIdent = targetIdent
val params = targetMDef.args.map(_.copy()) // for the new pos
val currentClassType = ClassType(classInfo.className)
val instanceThisType =
BoxedClassToPrimType.getOrElse(classInfo.className, ClassType(classInfo.className))

val body = ApplyStatically(
ApplyFlags.empty, This()(currentClassType), targetInterface,
ApplyFlags.empty, This()(instanceThisType), targetInterface,
targetIdent, params.map(_.ref))(targetMDef.resultType)

MethodDef(MemberFlags.empty, bridgeIdent, targetMDef.originalName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import org.scalajs.ir.Types._

import org.scalajs.junit.async._

import org.scalajs.logging._

import org.scalajs.linker.checker.ClassDefChecker
import org.scalajs.linker.interface.StandardConfig
import org.scalajs.linker.standard._

Expand Down Expand Up @@ -67,6 +70,28 @@ class BaseLinkerTest {
}
}

@Test
def correctThisTypeInHijackedClassReflectiveProxies_Issue4982(): AsyncResult = await {
val compareTo = m("compareTo", List(ClassRef(BoxedIntegerClass)), IntRef)
val compareToReflProxy =
MethodName.reflectiveProxy("compareTo", List(ClassRef(BoxedIntegerClass)))

val classDefs = Seq(
mainTestClassDef(
consoleLog(Apply(EAF, IntLiteral(5), compareToReflProxy, List(IntLiteral(6)))(AnyType))
)
)

val config = StandardConfig().withOptimizer(false)

for (moduleSet <- linkToModuleSet(classDefs, MainTestModuleInitializers, config = config)) yield {
val clazz = findClass(moduleSet, BoxedIntegerClass).get
val errorCount = ClassDefChecker.check(clazz, postOptimizer = false,
new ScalaConsoleLogger(Level.Error))
assertEquals(0, errorCount)
}
}

private def findClass(moduleSet: ModuleSet, name: ClassName): Option[LinkedClass] =
moduleSet.modules.flatMap(_.classDefs).find(_.className == name)
}

0 comments on commit db4d46c

Please sign in to comment.