recipes for asType and explicitCastArguments
forax at univ-mlv.fr
Wed Aug 17 14:12:18 PDT 2011
On 08/17/2011 09:47 PM, John Rose wrote:
> ## Using an interface as a marker for "dynamically typed reference"
> 1. Take one fresh interface D. Remove all methods.
> 2. Sprinkle D freely in invokedynamic signatures, wherever a static type "dynamic" is desired.
> 3. When binding a MH to such an interface, retype MH in two steps, an asType and an eCA.
> 3a. The asType retypes to the invokedynamic type, but with D replaced by Object.
> 3b. The eCA retypes Object references (with no runtime test) to D, as needed.
> 4. Mix and serve.
This one is really nice.
> ## Avoiding primitive conversions (a household hint)
> 1. Take a program which unboxes from references and primitives
> 1a. Observe that both asType and eCA potentially perform primitive conversions
> 1b. Observe that these primitive conversions are driven by the runtime type of the box
> 2. Decide whether your application doesn't need primitive conversions, just pure single-type unboxing.
> 2a. If it needs primitive conversions along with unboxing, find a different recipe.
> 3. Retype a MH which has primitives and requires unboxing in two steps.
> 3a. First, retype primitive to exact wrapper types (like Integer), to nail down the runtime type of each box.
> 3b. Then widen the exact wrapper types to the required type (e.g., Object, Number, or some interface).
This one is also explained in my presentation at last JVM Summit.
> ## Make a statically typed method handle have a dynamically typed signature (ready in 1 minute)
> 1. Take an arbitrary method handle mh.
> 2. Incant: mh = mh.asType(mh.type().generic())
> 3. (optional) Truss the arguments so they will invoke evenly: mh = mh.asSpreader(Object.class, mh.type().parameterCount())
We have invokeWithArguments,
perhaps this recipe is only for plumbers like you.
> ## Mix your conversions days ahead of the party
> 1. Decide ahead of time on a target MH type T1 and a desired type T0.
> 2. Insert a new leading parameter of MethodHandle.class, into both types. (Call them T0' and T1'.)
> 3. Obtain a plain invoker from MHs.exactInvoker.
> 3a. You can use the inexact kind too, for those extra degrees of freedom at invocation time.
> 4. Perform retyping on the invoker, as needed, from T1' back to T0'. Be creative!
> 4a. Leave the leading MH argument unchanged.
> 4b. Name your invoker I'. Store and chill.
> 5. When it's time to invoke an actual MH (of exact type T1 but using type T0), use an invokeExact of I' instead of the MH itself.
> 5a. If you are binding the MH to an invokedynamic site (of type T0), simply use I'.bindTo(mh)
> 5b. If the eventual MH is not exactly compatible with T1, use the inexact form of invoker to build I'.
> 6. Invoke as needed. Serves any number.
> 7. Note that this recipe can be used to pre-combine any transformations, not just asType and explicitCastArguments.
I'm looking for a use case for this one.
Perhaps if a language (even statically typed) use a dedicated list/array
like data structure
for doing varargs in a lambda and you want to simplify your call site.
More information about the mlvm-dev