recipes for asType and explicitCastArguments

John Rose john.r.rose at oracle.com
Wed Aug 17 12:47:25 PDT 2011


## 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.

## 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).

## 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())

## 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.



More information about the mlvm-dev mailing list