8344989: Test java/foreign/TestLinker.java failed with zero: IllegalStateException: libffi call failed with status: FFI_BAD_TYPEDEF

Reviewed-by: jvernee
This commit is contained in:
Per Minborg 2024-11-29 09:24:29 +00:00
parent 08d563ba15
commit f2c0d186ff
2 changed files with 43 additions and 2 deletions

View file

@ -31,6 +31,7 @@ import java.lang.foreign.GroupLayout;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.lang.foreign.SequenceLayout;
import java.lang.foreign.ValueLayout;
import static java.lang.foreign.ValueLayout.ADDRESS;
import static java.lang.foreign.ValueLayout.JAVA_BOOLEAN;
@ -85,6 +86,7 @@ public final class FallbackLinker extends AbstractLinker {
@Override
protected MethodHandle arrangeDowncall(MethodType inferredMethodType, FunctionDescriptor function, LinkerOptions options) {
assertNotEmpty(function);
MemorySegment cif = makeCif(inferredMethodType, function, options, Arena.ofAuto());
int capturedStateMask = options.capturedCallState()
@ -111,6 +113,7 @@ public final class FallbackLinker extends AbstractLinker {
@Override
protected UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function, LinkerOptions options) {
assertNotEmpty(function);
MemorySegment cif = makeCif(targetType, function, options, Arena.ofAuto());
UpcallData invData = new UpcallData(function.returnLayout().orElse(null), function.argumentLayouts(), cif);
@ -325,4 +328,35 @@ public final class FallbackLinker extends AbstractLinker {
return Holder.CANONICAL_LAYOUTS;
}
private static void assertNotEmpty(FunctionDescriptor fd) {
fd.returnLayout().ifPresent(FallbackLinker::assertNotEmpty);
fd.argumentLayouts().forEach(FallbackLinker::assertNotEmpty);
}
// Recursively tests for emptiness
private static void assertNotEmpty(MemoryLayout layout) {
switch (layout) {
case GroupLayout gl -> {
if (gl.memberLayouts().isEmpty()) {
throw empty(gl);
} else {
gl.memberLayouts().forEach(FallbackLinker::assertNotEmpty);
}
}
case SequenceLayout sl -> {
if (sl.elementCount() == 0) {
throw empty(sl);
} else {
assertNotEmpty(sl.elementLayout());
}
}
default -> { /* do nothing */ }
}
}
private static IllegalArgumentException empty(MemoryLayout layout) {
return new IllegalArgumentException("The layout " + layout + " is empty");
}
}