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

Processors and Optimize #14

Merged
merged 2 commits into from
May 17, 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: 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.25-jdk22")
implementation("io.github.over-run:marshal:0.1.0-alpha.26-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.25-jdk22
projVersion=0.1.0-alpha.26-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
2 changes: 2 additions & 0 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
module io.github.overrun.marshal {
exports overrun.marshal;
exports overrun.marshal.gen;
exports overrun.marshal.gen.processor;
exports overrun.marshal.struct;

opens overrun.marshal.internal.data;

requires static org.jetbrains.annotations;
requires jdk.jshell;
}
696 changes: 301 additions & 395 deletions src/main/java/overrun/marshal/Downcall.java

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/main/java/overrun/marshal/gen/Convert.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
import java.lang.annotation.*;

/**
* Marks an element that needs to convert from {@code boolean} to the given type.
* Marks a parameter that needs to convert from {@code boolean} to the given type,
* or a return type that needs to convert from the given type to {@code boolean}.
* <p>
* The type of the marked element must be {@code boolean}; otherwise this annotation will be ignored.
* <h2>Example</h2>
Expand Down
148 changes: 148 additions & 0 deletions src/main/java/overrun/marshal/gen/processor/ArgumentProcessor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* MIT License
*
* Copyright (c) 2024 Overrun Organization
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/

package overrun.marshal.gen.processor;

import overrun.marshal.gen.Type;
import overrun.marshal.internal.StringCharset;

import java.lang.classfile.CodeBuilder;
import java.lang.constant.MethodTypeDesc;
import java.util.ArrayList;
import java.util.List;

import static java.lang.constant.ConstantDescs.CD_boolean;
import static overrun.marshal.internal.Constants.*;

/**
* Method argument processor
*
* @author squid233
* @since 0.1.0
*/
public final class ArgumentProcessor implements Processor<ProcessorType, ArgumentProcessorContext> {
private static final ArgumentProcessor INSTANCE = new ArgumentProcessor();
private final List<Processor<ProcessorType, ArgumentProcessorContext>> list = new ArrayList<>(0);

private ArgumentProcessor() {
}

@SuppressWarnings("preview")
public boolean process(CodeBuilder builder, ProcessorType type, ArgumentProcessorContext context) {
switch (type) {
case ProcessorType.Value value -> {
if (value == ProcessorType.Value.BOOLEAN &&
context.convert() != null) {
final Type convertType = context.convert().value();
builder.loadInstruction(
value.typeKind(),
context.parameterSlot()
).invokestatic(CD_Marshal,
marshalFromBooleanMethod(convertType),
MethodTypeDesc.of(convertType.classDesc(), CD_boolean));
} else {
builder.loadInstruction(
value.typeKind().asLoadable(),
context.parameterSlot()
);
}
}
case ProcessorType.Allocator _ -> builder.aload(context.parameterSlot());
case ProcessorType.Str _ -> {
builder.aload(context.allocatorSlot())
.aload(context.parameterSlot());
if (StringCharset.getCharset(builder, context.parameter())) {
builder.invokestatic(CD_Marshal,
"marshal",
MTD_MemorySegment_SegmentAllocator_String_Charset);
} else {
builder.invokestatic(CD_Marshal,
"marshal",
MTD_MemorySegment_SegmentAllocator_String);
}
}
case ProcessorType.Addr _, ProcessorType.CEnum _ -> builder
.aload(context.parameterSlot())
.invokestatic(CD_Marshal,
"marshal",
MethodTypeDesc.of(type.downcallClassDesc(), type.marshalClassDesc()));
case ProcessorType.Upcall _ -> builder
.aload(context.allocatorSlot())
.checkcast(CD_Arena)
.aload(context.parameterSlot())
.invokestatic(CD_Marshal,
"marshal",
MTD_MemorySegment_Arena_Upcall);
case ProcessorType.Array array -> {
final ProcessorType componentType = array.componentType();
final boolean isStringArray = componentType instanceof ProcessorType.Str;
final boolean isUpcallArray = componentType instanceof ProcessorType.Upcall;
builder.aload(context.allocatorSlot());
if (isUpcallArray) {
builder.checkcast(CD_Arena);
}
builder.aload(context.parameterSlot());
if (isStringArray && StringCharset.getCharset(builder, context.parameter())) {
builder.invokestatic(CD_Marshal,
"marshal",
MTD_MemorySegment_SegmentAllocator_StringArray_Charset);
} else {
builder.invokestatic(CD_Marshal,
"marshal",
MethodTypeDesc.of(CD_MemorySegment,
isUpcallArray ? CD_Arena : CD_SegmentAllocator,
array.marshalClassDesc()));
}
}
default -> {
for (var processor : list) {
if (!processor.process(builder, type, context)) {
break;
}
}
}
}
return false;
}

/**
* Registers a processor
*
* @param processor the processor
*/
public void registerProcessor(Processor<ProcessorType, ArgumentProcessorContext> processor) {
list.add(processor);
}

/**
* {@return this}
*/
public static ArgumentProcessor getInstance() {
return INSTANCE;
}

private static String marshalFromBooleanMethod(Type convertType) {
return switch (convertType) {
case CHAR -> "marshalAsChar";
case BYTE -> "marshalAsByte";
case SHORT -> "marshalAsShort";
case INT -> "marshalAsInt";
case LONG -> "marshalAsLong";
case FLOAT -> "marshalAsFloat";
case DOUBLE -> "marshalAsDouble";
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* MIT License
*
* Copyright (c) 2024 Overrun Organization
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/

package overrun.marshal.gen.processor;

import overrun.marshal.gen.Convert;

import java.lang.reflect.Parameter;

/**
* The argument processor context
*
* @param parameter parameter
* @param parameterSlot parameter slot
* @param allocatorSlot allocator slot
* @param convert boolean convert
* @author squid233
* @since 0.1.0
*/
public record ArgumentProcessorContext(
Parameter parameter,
int parameterSlot,
int allocatorSlot,
Convert convert
) {
}
39 changes: 39 additions & 0 deletions src/main/java/overrun/marshal/gen/processor/Processor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* MIT License
*
* Copyright (c) 2024 Overrun Organization
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/

package overrun.marshal.gen.processor;

import java.lang.classfile.CodeBuilder;

/**
* Processor
*
* @param <T> target type
* @param <C> context type
* @author squid233
* @since 0.1.0
*/
public interface Processor<T, C> {
/**
* Processes with the context
*
* @param builder the code builder
* @param type the type
* @param context the context
* @return {@code true} if should continue; {@code false} otherwise
*/
boolean process(CodeBuilder builder, T type, C context);
}
Loading