Skip to content

Commit

Permalink
Update Downcall.java
Browse files Browse the repository at this point in the history
  • Loading branch information
squid233 committed Feb 25, 2024
1 parent 94ee289 commit a14346e
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 83 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Import as a Gradle dependency:

```groovy
dependencies {
implementation("io.github.over-run:marshal:0.1.0-alpha.20-jdk22")
implementation("io.github.over-run:marshal:0.1.0-alpha.21-jdk22")
}
```

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ projGroupId=io.github.over-run
projArtifactId=marshal
# The project name should only contain lowercase letters, numbers and hyphen.
projName=marshal
projVersion=0.1.0-alpha.20-jdk22
projVersion=0.1.0-alpha.21-jdk22
projDesc=Marshaler of native libraries
# Uncomment them if you want to publish to maven repository.
projUrl=https://github.com/Over-Run/marshal
Expand Down
163 changes: 82 additions & 81 deletions src/main/java/overrun/marshal/Downcall.java
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,8 @@ private static boolean shouldSkip(Method method) {
final boolean b =
method.getDeclaredAnnotation(Skip.class) != null ||
Modifier.isStatic(method.getModifiers()) ||
method.isSynthetic();
method.isSynthetic() ||
Modifier.isFinal(method.getModifiers());
if (b) {
return true;
}
Expand Down Expand Up @@ -996,96 +997,98 @@ private static DowncallData generateData(Map<Method, DowncallMethodData> methodD
final String entrypoint = methodData.entrypoint();
final Optional<MemorySegment> optional = lookup.find(entrypoint);

if (optional.isPresent()) {
// function descriptor
final FunctionDescriptor descriptor;
final FunctionDescriptor get = descriptorMap.get(entrypoint);
if (get != null) {
descriptor = get;
} else {
final var returnType = method.getReturnType();
final boolean returnVoid = returnType == void.class;
final boolean methodByValue = method.getDeclaredAnnotation(ByValue.class) != null;

// return layout
final MemoryLayout retLayout;
if (!returnVoid) {
final Convert convert = method.getDeclaredAnnotation(Convert.class);
if (convert != null && returnType == boolean.class) {
retLayout = convert.value().layout();
} else if (returnType.isPrimitive()) {
retLayout = getValueLayout(returnType);
} else {
final SizedSeg sizedSeg = method.getDeclaredAnnotation(SizedSeg.class);
final Sized sized = method.getDeclaredAnnotation(Sized.class);
final boolean isSizedSeg = sizedSeg != null;
final boolean isSized = sized != null;
if (Struct.class.isAssignableFrom(returnType)) {
StructLayout structLayout = null;
for (Field field : returnType.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers()) && field.getType() == StructLayout.class) {
try {
structLayout = (StructLayout) field.get(null);
break;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
// function descriptor
final FunctionDescriptor descriptor;
final FunctionDescriptor get = descriptorMap.get(entrypoint);
if (get != null) {
descriptor = get;
} else {
final var returnType = method.getReturnType();
final boolean returnVoid = returnType == void.class;
final boolean methodByValue = method.getDeclaredAnnotation(ByValue.class) != null;

// return layout
final MemoryLayout retLayout;
if (!returnVoid) {
final Convert convert = method.getDeclaredAnnotation(Convert.class);
if (convert != null && returnType == boolean.class) {
retLayout = convert.value().layout();
} else if (returnType.isPrimitive()) {
retLayout = getValueLayout(returnType);
} else {
final SizedSeg sizedSeg = method.getDeclaredAnnotation(SizedSeg.class);
final Sized sized = method.getDeclaredAnnotation(Sized.class);
final boolean isSizedSeg = sizedSeg != null;
final boolean isSized = sized != null;
if (Struct.class.isAssignableFrom(returnType)) {
StructLayout structLayout = null;
for (Field field : returnType.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers()) && field.getType() == StructLayout.class) {
try {
structLayout = (StructLayout) field.get(null);
break;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
Objects.requireNonNull(structLayout);
if (methodByValue) {
retLayout = structLayout;
}
Objects.requireNonNull(structLayout);
if (methodByValue) {
retLayout = structLayout;
} else {
final MemoryLayout targetLayout;
if (isSizedSeg) {
targetLayout = MemoryLayout.sequenceLayout(sizedSeg.value(), structLayout);
} else if (isSized) {
targetLayout = MemoryLayout.sequenceLayout(sized.value(), structLayout);
} else {
final MemoryLayout targetLayout;
if (isSizedSeg) {
targetLayout = MemoryLayout.sequenceLayout(sizedSeg.value(), structLayout);
} else if (isSized) {
targetLayout = MemoryLayout.sequenceLayout(sized.value(), structLayout);
} else {
targetLayout = structLayout;
}
retLayout = ValueLayout.ADDRESS.withTargetLayout(targetLayout);
targetLayout = structLayout;
}
} else {
final ValueLayout valueLayout = getValueLayout(returnType);
if ((valueLayout instanceof AddressLayout addressLayout) && (isSizedSeg || isSized)) {
if (isSizedSeg) {
retLayout = addressLayout.withTargetLayout(MemoryLayout.sequenceLayout(sizedSeg.value(),
ValueLayout.JAVA_BYTE));
} else {
retLayout = addressLayout.withTargetLayout(MemoryLayout.sequenceLayout(sized.value(),
returnType.isArray() ? getValueLayout(returnType.getComponentType()) : ValueLayout.JAVA_BYTE));
}
retLayout = ValueLayout.ADDRESS.withTargetLayout(targetLayout);
}
} else {
final ValueLayout valueLayout = getValueLayout(returnType);
if ((valueLayout instanceof AddressLayout addressLayout) && (isSizedSeg || isSized)) {
if (isSizedSeg) {
retLayout = addressLayout.withTargetLayout(MemoryLayout.sequenceLayout(sizedSeg.value(),
ValueLayout.JAVA_BYTE));
} else {
retLayout = valueLayout;
retLayout = addressLayout.withTargetLayout(MemoryLayout.sequenceLayout(sized.value(),
returnType.isArray() ? getValueLayout(returnType.getComponentType()) : ValueLayout.JAVA_BYTE));
}
} else {
retLayout = valueLayout;
}
}
} else {
retLayout = null;
}
} else {
retLayout = null;
}

// argument layouts
final var parameters = methodData.parameters();
final boolean skipFirstParam = methodData.skipFirstParam();
final int size = skipFirstParam || methodByValue ?
parameters.size() - 1 :
parameters.size();
final MemoryLayout[] argLayouts = new MemoryLayout[size];
for (int i = 0; i < size; i++) {
final Parameter parameter = parameters.get(skipFirstParam ? i + 1 : i);
final Class<?> type = parameter.getType();
final Convert convert = parameter.getDeclaredAnnotation(Convert.class);
if (convert != null && type == boolean.class) {
argLayouts[i] = convert.value().layout();
} else {
argLayouts[i] = getValueLayout(type);
}
// argument layouts
final var parameters = methodData.parameters();
final boolean skipFirstParam = methodData.skipFirstParam();
final int size = skipFirstParam || methodByValue ?
parameters.size() - 1 :
parameters.size();
final MemoryLayout[] argLayouts = new MemoryLayout[size];
for (int i = 0; i < size; i++) {
final Parameter parameter = parameters.get(skipFirstParam ? i + 1 : i);
final Class<?> type = parameter.getType();
final Convert convert = parameter.getDeclaredAnnotation(Convert.class);
if (convert != null && type == boolean.class) {
argLayouts[i] = convert.value().layout();
} else {
argLayouts[i] = getValueLayout(type);
}

descriptor = returnVoid ? FunctionDescriptor.ofVoid(argLayouts) : FunctionDescriptor.of(retLayout, argLayouts);
}

descriptor = returnVoid ? FunctionDescriptor.ofVoid(argLayouts) : FunctionDescriptor.of(retLayout, argLayouts);
}

descriptorMap1.put(entrypoint, descriptor);

if (optional.isPresent()) {
// linker options
final Linker.Option[] options;
final Critical critical = method.getDeclaredAnnotation(Critical.class);
Expand All @@ -1097,13 +1100,11 @@ private static DowncallData generateData(Map<Method, DowncallMethodData> methodD

if (!map.containsKey(entrypoint)) {
map.put(entrypoint, LINKER.downcallHandle(optional.get(), descriptor, options));
descriptorMap1.put(entrypoint, descriptor);
}
} else if (method.isDefault()) {
map.putIfAbsent(entrypoint, null);
descriptorMap1.put(entrypoint, descriptorMap.get(entrypoint));
} else {
throw new UnsatisfiedLinkError(STR."unresolved symbol: \{entrypoint}: \{methodData.exceptionString()}");
throw new UnsatisfiedLinkError(STR."unresolved symbol: \{entrypoint} (\{descriptor}): \{methodData.exceptionString()}");
}
});
return new DowncallData(Collections.unmodifiableMap(descriptorMap1), Collections.unmodifiableMap(map), lookup);
Expand Down

0 comments on commit a14346e

Please sign in to comment.