No segment method for MemoryAddress?

Ty Young youngty1997 at gmail.com
Tue Aug 25 18:05:13 UTC 2020


On 8/25/20 5:46 AM, Maurizio Cimadamore wrote:
>
> On 25/08/2020 10:14, Ty Young wrote:
>>
>> On 8/24/20 3:12 AM, Maurizio Cimadamore wrote:
>>>
>>> On 22/08/2020 03:45, Ty Young wrote:
>>>> Doing that increases the amount of generic type declarations for 
>>>> static methods which are already decently sized:
>>>>
>>>>
>>>> public static <T, E extends NativeValue<T>> E 
>>>> ofUnsafeValueLayout(MemoryAddress address, ValueLayout layout) 
>>>
>>> Without knowing exactly what your code is doing - this seems similar 
>>> to what we do in jextract to expose global variables (e.g. create 
>>> unsafe segments based at a certain address, with given size).
>>
>>
>> It's dual purpose - it can be used to create a usable object directly 
>> from native or interpret that MemoryAddress as the desired 
>> NativeValue given the layout.. but that's irrelevant.
>>
>>
>> How are you supposed to create/use method handles with this new 
>> setup? Do native bindings now return MemorySegment instead of 
>> MemoryAddress? Or does it not matter because of Addressable?
>
> Method handles works as before. If you want to pass structs by value, 
> you need MemorySegment, if you pass pointer you need MemoryAddress. 
> The only thing affected by this is memory deference with var handle.


That's interesting, I've been using MemoryAddress for structs this whole 
time without issues. What about arrays?


*snip*

>>
>>
>> 1. for creating a new NativeObject using a layout(often no-args 
>> default constructor)
>>
>>
>> 2. for interpreting an existing MemorySegment as another existing 
>> NativeObject
>>
>>
>> 3. for MemoryAddress pointers returned from C
>>
>>
>> I guess the roles are more distinguished this way(no dual purpose as 
>> mentioned above), but adding more static methods/constructors isn't 
>> desirable especially when the code path is basically the same anyway.
>
> What is NativeObject? Is it an abstraction to model structs? Again, I 
> can't comment on an API I only vaguely remember.


NativeObject is basically just a marker interface used for generic 
return types, at least now. I used to have segment methods in it so I 
didn't have to do <NativeObject>.getAddress().segment().asSlice() 
everytime, but the segment part had to be removed because of the 
Addressable change which broke my project.


>
> But it appears to me that these cases are all very different; if you 
> create something from scratch you know exactly spatial and temporal 
> bounds. If a C slips you a pointer, you know nothing and you have to 
> make up spatial and temporal bounds (with an unsafe segment, likely). 
> So it makes sense to me to have at least two overloads there.
>
> As for the reinterpreting, that's basically a view over an existing 
> segment, so that's a different one, yes.
>
> I'm not sure what the problem is here - that you need an extra 
> overload for MemoryAddress while before you just took a segment and 
> you just called address.segment() ? Do you realize that 
> address.segment() would have returned NULL in many cases?


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.


>
> Maurizio
>
>
>>
>>
>>>
>>> Maurizio
>>>


More information about the panama-dev mailing list