Skip to content

Commit 7494019

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

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
@@ -925,6 +925,8 @@ final class Analyzer(config: CommonPhaseConfig, initial: Boolean,
925925
private def computeMostSpecificProxyMatch(candidates: List[MethodInfo])(
926926
implicit from: From): Future[MethodInfo] = {
927927

928+
implicit val ec = workTracker.ec
929+
928930
/* From the JavaDoc of java.lang.Class.getMethod:
929931
*
930932
* If more than one [candidate] method is found in C, and one of these
@@ -933,31 +935,36 @@ final class Analyzer(config: CommonPhaseConfig, initial: Boolean,
933935
* chosen arbitrarily.
934936
*/
935937

936-
val resultTypes = candidates.map(c => c.methodName.resultTypeRef)
938+
def ifMostSpecific(candidate: MethodInfo): Future[Option[MethodInfo]] = {
939+
val specificityChecks = for {
940+
otherCandidate <- candidates
941+
if candidate != otherCandidate
942+
} yield {
943+
isMoreSpecific(otherCandidate.methodName.resultTypeRef,
944+
candidate.methodName.resultTypeRef)
945+
}
937946

938-
// We must not use Future.traverse since otherwise we might run things on
939-
// the non-main thread.
940-
val specificityChecks = resultTypes.map { x =>
941-
for (y <- resultTypes if x != y)
942-
yield isMoreSpecific(y, x)
947+
for {
948+
moreSpecific <- Future.find(specificityChecks)(identity)
949+
} yield {
950+
if (moreSpecific.isEmpty) Some(candidate)
951+
else None
952+
}
943953
}
944954

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

949-
val hasMoreSpecific = Future.traverse(specificityChecks)(
950-
checks => Future.sequence(checks).map(_.contains(true)))
951-
952-
hasMoreSpecific.map { hms =>
953-
val targets = candidates.zip(hms).filterNot(_._2).map(_._1)
954-
955-
/* This last step (chosen arbitrarily) causes some soundness issues of
956-
* the implementation of reflective calls. This is bug-compatible with
957-
* Scala/JVM.
958-
*/
959-
targets.head
960-
}
957+
/* This last step (chosen arbitrarily) causes some soundness issues of
958+
* the implementation of reflective calls. This is bug-compatible with
959+
* Scala/JVM.
960+
*/
961+
for {
962+
candidate <- Future.find(specificCandidates)(_.nonEmpty)
963+
} yield {
964+
/* First get: There must be a most specific candidate.
965+
* Second get: That's our find condition from above.
966+
*/
967+
candidate.get.get
961968
}
962969
}
963970

0 commit comments

Comments
 (0)