No segment method for MemoryAddress?
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue Aug 25 23:45:01 UTC 2020
On 25/08/2020 22:22, Ty Young wrote:
>
> On 8/25/20 3:40 PM, Maurizio Cimadamore wrote:
>>
>>>
>>> The libraries that I use(NVML, NVCtrl) rarely return pointers and
>>> even when they do they are immediately made safe by my abstraction
>>> layer:
>>>
>>>
>>> public static NativeArray<Byte> nvmlErrorString(nvmlReturn_t value)
>>> throws Throwable
>>> {
>>> return
>>> NativeArray.ofUnsafeSequenceLayout((MemoryAddress)ERROR_STRING.getMethodHandle().invoke(value.getNativeValue()),
>>> ERROR_LAYOUT);
>>> }
>>>
>>>
>>> So basically it's impossible for a MemoryAddress to not have
>>> segment. Of course functions are an exception.
>>
>> Ok - that's what I was hinting at.
>>
>> But if that's the case - you can simply replace MemoryAddress with
>> MemorySegment inside NativeObject and that should work as before?
>
>
> Except that doesn't work because NativeFunction(extends NativeObject)
> doesn't have a segment, only a MemoryAddress and creating different
> code paths is extremely ugly. Creating a method like:
>
>
> public interface NativeObject<A extends Addressable>
>
> {
>
> public A getAddressable();
>
> }
I have to admit, I don't understand why you even bother with generics.
Why should the user of this API (which you say it's meant to be
high-level) should care whether a NativeObject is backed by a segment or
an address? After all the API allows you to do dereference w/o ever
touching a segment, and calling functions w/o method handles. So, in a
way, these are all implementation details - and it seems odd to try so
hard to have the API reflecting such implementation details.
In other words, I'm assuming that, as a user of your API, I really never
need to peek at the lower level and deal with MemoryAddress and
MemorySegment directly, right? If that's the case, then I'd suggest that
dropping the generic type argument is ok, and perhaps even dropping the
"getAddressable" is ok; if you want to keep that for interop with other
libraries using memory segments (but here I have to admit I'm starting
to lose sight of the goal you are trying to achieve), then perhaps just
exposing something which returns an Addressable (and leave the user to
cast it) is ok.
Or, you can always use covariant overriding:
interface NativeObject {
public Addressable addressable();
}
interface NativeStruct extends NativeObject {
public MemorySegment addressable();
}
interface NativeFunction extends NativeObject {
public MemoryAddress addressable();
}
No type-variables here, and yet the types are sharp. Perhaps something
like this might work. I don't think you really need to expose sharp
distinction such as that between mapped segments and native segments,
but if you do then I have to admit I don't understand how the API is
supposed to be used.
Maurizio
More information about the panama-dev
mailing list