Skip to content

Commit

Permalink
feat: correct function signatures, allow object pointers in native me…
Browse files Browse the repository at this point in the history
…thods
  • Loading branch information
zskamljic committed Dec 3, 2024
1 parent 4e14df7 commit 831f67a
Show file tree
Hide file tree
Showing 40 changed files with 246 additions and 199 deletions.
4 changes: 2 additions & 2 deletions src/main/java/zskamljic/wjvern/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public static void main(String[] args) {
}

private static ProcessBuilder compileAssembly(List<Path> libraries) {
var items = new ArrayList<>(List.of("clang++", "-static", "-x", "ir", "-"));
var items = new ArrayList<>(List.of("clang++", "-x", "ir", "-"));
libraries.removeIf(p -> p.getFileName().toString().isBlank());
if (!libraries.isEmpty()) {
var paths = new HashSet<Path>();
Expand All @@ -80,7 +80,7 @@ private static ProcessBuilder compileAssembly(List<Path> libraries) {
paths.add(library.toAbsolutePath().getParent());
libs.add(library.getFileName()
.toString()
.replaceAll("^lib", "")
.replaceAll("^lib", "")
.replaceAll("\\.(so|a)$", ""));
}
libs.forEach(l -> items.add("-l" + l));
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/zskamljic/wjvern/llir/ClassBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.constantpool.MethodRefEntry;
import java.lang.classfile.constantpool.StringEntry;
import java.lang.classfile.instruction.ExceptionCatch;
import java.lang.classfile.instruction.ThrowInstruction;
import java.lang.classfile.instruction.TypeCheckInstruction;
import java.lang.constant.ClassDesc;
Expand Down Expand Up @@ -101,7 +102,9 @@ private void handleStaticRequirements(IrClassGenerator classGenerator, List<Stri
hasThrow = hasThrow || method.code()
.stream()
.flatMap(CompoundElement::elementStream)
.anyMatch(c -> c instanceof ThrowInstruction || c instanceof TypeCheckInstruction t && t.opcode() == Opcode.CHECKCAST);
.anyMatch(c -> c instanceof ThrowInstruction ||
c instanceof ExceptionCatch ||
c instanceof TypeCheckInstruction t && t.opcode() == Opcode.CHECKCAST);
classGenerator.addMethod(method);
}

Expand Down
7 changes: 6 additions & 1 deletion src/main/java/zskamljic/wjvern/llir/FunctionBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,12 @@ private void generateCode(IrMethodGenerator generator) {
String currentLabel = null;
for (var element : code) {
if (debug && !(element instanceof Label)) {
generator.comment(element.toString());
if (element instanceof ExceptionCatch e) {
generator.comment("ExceptionCatch[catchType="+e.catchType()+",start="+labelGenerator.getLabel(e.tryStart())+
",end="+labelGenerator.getLabel(e.tryEnd())+",handler="+labelGenerator.getLabel(e.handler())+"]");
} else {
generator.comment(element.toString());
}
}
switch (element) {
case ArrayStoreInstruction as -> handleArrayStore(generator, stack, types, as);
Expand Down
30 changes: 28 additions & 2 deletions src/main/java/zskamljic/wjvern/llir/IrClassGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,18 @@ private void generateInterfaceVtables(StringBuilder builder) {
var name = f.simpleName();
var interfaceMethod = Stream.concat(methods.stream(), parentMethods.stream())
.filter(m -> m.methodName().equalsString(name) &&
m.methodTypeSymbol().parameterList().stream().map(IrTypeMapper::mapType).toList().equals(requiredParams))
m.methodTypeSymbol()
.parameterList()
.stream()
.map(IrTypeMapper::mapType)
.map(t -> {
if (t.isReferenceType()) {
return new LlvmType.Pointer(t);
}
return t;
})
.toList()
.equals(requiredParams))
.findFirst();
return f.signature() + "* " + interfaceMethod.map(methodElements -> "@" + Utils.methodName(methodElements.parent().get().thisClass().name().stringValue(), methodElements))
.orElse("null");
Expand Down Expand Up @@ -352,6 +363,13 @@ private List<LlvmType.Declared> methodRequiredTypes() {
c.accept(f.returnType());
f.parameters().forEach(c);
})
.map(t -> {
if (t instanceof LlvmType.Pointer(var d)) {
return d;
} else {
return t;
}
})
.filter(LlvmType.Declared.class::isInstance)
.map(LlvmType.Declared.class::cast)
.distinct()
Expand Down Expand Up @@ -481,7 +499,15 @@ private String declareMethod(MethodModel method) {
if (isVarArg && i == symbol.parameterCount() - 1) {
parameters.add("...");
} else {
parameters.add(IrTypeMapper.mapType(parameter).toString());
var parameterType = IrTypeMapper.mapType(parameter);
if (parameterType.isReferenceType()) {
if (method.flags().has(AccessFlag.NATIVE)) {
parameterType = LlvmType.Primitive.POINTER;
} else {
parameterType = new LlvmType.Pointer(parameterType);
}
}
parameters.add(parameterType.toString());
}
}
declaration.append(String.join(", ", parameters));
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/zskamljic/wjvern/llir/models/LlvmType.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ private static List<LlvmType> generateParameterList(String className, MethodType
for (int i = 0; i < methodTypeSymbol.parameterCount(); i++) {
var parameter = methodTypeSymbol.parameterType(i);
var type = IrTypeMapper.mapType(parameter);
if (type.isReferenceType()) {
type = new Pointer(type);
}
parameterList.add(type);
}
return parameterList;
Expand Down
10 changes: 10 additions & 0 deletions src/test/java/Finally.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
public class Finally {
static int main() {
new Exception();
try {
return 0;
} finally {
return 1;
}
}
}
12 changes: 6 additions & 6 deletions src/test/resources/BasicMath.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
declare void @"java/lang/Object_notifyAll()V"(%"java/lang/Object"*) nounwind
declare i32 @"java/lang/Object_hashCode()I"(%"java/lang/Object"*) nounwind
declare void @"java/lang/Object_notify()V"(%"java/lang/Object"*) nounwind
declare i1 @"java/lang/Object_equals(Ljava/lang/Object;)Z"(%"java/lang/Object"*, %"java/lang/Object"*)
declare void @"java/lang/Object_finalize()V"(%"java/lang/Object"*)
declare i1 @"java/lang/Object_equals(Ljava/lang/Object;)Z"(%"java/lang/Object"*, %"java/lang/Object")
declare void @"java/lang/Object_<init>()V"(%"java/lang/Object"*)
declare void @"java/lang/Object_wait0(J)V"(%"java/lang/Object"*, i64) nounwind
%BasicMath_vtable_type = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)* }
%"java/lang/Object_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)* }
%"java/lang/String_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)*, i32(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*)*, i8(%"java/lang/String"*)*, %java_Array(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup")*, %"java/lang/Object"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup")* }
%BasicMath_vtable_type = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)* }
%"java/lang/Object_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)* }
%"java/lang/String_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)*, i32(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*)*, i8(%"java/lang/String"*)*, %java_Array(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup"*)*, %"java/lang/Object"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup"*)* }

%"java/util/stream/IntStream" = type opaque
declare i32 @__gxx_personality_v0(...)
Expand All @@ -27,7 +27,7 @@ declare void @llvm.memset.p0.i64(ptr,i8,i64,i1)

@BasicMath_vtable_data = global %BasicMath_vtable_type {
i32(%"java/lang/Object"*)* @"java/lang/Object_hashCode()I",
i1(%"java/lang/Object"*, %"java/lang/Object")* @"java/lang/Object_equals(Ljava/lang/Object;)Z",
i1(%"java/lang/Object"*, %"java/lang/Object"*)* @"java/lang/Object_equals(Ljava/lang/Object;)Z",
void(%"java/lang/Object"*)* @"java/lang/Object_finalize()V"
}

Expand Down Expand Up @@ -221,4 +221,4 @@ label1:
unreachable
}

declare i32 @printf(%java_Array, ...) nounwind
declare i32 @printf(ptr, ...) nounwind
12 changes: 6 additions & 6 deletions src/test/resources/Comparisons.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
declare void @"java/lang/Object_notifyAll()V"(%"java/lang/Object"*) nounwind
declare i32 @"java/lang/Object_hashCode()I"(%"java/lang/Object"*) nounwind
declare void @"java/lang/Object_notify()V"(%"java/lang/Object"*) nounwind
declare i1 @"java/lang/Object_equals(Ljava/lang/Object;)Z"(%"java/lang/Object"*, %"java/lang/Object"*)
declare void @"java/lang/Object_finalize()V"(%"java/lang/Object"*)
declare i1 @"java/lang/Object_equals(Ljava/lang/Object;)Z"(%"java/lang/Object"*, %"java/lang/Object")
declare void @"java/lang/Object_<init>()V"(%"java/lang/Object"*)
declare void @"java/lang/Object_wait0(J)V"(%"java/lang/Object"*, i64) nounwind
%"java/lang/Object_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)* }
%"java/lang/String_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)*, i32(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*)*, i8(%"java/lang/String"*)*, %java_Array(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup")*, %"java/lang/Object"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup")* }
%Comparisons_vtable_type = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)* }
%"java/lang/Object_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)* }
%"java/lang/String_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)*, i32(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*)*, i8(%"java/lang/String"*)*, %java_Array(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup"*)*, %"java/lang/Object"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup"*)* }
%Comparisons_vtable_type = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)* }

%"java/util/stream/IntStream" = type opaque
declare i32 @__gxx_personality_v0(...)
Expand All @@ -27,7 +27,7 @@ declare void @llvm.memset.p0.i64(ptr,i8,i64,i1)

@Comparisons_vtable_data = global %Comparisons_vtable_type {
i32(%"java/lang/Object"*)* @"java/lang/Object_hashCode()I",
i1(%"java/lang/Object"*, %"java/lang/Object")* @"java/lang/Object_equals(Ljava/lang/Object;)Z",
i1(%"java/lang/Object"*, %"java/lang/Object"*)* @"java/lang/Object_equals(Ljava/lang/Object;)Z",
void(%"java/lang/Object"*)* @"java/lang/Object_finalize()V"
}

Expand Down Expand Up @@ -403,4 +403,4 @@ label1:
unreachable
}

declare i32 @puts(%java_Array) nounwind
declare i32 @puts(ptr) nounwind
12 changes: 6 additions & 6 deletions src/test/resources/ConstructorAndInstanceMethods.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
declare void @"java/lang/Object_notifyAll()V"(%"java/lang/Object"*) nounwind
declare i32 @"java/lang/Object_hashCode()I"(%"java/lang/Object"*) nounwind
declare void @"java/lang/Object_notify()V"(%"java/lang/Object"*) nounwind
declare i1 @"java/lang/Object_equals(Ljava/lang/Object;)Z"(%"java/lang/Object"*, %"java/lang/Object"*)
declare void @"java/lang/Object_finalize()V"(%"java/lang/Object"*)
declare i1 @"java/lang/Object_equals(Ljava/lang/Object;)Z"(%"java/lang/Object"*, %"java/lang/Object")
declare void @"java/lang/Object_<init>()V"(%"java/lang/Object"*)
declare void @"java/lang/Object_wait0(J)V"(%"java/lang/Object"*, i64) nounwind
%"java/lang/Object_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)* }
%"java/lang/String_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)*, i32(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*)*, i8(%"java/lang/String"*)*, %java_Array(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup")*, %"java/lang/Object"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup")* }
%ConstructorAndInstanceMethods_vtable_type = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)* }
%"java/lang/Object_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)* }
%"java/lang/String_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)*, i32(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*)*, i8(%"java/lang/String"*)*, %java_Array(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup"*)*, %"java/lang/Object"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup"*)* }
%ConstructorAndInstanceMethods_vtable_type = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)* }

%"java/util/stream/IntStream" = type opaque
declare i32 @__gxx_personality_v0(...)
Expand All @@ -27,7 +27,7 @@ declare void @llvm.memset.p0.i64(ptr,i8,i64,i1)

@ConstructorAndInstanceMethods_vtable_data = global %ConstructorAndInstanceMethods_vtable_type {
i32(%"java/lang/Object"*)* @"java/lang/Object_hashCode()I",
i1(%"java/lang/Object"*, %"java/lang/Object")* @"java/lang/Object_equals(Ljava/lang/Object;)Z",
i1(%"java/lang/Object"*, %"java/lang/Object"*)* @"java/lang/Object_equals(Ljava/lang/Object;)Z",
void(%"java/lang/Object"*)* @"java/lang/Object_finalize()V"
}

Expand Down Expand Up @@ -200,4 +200,4 @@ define i32 @"ConstructorAndInstanceMethods_main()I"() personality ptr @__gxx_per
ret i32 0
}

declare i32 @printf(%java_Array, ...) nounwind
declare i32 @printf(ptr, ...) nounwind
12 changes: 6 additions & 6 deletions src/test/resources/Conversions.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
declare void @"java/lang/Object_notifyAll()V"(%"java/lang/Object"*) nounwind
declare i32 @"java/lang/Object_hashCode()I"(%"java/lang/Object"*) nounwind
declare void @"java/lang/Object_notify()V"(%"java/lang/Object"*) nounwind
declare i1 @"java/lang/Object_equals(Ljava/lang/Object;)Z"(%"java/lang/Object"*, %"java/lang/Object"*)
declare void @"java/lang/Object_finalize()V"(%"java/lang/Object"*)
declare i1 @"java/lang/Object_equals(Ljava/lang/Object;)Z"(%"java/lang/Object"*, %"java/lang/Object")
declare void @"java/lang/Object_<init>()V"(%"java/lang/Object"*)
declare void @"java/lang/Object_wait0(J)V"(%"java/lang/Object"*, i64) nounwind
%"java/lang/Object_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)* }
%"java/lang/String_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)*, i32(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*)*, i8(%"java/lang/String"*)*, %java_Array(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup")*, %"java/lang/Object"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup")* }
%Conversions_vtable_type = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)* }
%"java/lang/Object_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)* }
%"java/lang/String_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)*, i32(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*)*, i8(%"java/lang/String"*)*, %java_Array(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup"*)*, %"java/lang/Object"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup"*)* }
%Conversions_vtable_type = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)* }

%"java/util/stream/IntStream" = type opaque
declare i32 @__gxx_personality_v0(...)
Expand All @@ -27,7 +27,7 @@ declare void @llvm.memset.p0.i64(ptr,i8,i64,i1)

@Conversions_vtable_data = global %Conversions_vtable_type {
i32(%"java/lang/Object"*)* @"java/lang/Object_hashCode()I",
i1(%"java/lang/Object"*, %"java/lang/Object")* @"java/lang/Object_equals(Ljava/lang/Object;)Z",
i1(%"java/lang/Object"*, %"java/lang/Object"*)* @"java/lang/Object_equals(Ljava/lang/Object;)Z",
void(%"java/lang/Object"*)* @"java/lang/Object_finalize()V"
}

Expand Down Expand Up @@ -450,4 +450,4 @@ label1:
unreachable
}

declare i32 @printf(%java_Array, ...) nounwind
declare i32 @printf(ptr, ...) nounwind
2 changes: 1 addition & 1 deletion src/test/resources/CustomException.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

declare void @"java/lang/Exception_<init>()V"(%"java/lang/Exception"*)
%"java/lang/Exception_vtable_type" = type { }
%"java/lang/String_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object")*, void(%"java/lang/Object"*)*, i32(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*)*, i8(%"java/lang/String"*)*, %java_Array(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup")*, %"java/lang/Object"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup")* }
%"java/lang/String_vtable_type" = type { i32(%"java/lang/Object"*)*, i1(%"java/lang/Object"*, %"java/lang/Object"*)*, void(%"java/lang/Object"*)*, i32(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*)*, i8(%"java/lang/String"*)*, %java_Array(%"java/lang/String"*)*, i1(%"java/lang/String"*)*, %"java/lang/String"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup"*)*, %"java/lang/Object"(%"java/lang/String"*, %"java/lang/invoke/MethodHandles$Lookup"*)* }
%CustomException_vtable_type = type { i32(%CustomException*)* }

%"java/util/stream/IntStream" = type opaque
Expand Down
Loading

0 comments on commit 831f67a

Please sign in to comment.