Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DirectAccessData #22

Merged
merged 1 commit into from
Oct 7, 2024
Merged
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
2 changes: 0 additions & 2 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
exports overrun.marshal.gen.processor;
exports overrun.marshal.struct;

opens overrun.marshal.internal.data;

requires static org.jetbrains.annotations;
requires io.github.overrun.memstack;
}
38 changes: 2 additions & 36 deletions src/main/java/overrun/marshal/DirectAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@

package overrun.marshal;

import org.jetbrains.annotations.Unmodifiable;
import overrun.marshal.gen.Skip;

import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.SymbolLookup;
import java.lang.invoke.MethodHandle;
import java.util.Map;

/**
* This interface provides access to function descriptors and method handles
* for each function that is loaded by {@link Downcall}.
Expand All @@ -34,33 +26,7 @@
*/
public interface DirectAccess {
/**
* {@return an unmodifiable map of the function descriptors for each method}
*/
@Skip
@Unmodifiable
Map<String, FunctionDescriptor> functionDescriptors();

/**
* {@return an unmodifiable map of the method handles for each method}
*/
@Skip
@Unmodifiable
Map<String, MethodHandle> methodHandles();

/**
* Gets the method handle with the given entrypoint name.
*
* @param entrypoint the entrypoint name
* @return the method handle
*/
@Skip
default MethodHandle methodHandle(String entrypoint) {
return methodHandles().get(entrypoint);
}

/**
* {@return the symbol lookup of this library}
* {@return the data of this access}
*/
@Skip
SymbolLookup symbolLookup();
DirectAccessData directAccessData();
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@
* copies or substantial portions of the Software.
*/

package overrun.marshal.internal.data;
package overrun.marshal;

import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.SymbolLookup;
import java.lang.invoke.MethodHandle;
import java.util.Map;

/**
* Downcall class data
* The data for {@link DirectAccess}.
*
* @param descriptorMap descriptorMap
* @param handleMap handleMap
* @param symbolLookup symbolLookup
* @param functionDescriptors an unmodifiable map of the function descriptors for each method
* @param methodHandles an unmodifiable map of the method handles for each method
* @param symbolLookup the symbol lookup of this library
* @author squid233
* @since 0.1.0
*/
public record DowncallData(
Map<String, FunctionDescriptor> descriptorMap,
Map<String, MethodHandle> handleMap,
public record DirectAccessData(
Map<String, FunctionDescriptor> functionDescriptors,
Map<String, MethodHandle> methodHandles,
SymbolLookup symbolLookup
) {
}
42 changes: 13 additions & 29 deletions src/main/java/overrun/marshal/Downcall.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import overrun.marshal.gen.processor.*;
import overrun.marshal.internal.DowncallOptions;
import overrun.marshal.internal.StringCharset;
import overrun.marshal.internal.data.DowncallData;
import overrun.marshal.struct.ByValue;

import java.lang.classfile.ClassFile;
Expand Down Expand Up @@ -208,7 +207,7 @@ private static String getMethodEntrypoint(Method method) {
entrypoint.value();
}

private static Map.Entry<byte[], DowncallData> buildBytecode(MethodHandles.Lookup caller, SymbolLookup lookup, DowncallOption... options) {
private static Map.Entry<byte[], DirectAccessData> buildBytecode(MethodHandles.Lookup caller, SymbolLookup lookup, DowncallOption... options) {
Class<?> _targetClass = null, targetClass;
Map<String, FunctionDescriptor> _descriptorMap = null, descriptorMap;
UnaryOperator<MethodHandle> _transform = null, transform;
Expand Down Expand Up @@ -281,7 +280,7 @@ private static Map.Entry<byte[], DowncallData> buildBytecode(MethodHandles.Looku
}
//endregion

final DowncallData downcallData = generateData(methodDataMap, lookup, descriptorMap, transform);
final var downcallData = generateData(methodDataMap, lookup, descriptorMap, transform);

return Map.entry(cf.build(cd_thisClass, classBuilder -> {
classBuilder.withFlags(ACC_FINAL | ACC_SUPER);
Expand All @@ -296,7 +295,7 @@ private static Map.Entry<byte[], DowncallData> buildBytecode(MethodHandles.Looku

//region method handles
for (String entrypoint : methodEntrypointSet) {
if (downcallData.handleMap().get(entrypoint) != null) {
if (downcallData.methodHandles().get(entrypoint) != null) {
classBuilder.withField(entrypoint,
CD_MethodHandle,
ACC_PRIVATE | ACC_FINAL | ACC_STATIC);
Expand Down Expand Up @@ -342,7 +341,7 @@ private static Map.Entry<byte[], DowncallData> buildBytecode(MethodHandles.Looku
// returns MethodHandle
if (returnType == MethodHandle.class) {
if (method.isDefault() &&
downcallData.handleMap().get(entrypoint) == null) {
downcallData.methodHandles().get(entrypoint) == null) {
// invoke super interface
invokeSuperMethod(codeBuilder, parameters);
codeBuilder.invokespecial(cd_targetClass,
Expand All @@ -358,7 +357,7 @@ private static Map.Entry<byte[], DowncallData> buildBytecode(MethodHandles.Looku
}

if (method.isDefault() &&
downcallData.handleMap().get(entrypoint) == null) {
downcallData.methodHandles().get(entrypoint) == null) {
// invoke super interface
invokeSuperMethod(codeBuilder, parameters);
codeBuilder.invokespecial(cd_targetClass,
Expand Down Expand Up @@ -470,26 +469,11 @@ private static Map.Entry<byte[], DowncallData> buildBytecode(MethodHandles.Looku
//region DirectAccess
final boolean hasDirectAccess = DirectAccess.class.isAssignableFrom(targetClass);
if (hasDirectAccess) {
classBuilder.withMethodBody("functionDescriptors",
MTD_Map,
classBuilder.withMethodBody("directAccessData",
MTD_DirectAccessData,
ACC_PUBLIC,
codeBuilder -> codeBuilder
.ldc(DCD_classData_DowncallData)
.invokevirtual(CD_DowncallData, "descriptorMap", MTD_Map)
.areturn());
classBuilder.withMethodBody("methodHandles",
MTD_Map,
ACC_PUBLIC,
codeBuilder -> codeBuilder
.ldc(DCD_classData_DowncallData)
.invokevirtual(CD_DowncallData, "handleMap", MTD_Map)
.areturn());
classBuilder.withMethodBody("symbolLookup",
MTD_SymbolLookup,
ACC_PUBLIC,
codeBuilder -> codeBuilder
.ldc(DCD_classData_DowncallData)
.invokevirtual(CD_DowncallData, "symbolLookup", MTD_SymbolLookup)
.ldc(DCD_classData_DirectAccessData)
.areturn());
}
//endregion
Expand All @@ -498,13 +482,13 @@ private static Map.Entry<byte[], DowncallData> buildBytecode(MethodHandles.Looku
classBuilder.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC,
codeBuilder -> {
final int handleMapSlot = codeBuilder.allocateLocal(TypeKind.ReferenceType);
codeBuilder.ldc(DCD_classData_DowncallData)
.invokevirtual(CD_DowncallData, "handleMap", MTD_Map)
codeBuilder.ldc(DCD_classData_DirectAccessData)
.invokevirtual(CD_DirectAccessData, "methodHandles", MTD_Map)
.astore(handleMapSlot);

// method handles
for (String entrypoint : methodEntrypointSet) {
if (downcallData.handleMap().get(entrypoint) != null) {
if (downcallData.methodHandles().get(entrypoint) != null) {
codeBuilder
.aload(handleMapSlot)
.ldc(entrypoint)
Expand Down Expand Up @@ -622,7 +606,7 @@ private static boolean isValidReturnType(Class<?> aClass) {
return aClass == MethodHandle.class || ProcessorTypes.isRegisteredExactly(aClass);
}

private static DowncallData generateData(
private static DirectAccessData generateData(
Map<Method, DowncallMethodData> methodDataMap,
SymbolLookup lookup,
Map<String, FunctionDescriptor> descriptorMap,
Expand Down Expand Up @@ -676,7 +660,7 @@ private static DowncallData generateData(
}
}
}
return new DowncallData(Collections.unmodifiableMap(descriptorMap1),
return new DirectAccessData(Collections.unmodifiableMap(descriptorMap1),
Collections.unmodifiableMap(map),
lookup);
}
Expand Down
18 changes: 7 additions & 11 deletions src/main/java/overrun/marshal/internal/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public final class Constants {
*/
public static final ClassDesc CD_Checks = ClassDesc.of("overrun.marshal.Checks");
/**
* CD_DowncallData
* CD_DirectAccessData
*/
public static final ClassDesc CD_DowncallData = ClassDesc.of("overrun.marshal.internal.data.DowncallData");
public static final ClassDesc CD_DirectAccessData = ClassDesc.of("overrun.marshal.DirectAccessData");
/**
* CD_IllegalStateException
*/
Expand Down Expand Up @@ -105,10 +105,6 @@ public final class Constants {
* CD_StructLayout
*/
public static final ClassDesc CD_StructLayout = ClassDesc.of("java.lang.foreign.StructLayout");
/**
* CD_SymbolLookup
*/
public static final ClassDesc CD_SymbolLookup = ClassDesc.of("java.lang.foreign.SymbolLookup");
/**
* CD_Unmarshal
*/
Expand Down Expand Up @@ -214,6 +210,10 @@ public final class Constants {
* MTD_Charset_String
*/
public static final MethodTypeDesc MTD_Charset_String = MethodTypeDesc.of(CD_Charset, CD_String);
/**
* MTD_DirectAccessData
*/
public static final MethodTypeDesc MTD_DirectAccessData = MethodTypeDesc.of(CD_DirectAccessData);
/**
* MTD_long
*/
Expand Down Expand Up @@ -366,10 +366,6 @@ public final class Constants {
* MTD_StructLayout
*/
public static final MethodTypeDesc MTD_StructLayout = MethodTypeDesc.of(CD_StructLayout);
/**
* MTD_SymbolLookup
*/
public static final MethodTypeDesc MTD_SymbolLookup = MethodTypeDesc.of(CD_SymbolLookup);
/**
* MTD_Upcall_MemorySegment
*/
Expand Down Expand Up @@ -438,7 +434,7 @@ public final class Constants {
/**
* DCD_classData_DowncallData
*/
public static final DynamicConstantDesc<?> DCD_classData_DowncallData = DynamicConstantDesc.ofNamed(BSM_CLASS_DATA, DEFAULT_NAME, CD_DowncallData);
public static final DynamicConstantDesc<?> DCD_classData_DirectAccessData = DynamicConstantDesc.ofNamed(BSM_CLASS_DATA, DEFAULT_NAME, CD_DirectAccessData);
/**
* DCD_classData_StructLayout
*/
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/overrun/marshal/test/GlobalVarTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public final class GlobalVarTest {

interface I extends DirectAccess {
I INSTANCE = Downcall.load(MethodHandles.lookup(), LOOKUP);
MemorySegment myGlobalVar = INSTANCE.symbolLookup().findOrThrow("globalVar");
MemorySegment myGlobalVar = INSTANCE.directAccessData().symbolLookup().findOrThrow("globalVar");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ void testInheritDowncall() {
assertEquals(1, d.get2());
assertEquals(3, d.get3());

assertEquals(3, assertDoesNotThrow(() -> (int) d.methodHandle("get3").invokeExact()));
assertEquals(3, assertDoesNotThrow(() -> (int) d.directAccessData().methodHandles().get("get3").invokeExact()));
}
}