On Thu, 23 Mar 2023 10:28:23 GMT, Maurizio Cimadamore <mcimadam...@openjdk.org> wrote:
>> Yes - although there is a distinction between passed by value and by ref. I >> wouldn't be surprised if we just threw NPE for by-value. > > Just did a test with jshell: > > > jshell> Linker linker = Linker.nativeLinker(); > > jshell> MethodHandle handleValue = > linker.downcallHandle(FunctionDescriptor.ofVoid(MemoryLayout.structLayout(ValueLayout.JAVA_INT))); > handleValue ==> MethodHandle(MemorySegment,MemorySegment)void > > jshell> handleValue.invoke(MemorySegment.ofAddress(1), null); > | Exception java.lang.NullPointerException > | at (#5:1) > > > So, yes, passing `null` for a "by-value" struct issues NPEs. I also get same > exception when calling a method handle which passes a struct by reference: > > > jshell> MethodHandle handleRef = > linker.downcallHandle(FunctionDescriptor.ofVoid(ValueLayout.ADDRESS)); > handleRef ==> MethodHandle(MemorySegment,MemorySegment)void > > jshell> handleRef.invoke(MemorySegment.ofAddress(1), null); > | Exception java.lang.NullPointerException > | at (#7:1) > > > Given what the impl does, to be fair I don't mind the NPE (it seems a good > exception to throw if we're passing a raw `null`). But we should document it > at such. > > It also seems like the first parameter of the downcall has somewhat better > checks (but still NPEs): > > > jshell> handleRef.invoke(null, MemorySegment.ofAddress(1)); > | Exception java.lang.NullPointerException > | at Objects.requireNonNull (Objects.java:233) > | at SharedUtils.checkSymbol (SharedUtils.java:351) > | at (#8:1) > > > And: > > > jshell> handleRef.invoke(MemorySegment.NULL, MemorySegment.ofAddress(1)); > | Exception java.lang.IllegalArgumentException: Symbol is NULL: > MemorySegment{ heapBase: Optional.empty address:0 limit: 0 } > | at SharedUtils.checkSymbol (SharedUtils.java:353) > | at (#9:1) > > > I think this last case is the _only_ one where IAE is warranted - as the role > of the first parameter is special, and we can't tolerate a > `MemorySegment::NULL` there. For all other reference parameters, the downcall > handle should just check that they are non-null, and throw if so. The returned method handle will throw an {@link IllegalArgumentException} if the {@link MemorySegment} representing the target address of the foreign function is the {@link MemorySegment#NULL} address. The returned method handle will additionally throw {@link NullPointerException} if any parameter of type {@link MemorySegment} is {@code null}. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/13079#discussion_r1145982159