-
Notifications
You must be signed in to change notification settings - Fork 3
Fix reflective proxy for Hijacked classes #108
Conversation
// } | ||
if (methods.exists( m => | ||
m.name.simpleName == methodName.nameString && | ||
!m.isAbstract |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ouch, good catch!
cc381eb
to
6747768
Compare
// The synthetic `This` may contains boxed primitive, instead of primitive types. | ||
// However, the checker should ensure that the `This` is never boxed in Scala.js linker frontend. | ||
// As a workaround, we unbox the `This` here. | ||
val fixedTpe = t.tpe match { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any better explanation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps as follows:
Workaround wrong
t.tpe
forThis
nodes inside reflective proxies.
In a hijacked class,This
nodes are supposed to be typed as the corresponding primitive type.
However, the Scala.js linker frontend synthesizes reflective proxies that containThis
nodes typed as the hijacked class'ClassType
instead.
This is bad for us because it meansgenAdapt
fails to box the primitives when required.
We work around this issue here by re-computing the correct type ofThis
nodes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. The commits should probably be squashed at this point.
This commit fix 2 things (1) Reflective proxy for methods in `j.l.Object` should call the methods in `j.l.Object` Resolves: #97 Related: #98 When a reflective call is made on the `clone` method, reflective proxies are generated for the `clone` method on the Hijacked classes, including `java.lang.Void` and `java.lang.Boolean`. The issue arises because the generated reflective proxy contains a function call to a non-existent function, such as `$f#java.lang.Void#clone_Ljava.lang.Object` in this example. ``` (func $f#java.lang.Void#clone_R (type $f.21) (param $___<this> (ref any)) (result anyref) local.get $___<this> call $f#java.lang.Void#clone_Ljava.lang.Object) ``` For Hijacked classes, `genApply` is transformed into `genApplyStatically`, which looks up the method in the Hijacked class and calls it directly, instead of using table dispatching. However, `resolvePublicMethod` incorrectly resolves the "clone" method from the Hijacked classes, such as `java.lang.Boolean`, even though the method doesn't exist in the Hijacked class itself (it is inherited from java.lang.Object). In this context, `resolvePublicMethod` should not resolve methods that are not defined in the specific Hijacked class. --- (2) Workaround wrong t.tpe for `This` nodes inside reflective proxies. In a hijacked class, This nodes are supposed to be typed as the corresponding primitive type. However, the Scala.js linker frontend synthesizes reflective proxies that contain This nodes typed as the hijacked class' ClassType instead. This is bad for us because it means genAdapt fails to box the primitives when required. We work around this issue here by re-computing the correct type of This nodes. #100 Synthetic `This` should have a primitive type instead of BoxedType Fix #100
6747768
to
8d8a6c7
Compare
Thanks, edited the comment, and squashed 👍 |
This commit fix 2 things
(1) Reflective proxy for methods in
j.l.Object
should call the methods inj.l.Object
Resolves: #97
Related: #98
When a reflective call is made on the
clone
method, reflective proxies are generatedfor the
clone
method on the Hijacked classes, includingjava.lang.Void
andjava.lang.Boolean
.The issue arises because the generated reflective proxy contains a function call
to a non-existent function, such as
$f#java.lang.Void#clone_Ljava.lang.Object
in this example.For Hijacked classes,
genApply
is transformed intogenApplyStatically
, which looks upthe method in the Hijacked class and calls it directly, instead of using table dispatching.
However,
resolvePublicMethod
incorrectly resolves the "clone" method from the Hijacked classes,such as
java.lang.Boolean
, even though the method doesn't exist in the Hijacked class itself(it is inherited from java.lang.Object).
In this context,
resolvePublicMethod
should not resolve methods that are not defined in thespecific Hijacked class.
(2) Workaround wrong t.tpe for
This
nodes inside reflective proxies.In a hijacked class, This nodes are supposed to be typed as the corresponding primitive type.
However, the Scala.js linker frontend synthesizes reflective proxies that contain This nodes typed as the hijacked class' ClassType instead.
This is bad for us because it means genAdapt fails to box the primitives when required.
We work around this issue here by re-computing the correct type of This nodes.
#100
Synthetic
This
should have a primitive type instead of BoxedTypeFix #100