Skip to content

Commit eb1c59d

Browse files
committed
Do not generate reflective proxies in the compiler anymore.
This is follow up to the parent commit. Now that reflective proxies are synthesized at link time, they are not needed in sjsir files anymore.
1 parent 3ebbd17 commit eb1c59d

File tree

3 files changed

+3
-122
lines changed

3 files changed

+3
-122
lines changed

compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala

Lines changed: 1 addition & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,9 @@ abstract class GenJSCode extends plugins.PluginComponent
367367
memberExports ++ exportedConstructorsOrAccessors
368368
}
369369

370-
// Generate the reflective call proxies (where required)
371-
val reflProxies =
372-
if (isHijacked) Nil
373-
else genReflCallProxies(sym)
374-
375370
// Hashed definitions of the class
376371
val hashedDefs =
377-
Hashers.hashDefs(generatedMembers ++ exports ++ reflProxies)
372+
Hashers.hashDefs(generatedMembers ++ exports)
378373

379374
// The complete class definition
380375
val kind =
@@ -890,120 +885,6 @@ abstract class GenJSCode extends plugins.PluginComponent
890885
afterSuper)(body.pos)
891886
}
892887

893-
/**
894-
* Generates reflective proxy methods for methods in sym
895-
*
896-
* Reflective calls don't depend on the return type, so it's hard to
897-
* generate calls without using runtime reflection to list the methods. We
898-
* generate a method to be used for reflective calls (without return
899-
* type in the name).
900-
*
901-
* There are cases where non-trivial overloads cause ambiguous situations:
902-
*
903-
* {{{
904-
* object A {
905-
* def foo(x: Option[Int]): String
906-
* def foo(x: Option[String]): Int
907-
* }
908-
* }}}
909-
*
910-
* This is completely legal code, but due to the same erased parameter
911-
* type of the {{{foo}}} overloads, they cannot be disambiguated in a
912-
* reflective call, as the exact return type is unknown at the call site.
913-
*
914-
* Cases like the upper currently fail on the JVM backend at runtime. The
915-
* Scala.js backend uses the following rules for selection (which will
916-
* also cause runtime failures):
917-
*
918-
* - If a proxy with the same signature (method name and parameters)
919-
* exists in the superclass, no proxy is generated (proxy is inherited)
920-
* - If no proxy exists in the superclass, a proxy is generated for the
921-
* first method with matching signatures.
922-
*/
923-
def genReflCallProxies(sym: Symbol): List[js.MethodDef] = {
924-
import scala.reflect.internal.Flags
925-
926-
// Flags of members we do not want to consider for reflective call proxys
927-
val excludedFlags = (
928-
Flags.BRIDGE |
929-
Flags.PRIVATE |
930-
Flags.MACRO
931-
)
932-
933-
/** Check if two method symbols conform in name and parameter types */
934-
def weakMatch(s1: Symbol)(s2: Symbol) = {
935-
val p1 = s1.tpe.params
936-
val p2 = s2.tpe.params
937-
s1 == s2 || // Shortcut
938-
s1.name == s2.name &&
939-
p1.size == p2.size &&
940-
(p1 zip p2).forall { case (s1,s2) =>
941-
s1.tpe =:= s2.tpe
942-
}
943-
}
944-
945-
/** Check if the symbol's owner's superclass has a matching member (and
946-
* therefore an existing proxy).
947-
*/
948-
def superHasProxy(s: Symbol) = {
949-
val alts = sym.superClass.tpe.findMember(
950-
name = s.name,
951-
excludedFlags = excludedFlags,
952-
requiredFlags = Flags.METHOD,
953-
stableOnly = false).alternatives
954-
alts.exists(weakMatch(s) _)
955-
}
956-
957-
// Query candidate methods
958-
val methods = sym.tpe.findMembers(
959-
excludedFlags = excludedFlags,
960-
requiredFlags = Flags.METHOD)
961-
962-
val candidates = methods filterNot { s =>
963-
s.isConstructor ||
964-
superHasProxy(s) ||
965-
jsInterop.isExport(s)
966-
}
967-
968-
val proxies = candidates filter {
969-
c => candidates.find(weakMatch(c) _).get == c
970-
}
971-
972-
proxies.map(genReflCallProxy _).toList
973-
}
974-
975-
/** actually generates reflective call proxy for the given method symbol */
976-
private def genReflCallProxy(sym: Symbol): js.MethodDef = {
977-
implicit val pos = sym.pos
978-
979-
val proxyIdent = encodeMethodSym(sym, reflProxy = true)
980-
981-
withNewLocalNameScope {
982-
val jsParams = for (param <- sym.tpe.params) yield {
983-
implicit val pos = param.pos
984-
js.ParamDef(encodeLocalSym(param), toIRType(param.tpe),
985-
mutable = false, rest = false)
986-
}
987-
988-
val call = genApplyMethod(genThis(), sym, jsParams.map(_.ref))
989-
val resTpeEnteringPosterasure = enteringPhase(currentRun.posterasurePhase) {
990-
sym.tpe match {
991-
case _: ExistentialType =>
992-
/* We should not see an ExistentialType here. This is a
993-
* scalac 2.10 bug. We assume no boxing is required. See #1581.
994-
*/
995-
ObjectTpe
996-
case symTpe =>
997-
symTpe.resultType
998-
}
999-
}
1000-
val body = ensureBoxed(call, resTpeEnteringPosterasure)
1001-
1002-
js.MethodDef(static = false, proxyIdent, jsParams, jstpe.AnyType,
1003-
body)(OptimizerHints.empty, None)
1004-
}
1005-
}
1006-
1007888
/** Generates the MethodDef of a (non-constructor) method
1008889
*
1009890
* Most normal methods are emitted straightforwardly. If the result

ir/src/main/scala/org/scalajs/core/ir/InfoSerializers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ object InfoSerializers {
130130
}
131131

132132
val methods0 = readList(readMethod())
133-
val methods = if (true) { // useHacks065
133+
val methods = if (useHacks065) {
134134
methods0.filter(m => !Definitions.isReflProxyName(m.encodedName))
135135
} else {
136136
methods0

ir/src/main/scala/org/scalajs/core/ir/Serializers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ object Serializers {
713713
val parents = readIdents()
714714
val jsName = Some(readString()).filter(_ != "")
715715
val defs0 = readTrees()
716-
val defs = if (true) { // useHacks065
716+
val defs = if (useHacks065) {
717717
defs0.filter {
718718
case MethodDef(_, Ident(name, _), _, _, _) =>
719719
!Definitions.isReflProxyName(name)

0 commit comments

Comments
 (0)