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