-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for @PolymorphicSignature, required for using MethodHandles from Scala #7965
Comments
Imported From: https://issues.scala-lang.org/browse/SI-7965?orig=1 |
@DarkDimius said: {quote}As is usual with virtual methods, source-level calls to invokeExact and invoke compile to an invokevirtual instruction. More unusually, the compiler must record the actual argument types, and may not perform method invocation conversions on the arguments. Instead, it must push them on the stack according to their own unconverted types. The method handle object itself is pushed on the stack before the arguments. The compiler then calls the method handle with a symbolic type descriptor which describes the argument and return types. To issue a complete symbolic type descriptor, the compiler must also determine the return type. This is based on a cast on the method invocation expression, if there is one, or else Object if the invocation is an expression or else void if the invocation is a statement. The cast may be to a primitive type (but not void). As a corner case, an uncasted null argument is given a symbolic type descriptor of java.lang.Void. The ambiguity with the type Void is harmless, since there are no references of type Void except the null reference. |
@DarkDimius said: |
@retronym said: scala> :paste -raw
// Entering paste mode (ctrl-D to finish)
package pack { object O { private def foo = "foo"; val lookup = java.lang.invoke.MethodHandles.lookup } }
// Exiting paste mode, now interpreting.
scala> val mt = java.lang.invoke.MethodType.methodType(classOf[String], Array[Class[_]]())
mt: java.lang.invoke.MethodType = ()String
scala> val mh = pack.O.lookup.findVirtual(pack.O.getClass, "foo", mt)
mh: java.lang.invoke.MethodHandle = MethodHandle(O$)String
scala> mh.invokeExact(pack.O) // won't work as Scala doesn't respect the @PolymorphicSignature of invokeExact
java.lang.invoke.WrongMethodTypeException: expected (O$)String but found (Object[])Object
at java.lang.invoke.Invokers.newWrongMethodTypeException(Invokers.java:340)
at java.lang.invoke.Invokers.checkExactType(Invokers.java:351)
... 33 elided
scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
** :phase has been set to 'typer'. **
** scala.tools.nsc._ has been imported **
** global._, definitions._ also imported **
** Try :help, :vals, power.<tab> **
scala> val invokeExact = typeOf[java.lang.invoke.MethodHandle].member(TermName("invokeExact"))
invokeExact: $r.intp.global.Symbol = method invokeExact
scala> val origInfo = invokeExact.info
origInfo: $r.intp.global.Type = (x$1: Object*)Object
scala> val newInfo = JavaMethodType(invokeExact.newValueParameter(TermName("x")).setInfo(typeOf[pack.O.type]) :: Nil, StringTpe)
newInfo: $r.intp.global.JavaMethodType = (x: pack.O.type)String
scala> invokeExact.setInfo(newInfo)
res1: invokeExact.type = method invokeExact
scala> mh.invokeExact(pack.O) // Let's try again!
res2: String = foo I was messing around with |
@retronym said: |
@adriaanm said: |
Java 7 has added MethodHandle's which can take any arguments types and their result can be cast to any return type.
The signature polymorphism was introduced that "connects this freedom of invocation directly to the JVM execution stack"
Currently the code
compiles to
has the wrong call in the end, as compiler shouldn't have boxed "bla" to array
The equivalent to java code
compiles to this
You can see that "bla" in the last call was just forwarded to invoke, without being boxed, and the return value is being treated AS an int, not being casted to it.
Such behaviour should be used when method is marked with @PolymorphicSignature annotation.
The text was updated successfully, but these errors were encountered: