I have been working with method lookup and caching using gwt which seems 
to work well.
However to get it to work I had to set up the casting in a way which was 
not obvious to me.

In my Smalltalk implementation all ST objects are instances of a single 
java class ( RtObject )
so I was thinking that all of my method handles would use that as a type. 
But what worked was:
( full code at bottom )
First I collect all of the ST args into an array

My collector  ( mh2 type is (RtObject.class, RtObject.class, 
RtObject.class )
   MethodHandle mh3=mh2.asCollector(RtObject[].class, site.getAirity());

At this point I enter the fallback
The type of my fallback method ( I expected the last type to be RtObject[] 
).
    MethodType mt=MethodType.methodType(RtObject.class, RtCallSite.class, 
Object[].class);

The spreader ( I expected the first type to be RtObject[] )
   MethodHandle invoke=newTarget.asSpreader(Object[].class, 
site.getAirity());

The invoke  ( again not sure why I needed the cast here )
    result=(RtObject)invoke.invokeExact((Object[])args);

The problem area seems to be going from the collector to the fallback 
call.  If I make the
fallback RtObject then I start getting type error.  The latest doc implies 
that the type of 
this array 'usually' is the same type as the args collected.
Is collector doing the cast to Object[]?


Thanks 
mark




  // handle the self bootstrap and lookup
  public static RtCallSite bootStrapSelf(MethodHandles.Lookup 
callerLookup, String name, MethodType type, Object arg) {
    // return a call site for a method on self called first time
    System.out.println("bootstrap " + name);
    RtObject sel=new RtObject(name);
    RtCallSite site=new RtCallSite(type, sel.asSymbol());
    site.setAirity(type.parameterCount());
    // need to set the target to the initial fallback
    // needs to do a combine args based on airity, insert site and then 
the lookup
    MethodHandles.Lookup lookup=MethodHandles.lookup();
    MethodType mt=MethodType.methodType(RtObject.class, RtCallSite.class, 
Object[].class);
    MethodHandle mh=null;
    try {
      mh=lookup.findStatic(RtCallSite.class, "fallbackSelf", mt);
    }
    catch (Exception e1) {
      e1.printStackTrace();
    }
    // insert the call site
    MethodHandle mh2=MethodHandles.insertArguments(mh, 0, site);
    // combine the args into an array
    MethodHandle mh3=mh2.asCollector(RtObject[].class, site.getAirity());
    site.setTarget(mh3);
    return site;
  }

  public static RtObject fallbackSelf(RtCallSite site, Object[] args) {
    // set a new guard with test path based on test failing/;
    System.out.println("fallback");
    System.out.println(site.getSelector());
    int last=args.length;
    RtObject rcvr=(RtObject)args[last - 1];
    MethodHandles.Lookup lookup=MethodHandles.lookup();
    // create the gwt
    MethodType mt=MethodType.methodType(boolean.class, RtObject.class, 
RtObject.class);
    MethodHandle test=null;
    try {
      test=lookup.findStatic(RtCallSite.class, "test", mt);
    }
    catch (Exception e1) {
      e1.printStackTrace();
    }
    // need to insert the test at the beginning
    test=MethodHandles.insertArguments(test, 0, rcvr.classField());
    // now drop the excess args ( leaving first and last)
    test=MethodHandles.dropArguments(test, 1, site.dropArray());
    // now I need to lookup the smalltalk method
    RtObject method=rcvr.lookupSelf(site.getSelector());
    MethodHandle newTarget=primGetMethodHandle(method);
    MethodHandle gwt=MethodHandles.guardWithTest(test, newTarget, 
site.getTarget());
    site.setTarget(gwt);
    // now I have to invoke it
    MethodHandle invoke=newTarget.asSpreader(Object[].class, 
site.getAirity());
    RtObject result=null;
    try {
      result=(RtObject)invoke.invokeExact((Object[])args);
    }
    catch (Throwable e) {
      e.printStackTrace();
    }
    return result;
  }
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to