On Mar 20, 2020, at 10:49 AM, Jorn Vernee <jorn.ver...@oracle.com> wrote:
> 
> W.r.t. the source type being needed, I see the following 4 major cases:
> 
> 1. src=Prim & dst=Prim -> cast convert. For boolean the least-significant-bit 
> is used to convert it to/from an integer type.
> 2. src=Prim & dst=Ref   -> box the source value and potentially cast
> 3. src=Ref   & dst=Prim -> apply an unboxing conversion if possible and then 
> a casting conversion (with same trick for boolean as (1))
> 4. src=Ref   & dst=Ref   -> reference cast
> 
> Without the source type we can't disambiguate between cases (2) and (4), or 
> (1) and (3) because the bootstrap takes Object as an input.

I think that if you box the src=Prim from 1 or 2 and then
hand the resulting src=Ref to 3 or 4 you will get the same
thing.  The basic design here is that dst=Prim is the key
signal that unlocks the primitive conversions.  The type
of the src (Ref or Prim) doesn’t change the access to the
primitive conversions.

> For (2) and (4) the bootstrap invocation mechanism takes care of the boxing 
> for us, and the cast is performed by (4). For (1) and (3) the conversion code 
> for the latter handles conversion of wrapper types to Number and then to the 
> target primitive per (1). In the end things seems to work out to the same 
> result (though maybe I'm missing some subtle difference in a failure case).

Indeed they do.  That’s how I designed it.  The upshot is that
Object is a reliable carrier even of primitive values, for these
APIs.

> What I'm mostly worried about is that the source type already affects _how_ 
> the conversion is done, and the fact that this difference is not observable 
> seems somewhat incidental.... Coupled with the fact that asType and 
> explicitCastArguments also have access to both the source and destination 
> type, I think maybe the new bootstrap method should as well. After all, what 
> if the set of cases is extended (valhalla?) and/or not being able to 
> disambiguate starts to matter?

You shouldn’t be appealing to an internal function here for
designing the semantics.  The dual arguments to the internal
function are excess information; the shape of that function
predates the design decision described above.

Instead, appeal to some pseudocode, such as:

var id = identity(Object.class);
var mt = methodType(dst, Object.class);
var conv = explicitCastArguments(id, mt);
return conv.invoke(x);

I think that will give us all conversions we will need.

> 
> ---
> 
> I've written a more in-depth specification for the bootstrap, and 
> re-implemented it using explicitCastArguments, since that helps to catch 
> discrepancies between the input value and the source type. Here is the next 
> iteration: http://cr.openjdk.java.net/~jvernee/8241100/webrev.01
> 
> I've kept the source type for now, if it should be removed the specification 
> can be trimmed down (since there would be less cases to specify).
> 
> As for the name; I think "asType" might be confusing since the applied 
> conversion is not quite the same as MethodHandle::asType. Since the bootstrap 
> is implemented in terms of explicitCastArguments I went with "explicitCast", 
> how is that?

Yes, I like that name.

— John

Reply via email to