-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support signature polymorphic methods (
MethodHandle
and VarHandle
) (
- Loading branch information
Showing
14 changed files
with
193 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// scalajs: --skip | ||
import scala.language.unsafeNulls | ||
|
||
import java.lang.invoke._, MethodType.methodType | ||
|
||
// A copy of tests/run/i11332.scala | ||
// to test the bootstrap minimisation which failed | ||
// (because bootstrap runs under explicit nulls) | ||
class Foo: | ||
def neg(x: Int): Int = -x | ||
|
||
object Test: | ||
def main(args: Array[String]): Unit = | ||
val l = MethodHandles.lookup() | ||
val self = new Foo() | ||
|
||
val res4 = { | ||
l // explicit chain method call - previously derivedSelect broke the type | ||
.findVirtual(classOf[Foo], "neg", methodType(classOf[Int], classOf[Int])) | ||
.invokeExact(self, 4): Int | ||
} | ||
assert(-4 == res4) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// scalajs: --skip | ||
import scala.language.unsafeNulls | ||
|
||
import java.lang.invoke._, MethodType.methodType | ||
|
||
class Foo: | ||
def neg(x: Int): Int = -x | ||
def rev(s: String): String = s.reverse | ||
def over(l: Long): String = "long" | ||
def over(i: Int): String = "int" | ||
def unit(s: String): Unit = () | ||
def obj(s: String): Object = s | ||
|
||
object Test: | ||
def main(args: Array[String]): Unit = | ||
val l = MethodHandles.lookup() | ||
val self = new Foo() | ||
val mhNeg = l.findVirtual(classOf[Foo], "neg", methodType(classOf[Int], classOf[Int])) | ||
val mhRev = l.findVirtual(classOf[Foo], "rev", methodType(classOf[String], classOf[String])) | ||
val mhOverL = l.findVirtual(classOf[Foo], "over", methodType(classOf[String], classOf[Long])) | ||
val mhOverI = l.findVirtual(classOf[Foo], "over", methodType(classOf[String], classOf[Int])) | ||
val mhUnit = l.findVirtual(classOf[Foo], "unit", methodType(classOf[Unit], classOf[String])) | ||
val mhObj = l.findVirtual(classOf[Foo], "obj", methodType(classOf[Any], classOf[String])) | ||
val mhCL = l.findStatic(classOf[ClassLoader], "getPlatformClassLoader", methodType(classOf[ClassLoader])) | ||
|
||
assert(-42 == (mhNeg.invokeExact(self, 42): Int)) | ||
assert(-33 == (mhNeg.invokeExact(self, 33): Int)) | ||
|
||
assert("oof" == (mhRev.invokeExact(self, "foo"): String)) | ||
assert("rab" == (mhRev.invokeExact(self, "bar"): String)) | ||
|
||
assert("long" == (mhOverL.invokeExact(self, 1L): String)) | ||
assert("int" == (mhOverI.invokeExact(self, 1): String)) | ||
|
||
assert(-3 == (id(mhNeg.invokeExact(self, 3)): Int)) | ||
expectWrongMethod(mhNeg.invokeExact(self, 4)) | ||
|
||
{ mhUnit.invokeExact(self, "hi"): Unit; () } // explicit block | ||
val hi2: Unit = mhUnit.invokeExact(self, "hi2") | ||
assert((()) == hi2) | ||
def hi3: Unit = mhUnit.invokeExact(self, "hi3") | ||
assert((()) == hi3) | ||
|
||
{ mhObj.invokeExact(self, "any"); () } // explicit block | ||
val any2 = mhObj.invokeExact(self, "any2") | ||
assert("any2" == any2) | ||
def any3 = mhObj.invokeExact(self, "any3") | ||
assert("any3" == any3) | ||
|
||
assert(null != (mhCL.invoke(): ClassLoader)) | ||
assert(null != (mhCL.invoke().asInstanceOf[ClassLoader]: ClassLoader)) | ||
assert(null != (mhCL.invokeExact(): ClassLoader)) | ||
assert(null != (mhCL.invokeExact().asInstanceOf[ClassLoader]: ClassLoader)) | ||
|
||
expectWrongMethod { | ||
l // explicit chain method call | ||
.findVirtual(classOf[Foo], "neg", methodType(classOf[Int], classOf[Int])) | ||
.invokeExact(self, 3) | ||
} | ||
val res4 = { | ||
l // explicit chain method call | ||
.findVirtual(classOf[Foo], "neg", methodType(classOf[Int], classOf[Int])) | ||
.invokeExact(self, 4): Int | ||
} | ||
assert(-4 == res4) | ||
|
||
def id[T](x: T): T = x | ||
|
||
def expectWrongMethod(op: => Any) = try { | ||
op | ||
throw new AssertionError("expected operation to fail but it didn't") | ||
} catch case expected: WrongMethodTypeException => () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// test: -jvm 11+ | ||
// scalajs: --skip | ||
import java.lang.invoke._ | ||
import scala.runtime.IntRef | ||
|
||
object Test { | ||
def main(args: Array[String]): Unit = { | ||
val ref = new scala.runtime.IntRef(0) | ||
val varHandle = MethodHandles.lookup() | ||
.in(classOf[IntRef]) | ||
.findVarHandle(classOf[IntRef], "elem", classOf[Int]) | ||
assert(0 == (varHandle.getAndSet(ref, 1): Int)) | ||
assert(1 == (varHandle.getAndSet(ref, 2): Int)) | ||
assert(2 == ref.elem) | ||
|
||
assert((()) == (varHandle.set(ref, 3): Any)) | ||
assert(3 == (varHandle.get(ref): Int)) | ||
|
||
assert(true == (varHandle.compareAndSet(ref, 3, 4): Any)) | ||
assert(4 == (varHandle.get(ref): Int)) | ||
} | ||
} |