Skip to content

Commit 1f37da9

Browse files
committed
Rewrite computeMostSpecificProxyMatch
Now that we can run in parallel, we can use full future power.
1 parent 41f178d commit 1f37da9

File tree

1 file changed

+28
-21
lines changed
  • linker/shared/src/main/scala/org/scalajs/linker/analyzer

1 file changed

+28
-21
lines changed

linker/shared/src/main/scala/org/scalajs/linker/analyzer/Analyzer.scala

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,8 @@ final class Analyzer(config: CommonPhaseConfig, initial: Boolean,
916916
private def computeMostSpecificProxyMatch(candidates: List[MethodInfo])(
917917
implicit from: From): Future[MethodInfo] = {
918918

919+
implicit val ec = workTracker.ec
920+
919921
/* From the JavaDoc of java.lang.Class.getMethod:
920922
*
921923
* If more than one [candidate] method is found in C, and one of these
@@ -924,31 +926,36 @@ final class Analyzer(config: CommonPhaseConfig, initial: Boolean,
924926
* chosen arbitrarily.
925927
*/
926928

927-
val resultTypes = candidates.map(c => c.methodName.resultTypeRef)
929+
def ifMostSpecific(candidate: MethodInfo): Future[Option[MethodInfo]] = {
930+
val specificityChecks = for {
931+
otherCandidate <- candidates
932+
if candidate != otherCandidate
933+
} yield {
934+
isMoreSpecific(otherCandidate.methodName.resultTypeRef,
935+
candidate.methodName.resultTypeRef)
936+
}
928937

929-
// We must not use Future.traverse since otherwise we might run things on
930-
// the non-main thread.
931-
val specificityChecks = resultTypes.map { x =>
932-
for (y <- resultTypes if x != y)
933-
yield isMoreSpecific(y, x)
938+
for {
939+
moreSpecific <- Future.find(specificityChecks)(identity)
940+
} yield {
941+
if (moreSpecific.isEmpty) Some(candidate)
942+
else None
943+
}
934944
}
935945

936-
// Starting here, we just do data juggling, so it can run on any thread.
937-
locally {
938-
implicit val iec = workTracker.ec
946+
val specificCandidates = candidates.map(ifMostSpecific)
939947

940-
val hasMoreSpecific = Future.traverse(specificityChecks)(
941-
checks => Future.sequence(checks).map(_.contains(true)))
942-
943-
hasMoreSpecific.map { hms =>
944-
val targets = candidates.zip(hms).filterNot(_._2).map(_._1)
945-
946-
/* This last step (chosen arbitrarily) causes some soundness issues of
947-
* the implementation of reflective calls. This is bug-compatible with
948-
* Scala/JVM.
949-
*/
950-
targets.head
951-
}
948+
/* This last step (chosen arbitrarily) causes some soundness issues of
949+
* the implementation of reflective calls. This is bug-compatible with
950+
* Scala/JVM.
951+
*/
952+
for {
953+
candidate <- Future.find(specificCandidates)(_.nonEmpty)
954+
} yield {
955+
/* First get: There must be a most specific candidate.
956+
* Second get: That's our find condition from above.
957+
*/
958+
candidate.get.get
952959
}
953960
}
954961

0 commit comments

Comments
 (0)