Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class Method {
private Type returnType;
private Parameter[] parameters;
private String dll;
private boolean supportsAllocator;
private boolean supportsLastError;
private Object constantValue;
private LazyString documentationUrl;
Expand Down Expand Up @@ -208,6 +209,24 @@ public boolean hasReturnType() {
return !(returnType instanceof Primitive primitive && primitive.kind() == PrimitiveKind.VOID);
}

/**
* Indicates if this method uses a {@code SegmentAllocator} to allocate struct return values.
*
* @return {@code true} if {@code SegmentAllocator} is supported
*/
public boolean supportsAllocator() {
return supportsAllocator;
}

/**
* Sets if this method uses a {@code SegmentAllocator} to allocate struct return values.
*
* @param supportsAllocator {@code true} if {@code SegmentAllocator} is supported, {@code false} otherwise
*/
public void setSupportsAllocator(boolean supportsAllocator) {
this.supportsAllocator = supportsAllocator;
}

/**
* Indicates if this method uses the {@code GetLastError} function to provide error details.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class CustomAttributeDecoder extends Decoder {
private static final QualifiedName NATIVE_ENCODING_ATTRIBUTE = new QualifiedName(METADATA,
"NativeEncodingAttribute");
private static final QualifiedName NATIVE_TYPEDEF_ATTRIBUTE = new QualifiedName(METADATA, "NativeTypedefAttribute");
private static final QualifiedName METADATA_TYPEDEF_ATTRIBUTE = new QualifiedName(METADATA,
"MetadataTypedefAttribute");
private static final QualifiedName STRUCT_SIZE_FIELD_ATTRIBUTE = new QualifiedName(METADATA,
"StructSizeFieldAttribute");
private static final QualifiedName SUPPORTED_ARCHITECTURE_ATTRIBUTE = new QualifiedName(METADATA,
Expand All @@ -72,6 +74,8 @@ class CustomAttributeDecoder extends Decoder {
(context, data) -> data.guidConstant = createGuidConstant(context.getValue()),
NATIVE_TYPEDEF_ATTRIBUTE,
(context, data) -> data.isTypedef = true,
METADATA_TYPEDEF_ATTRIBUTE,
(context, data) -> data.isTypedef = true,
STRUCT_SIZE_FIELD_ATTRIBUTE,
(context, data) -> data.structSizeField = (String) context.getValue().fixedArguments()[0].value()
);
Expand All @@ -89,7 +93,6 @@ class CustomAttributeDecoder extends Decoder {
new QualifiedName(METADATA, "AnsiAttribute"),
new QualifiedName(METADATA, "AssociatedConstantAttribute"),
new QualifiedName(METADATA, "InvalidHandleValueAttribute"),
new QualifiedName(METADATA, "MetadataTypedefAttribute"),
new QualifiedName(METADATA, "RAIIFreeAttribute"),
new QualifiedName(METADATA, "ScopedEnumAttribute"),
new QualifiedName(METADATA, "SupportedOSPlatformAttribute"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,9 @@ private void buildMethodParameters(Method method) {
var methodDef = metadataFile.getMethodDef(method.methodDefIndex());
var methodSignature =
signatureDecoder.decodeMethodDefSignature(metadataFile.getBlob(methodDef.signature()));
method.setReturnType(methodSignature.returnType());
var returnType = methodSignature.returnType();
method.setReturnType(returnType);
method.setSupportsAllocator(returnType instanceof Struct);

var parameters = new Parameter[methodSignature.paramTypes().length];
int index = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,20 @@ void writeFunctionComment(PrintWriter writer, Method function, String label) {
* </p>
""");

if (function.supportsLastError())
var supportsAllocator = function.supportsAllocator();
var supportsLastError = function.supportsLastError();
if (supportsAllocator)
writer.print("""
* <p>
* The additional first parameter takes a memory segment to capture the call state (replacement for {@code GetLastError()}).
* The additional first parameter takes a segment allocator to allocate struct return values.
* </p>
""");
if (supportsLastError)
writer.printf("""
* <p>
* The additional %s parameter takes a memory segment to capture the call state (replacement for {@code GetLastError()}).
* </p>
""", supportsAllocator ? "second" : "first");

writeDocumentationUrl(writer, function);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
*/
class FunctionCodeWriter extends FunctionCodeWriterBase<Type> {

private static final String CALL_STATE_NOTE = "The additional first parameter takes a memory segment to capture " +
private static final String CALL_STATE_NOTE_1 = "The additional first parameter takes a segment allocator to " +
"allocate struct return values.";
private static final String CALL_STATE_NOTE_2 = "The additional %s parameter takes a memory segment to capture " +
"the call state (replacement for {@code GetLastError()}).";

private final CommentWriter commentWriter = new CommentWriter();
Expand Down Expand Up @@ -150,10 +152,15 @@ private void writeFunctionInnerClass(Method method) {

private void writeFunctionDescriptorAndHandle(Method method) {
var methodName = method.name();
var supportsAllocator = method.supportsAllocator();
var supportsLastError = method.supportsLastError();

var callStateNote1 = supportsAllocator ? CALL_STATE_NOTE_1 : null;
var callStateNote2 = supportsLastError ? String.format(CALL_STATE_NOTE_2, supportsAllocator ? "second" : "first") : null;

// descriptor accessor
writeCommentWithNotes(String.format("Gets the function descriptor for {@code %s}", method.nativeName()),
method.supportsLastError() ? CALL_STATE_NOTE : null);
callStateNote1, callStateNote2);
writer.printf("""
public static FunctionDescriptor %1$s$descriptor() {
return %1$s$IMPL.DESC;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,18 @@ protected void writeFunctionSignatureIntro(Method function, String functionName)
*/
protected void writeFunctionSignatureParameters(Method function) {
var parameters = function.parameters();
if (function.supportsLastError())
writer.print("MemorySegment lastErrorState");
var supportsAllocator = function.supportsAllocator();
var supportsLastError = function.supportsLastError();

if (supportsAllocator)
writer.print("SegmentAllocator allocator");
if (supportsLastError)
writer.printf("%sMemorySegment lastErrorState",
supportsAllocator ? ", " : "");

for (int i = 0; i < parameters.length; i += 1) {
writer.printf("%s%s %s",
i > 0 || function.supportsLastError() ? ", " : "",
i > 0 || supportsAllocator || supportsLastError ? ", " : "",
getJavaType(parameters[i].type()),
getJavaSafeName(parameters[i].name()));
}
Expand All @@ -113,13 +119,16 @@ protected void writeInvoke(Method function, String invoke, int indenting) {
%1$stry {
%1$s %2$s%3$s""", indent, returnWithCast, invoke);

var supportsAllocator = function.supportsAllocator();
var supportsLastError = function.supportsLastError();
if (supportsAllocator)
writer.print("allocator");
if (supportsLastError)
writer.print("lastErrorState");
writer.printf("%slastErrorState", supportsAllocator ? ", " : "");

var parameters = function.parameters();
for (int i = 0; i < parameters.length; i += 1) {
writer.print(i > 0 || supportsLastError ? ", " : "");
writer.print(i > 0 || supportsAllocator || supportsLastError ? ", " : "");
writer.print(getJavaSafeName(parameters[i].name()));
}
writer.println(");");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void writeAll_succeeds() {
.map(Map.Entry::getKey).toList();
assertThat(duplicateFiles).isEmpty();
// The following number must not change unless the metadata has been updated
assertThat(eventListener.filePaths).hasSize(31992);
assertThat(eventListener.filePaths).hasSize(31985);
}

@Test
Expand Down