[foreign-abi] RFR: 8241148: need a way to create MemorySegment with contents from java String and a way to read a C char* as java String

Ty Young youngty1997 at gmail.com
Thu Mar 19 10:37:20 UTC 2020


On 3/18/20 11:58 AM, Athijegannathan Sundararajan wrote:
> Adding utility methods to ForeignUnsafe class.


A few suggestions on this, if you don't mind.


ForeignUnsafe is apart of the native system call part of Panama and 
therefore will not be apart of the general foreign memory access API 
that will be released first. It is, however, possible to read and write 
strings from/to memory without that additional native access layer.


So, maybe instead of adding these static methods to ForeignUnsafe, they 
should instead be added to MemoryAddress(Or MemorySegment)? Of course, 
this means that any MemoryAddress(or MemorySegment) returned by a native 
function will have to go through ForeignUnsafe, but, forcing the user to 
explicitly deal with that themselves is probably desirable, right?


Doing this also simplifies and fixes the code of toJavaString(). Right 
now it's implemented like so:


public static String toJavaString(MemoryAddress addr) {
         StringBuilder buf = new StringBuilder();

         try (MemorySegment seg = ofNativeUnchecked(addr, Long.MAX_VALUE)) {
             MemoryAddress baseAddr = seg.baseAddress();
             byte curr = (byte) byteArrHandle.get(baseAddr, 0);
             long offset = 0;
             while (curr != 0) {
                 buf.append((char) curr);
                 curr = (byte) byteArrHandle.get(baseAddr, ++offset);
             }
         }
         return buf.toString();
     }


Which has two (really minor) issues in that it applies a Long.MAX_VALUE 
on a native, unsafe MemoryAddress(Yes, it'll work fine, but still, the 
API user would know the actual size and probably have applied it already 
before this, making it a waste), and that it's a bit messy.


However, if it were move to MemoryAddress and it's assumed the address 
is safe, the method could just basically be a copy/paste of the old 
Pointer.toString from old Panama[1], with a variant that accepts a Charset.


FWIW, I'm doing this now for my abstraction layer's MemoryArray.toString 
methods and it works fine. There is also a toString() method which 
accepts a Charset, so that isn't an issue.


[1] 
https://github.com/openjdk/panama-foreign/blob/4c00f872eaf7bc3ac1be3a18060331d76de1fee0/src/java.base/share/classes/java/foreign/memory/Pointer.java#L265



>
> -------------
>
> Commit messages:
>   - 8241148: need a way to create MemorySegment with contents from java String and a way to read a C char* as java String
>
> Changes: https://git.openjdk.java.net/panama-foreign/pull/55/files
>   Webrev: https://webrevs.openjdk.java.net/panama-foreign/55/webrev.00
>    Issue: https://bugs.openjdk.java.net/browse/JDK-8241148
>    Stats: 154 lines in 3 files changed: 133 ins; 19 del; 2 mod
>    Patch: https://git.openjdk.java.net/panama-foreign/pull/55.diff
>    Fetch: git fetch https://git.openjdk.java.net/panama-foreign pull/55/head:pull/55
>
> PR: https://git.openjdk.java.net/panama-foreign/pull/55


More information about the panama-dev mailing list