Few questions about invokeDynamic

Rémi Forax forax at univ-mlv.fr
Tue Nov 9 07:25:21 PST 2010


Le 09/11/2010 14:57, Christian Thalinger a écrit :
> On Nov 9, 2010, at 11:43 AM, Rémi Forax wrote:
>    
>>   So a workaround for that bug is to declare the return type of
>> invokedynamic
>> to be not void but by example int.
>>      
>
> The fix is trivial but I'd like to implemented to other missing pieces
> too, like int-to-float conversion and friends.
>
> Remi, could you tell me how I can produce AMHs that do such
> conversions (on the return type)?
>    

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.

---------------------------------------------------------------------------------------------------
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;
   }
}


> -- Christian
> _______________________________________________
> 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