Few questions about invokeDynamic
Rémi Forax
forax at univ-mlv.fr
Mon Jan 10 05:32:45 PST 2011
On 01/10/2011 02:02 PM, Christian Thalinger wrote:
> On Nov 9, 2010, at 4:25 PM, Rémi Forax wrote:
>> Here is an example.
>> If indy has no parameter, it tests void -> indy return type
>> If indy has one parameter, it test parameter type -> return type
>> If indy name is "spread", a spread/collect is done.
>>
>> Rémi
>>
>> PS: With the new API, all identity methods but the one that take no
>> parameter
>> can be removed and replace by Methodhandles.identity() in the BSM.
> I just got back to this bug and now that InvokeDynamic is gone how can I rewrite that code to work again (without John's Indify magic)?
>
> -- Christian
>
Good question.
First, I don't know if this bug is specific to invokedynamic or if the
conversion code is shared
between MetodHandle and invokedynamic. If the code is shared, you can
rewrite it using MethodHandle
because invokedynamic can be rewritten to
bootstrap().getTarget().invokeExact(...)
The other solution is to use this small class:
http://weblogs.java.net/blog/forax/archive/2011/01/07/call-invokedynamic-java
Basically, the code generates at runtime a method containing an
invokedynamic and returns a MethodHandle
created on the method. The main problem is that this code depends on
ASM. Not sure you want such dependency
in your test suite.
The last solution is to send enough mails to Brian asking him (he
currently own the Java language token)
to re-introduce a Java syntax for invokedynamic.
Rémi
>> ---------------------------------------------------------------------------------------------------
>> public class ConvertTest {
>> private static boolean identity(boolean v) {
>> return v;
>> }
>> private static byte identity(byte v) {
>> return v;
>> }
>> private static char identity(char v) {
>> return v;
>> }
>> private static short identity(short v) {
>> return v;
>> }
>> private static int identity(int v) {
>> return v;
>> }
>> private static long identity(long v) {
>> return v;
>> }
>> private static float identity(float v) {
>> return v;
>> }
>> private static double identity(double v) {
>> return v;
>> }
>>
>> private static void identity() { }
>>
>> private static void assertEquals(Object o, Object o2) {
>> if (!o.equals(o2))
>> throw new AssertionError("expected "+ o +" found "+o2);
>> }
>>
>> public static void main(String[] args) throws Throwable {
>> for(int i=0; i< 1000000; i++) {
>> boolean dummyZ; byte dummyB; short dummyS; char dummyC; int
>> dummyI; long dummyL; float dummyF; double dummyD;
>>
>>
>> //dummyZ = (boolean)InvokeDynamic.foo(); // void -> boolean
>> //dummyI = (int)InvokeDynamic.foo(); // void -> int
>>
>> //InvokeDynamic.foo(4); // int -> void
>> InvokeDynamic.spread(4); // spread: int -> void
>>
>> //dummyF = (float)InvokeDynamic.foo(4); // int -> float
>> //dummyD = (double)InvokeDynamic.foo(4); // int -> double
>>
>> //assertEquals(4.0f, (float)InvokeDynamic.foo(4)); // int -> float
>> }
>> }
>>
>> static {
>> Linkage.registerBootstrapMethod("bootstrap");
>> }
>>
>> private static CallSite bootstrap(Class<?> declaring, String name,
>> MethodType methodType) throws Throwable {
>> Lookup lookup = MethodHandles.lookup();
>>
>> MethodHandle mh;
>> if (methodType.parameterCount() == 0) {
>> mh = lookup.findStatic(ConvertTest.class, "identity",
>> MethodType.methodType(void.class));
>> } else {
>> Class<?> type = methodType.parameterType(0);
>> mh = lookup.findStatic(ConvertTest.class, "identity",
>> MethodType.methodType(type, type));
>>
>> if ("spread".equals(name)) {
>> mh = MethodHandles.spreadArguments(mh,
>> methodType.changeParameterType(0, Object[].class));
>> mh = MethodHandles.collectArguments(mh, methodType);
>> }
>> }
>>
>> mh = mh.asType(methodType);
>>
>> CallSite cs = new CallSite();
>> cs.setTarget(mh);
>> return cs;
>> }
>> }
>
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
More information about the mlvm-dev
mailing list