8327994: Update code gen in CallGeneratorHelper
Reviewed-by: mcimadamore
This commit is contained in:
parent
c434b79cff
commit
ac2f8e5af8
@ -22,9 +22,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.foreign.*;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
@ -188,7 +192,7 @@ public class CallGeneratorHelper extends NativeTestHelper {
|
||||
return elems.stream().map(p -> p.name().charAt(0) + "").collect(Collectors.joining());
|
||||
}
|
||||
|
||||
static void generateStructDecl(List<StructFieldType> fields) {
|
||||
private static void generateStructDecl(PrintStream out, List<StructFieldType> fields) {
|
||||
String structCode = sigCode(fields);
|
||||
List<String> fieldDecls = new ArrayList<>();
|
||||
for (int i = 0 ; i < fields.size() ; i++) {
|
||||
@ -196,58 +200,88 @@ public class CallGeneratorHelper extends NativeTestHelper {
|
||||
}
|
||||
String res = String.format("struct S_%s { %s };", structCode,
|
||||
fieldDecls.stream().collect(Collectors.joining(" ")));
|
||||
System.out.println(res);
|
||||
out.println(res);
|
||||
}
|
||||
|
||||
/* this can be used to generate the test header/implementation */
|
||||
public static void main(String[] args) {
|
||||
boolean header = args.length > 0 && args[0].equals("header");
|
||||
boolean upcall = args.length > 1 && args[1].equals("upcall");
|
||||
if (upcall) {
|
||||
generateUpcalls(header);
|
||||
} else {
|
||||
generateDowncalls(header);
|
||||
private static PrintStream printStream(String first) throws IOException {
|
||||
return new PrintStream(Files.newOutputStream(Path.of(first)));
|
||||
}
|
||||
|
||||
// This can be used to generate the test implementation.
|
||||
// From the test/jdk/java/foreign directory, run this class using:
|
||||
// java -cp <jtreg_home>\lib\testng-7.3.0.jar --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED ./CallGeneratorHelper.java
|
||||
// Copyright header has to be added manually, and on Windows line endings have to be changed from \r\n to just \n
|
||||
public static void main(String[] args) throws IOException {
|
||||
try (PrintStream shared = printStream("shared.h");
|
||||
PrintStream libTestDowncall = printStream("libTestDowncall.c");
|
||||
PrintStream libTestDowncallStack = printStream("libTestDowncallStack.c");
|
||||
PrintStream libTestUpcall = printStream("libTestUpcall.c");
|
||||
PrintStream libTestUpcallStack = printStream("libTestUpcallStack.c")) {
|
||||
generateShared(shared);
|
||||
generateDowncalls(libTestDowncall, false);
|
||||
generateDowncalls(libTestDowncallStack, true);
|
||||
generateUpcalls(libTestUpcall, false);
|
||||
generateUpcalls(libTestUpcallStack, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void generateDowncalls(boolean header) {
|
||||
if (header) {
|
||||
System.out.println(
|
||||
"#include \"export.h\"\n"
|
||||
);
|
||||
private static void generateShared(PrintStream out) {
|
||||
out.println("""
|
||||
#include "export.h"
|
||||
|
||||
for (int j = 1; j <= MAX_FIELDS; j++) {
|
||||
for (List<StructFieldType> fields : StructFieldType.perms(j)) {
|
||||
generateStructDecl(fields);
|
||||
}
|
||||
#ifdef __clang__
|
||||
#pragma clang optimize off
|
||||
#elif defined __GNUC__
|
||||
#pragma GCC optimize ("O0")
|
||||
#elif defined _MSC_BUILD
|
||||
#pragma optimize( "", off )
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
#pragma align (natural)
|
||||
#endif
|
||||
""");
|
||||
|
||||
for (int j = 1; j <= MAX_FIELDS; j++) {
|
||||
for (List<StructFieldType> fields : StructFieldType.perms(j)) {
|
||||
generateStructDecl(out, fields);
|
||||
}
|
||||
} else {
|
||||
System.out.println(
|
||||
"#include \"libh\"\n" +
|
||||
"#ifdef __clang__\n" +
|
||||
"#pragma clang optimize off\n" +
|
||||
"#elif defined __GNUC__\n" +
|
||||
"#pragma GCC optimize (\"O0\")\n" +
|
||||
"#elif defined _MSC_BUILD\n" +
|
||||
"#pragma optimize( \"\", off )\n" +
|
||||
"#endif\n"
|
||||
);
|
||||
}
|
||||
|
||||
out.print("""
|
||||
|
||||
#ifdef _AIX
|
||||
#pragma align (reset)
|
||||
#endif
|
||||
""");
|
||||
}
|
||||
|
||||
private static void generateDowncalls(PrintStream out, boolean stack) {
|
||||
out.println("#include \"shared.h\"\n");
|
||||
|
||||
for (Object[] downcall : functions()) {
|
||||
String fName = (String)downcall[0];
|
||||
Ret r = (Ret)downcall[1];
|
||||
String fName = (String)downcall[1];
|
||||
Ret r = (Ret)downcall[2];
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ParamType> ptypes = (List<ParamType>)downcall[2];
|
||||
List<ParamType> ptypes = (List<ParamType>)downcall[3];
|
||||
@SuppressWarnings("unchecked")
|
||||
List<StructFieldType> fields = (List<StructFieldType>)downcall[3];
|
||||
generateDowncallFunction(fName, r, ptypes, fields, header);
|
||||
List<StructFieldType> fields = (List<StructFieldType>)downcall[4];
|
||||
generateDowncallFunction(out, fName, r, ptypes, fields, stack);
|
||||
}
|
||||
}
|
||||
|
||||
static void generateDowncallFunction(String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean declOnly) {
|
||||
private static final List<String> stackParamTypes = Stream.concat(Stream.generate(() -> "long long").limit(8),
|
||||
Stream.generate(() -> "double").limit(8)).toList();
|
||||
private static final List<String> stackParamNames = IntStream.range(0, 16).mapToObj(i -> "pf" + i).toList();
|
||||
private static final List<String> stackParamDecls = IntStream.range(0, 16)
|
||||
.mapToObj(i -> stackParamTypes.get(i) + " " + stackParamNames.get(i)).toList();
|
||||
|
||||
private static void generateDowncallFunction(PrintStream out, String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean stack) {
|
||||
String retType = ret == Ret.VOID ? "void" : params.get(0).type(fields);
|
||||
List<String> paramDecls = new ArrayList<>();
|
||||
if (stack) {
|
||||
paramDecls.addAll(stackParamDecls);
|
||||
}
|
||||
for (int i = 0 ; i < params.size() ; i++) {
|
||||
paramDecls.add(String.format("%s p%d", params.get(i).type(fields), i));
|
||||
}
|
||||
@ -255,69 +289,55 @@ public class CallGeneratorHelper extends NativeTestHelper {
|
||||
"void" :
|
||||
paramDecls.stream().collect(Collectors.joining(", "));
|
||||
String body = ret == Ret.VOID ? "{ }" : "{ return p0; }";
|
||||
String res = String.format("EXPORT %s f%s(%s) %s", retType, fName,
|
||||
sig, declOnly ? ";" : body);
|
||||
System.out.println(res);
|
||||
String res = String.format("EXPORT %s %s%s(%s) %s", retType, stack ? "s" : "", fName,
|
||||
sig, body);
|
||||
out.println(res);
|
||||
}
|
||||
|
||||
static void generateUpcalls(boolean header) {
|
||||
if (header) {
|
||||
System.out.println(
|
||||
"#include \"export.h\"\n"
|
||||
);
|
||||
|
||||
for (int j = 1; j <= MAX_FIELDS; j++) {
|
||||
for (List<StructFieldType> fields : StructFieldType.perms(j)) {
|
||||
generateStructDecl(fields);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println(
|
||||
"#include \"libh\"\n" +
|
||||
"#ifdef __clang__\n" +
|
||||
"#pragma clang optimize off\n" +
|
||||
"#elif defined __GNUC__\n" +
|
||||
"#pragma GCC optimize (\"O0\")\n" +
|
||||
"#elif defined _MSC_BUILD\n" +
|
||||
"#pragma optimize( \"\", off )\n" +
|
||||
"#endif\n"
|
||||
);
|
||||
}
|
||||
private static void generateUpcalls(PrintStream out, boolean stack) {
|
||||
out.println("#include \"shared.h\"\n");
|
||||
|
||||
for (Object[] downcall : functions()) {
|
||||
String fName = (String)downcall[0];
|
||||
Ret r = (Ret)downcall[1];
|
||||
String fName = (String)downcall[1];
|
||||
Ret r = (Ret)downcall[2];
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ParamType> ptypes = (List<ParamType>)downcall[2];
|
||||
List<ParamType> ptypes = (List<ParamType>)downcall[3];
|
||||
@SuppressWarnings("unchecked")
|
||||
List<StructFieldType> fields = (List<StructFieldType>)downcall[3];
|
||||
generateUpcallFunction(fName, r, ptypes, fields, header);
|
||||
List<StructFieldType> fields = (List<StructFieldType>)downcall[4];
|
||||
generateUpcallFunction(out, fName, r, ptypes, fields, stack);
|
||||
}
|
||||
}
|
||||
|
||||
static void generateUpcallFunction(String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean declOnly) {
|
||||
private static void generateUpcallFunction(PrintStream out, String fName, Ret ret, List<ParamType> params, List<StructFieldType> fields, boolean stack) {
|
||||
String retType = ret == Ret.VOID ? "void" : params.get(0).type(fields);
|
||||
List<String> paramDecls = new ArrayList<>();
|
||||
if (stack) {
|
||||
paramDecls.addAll(stackParamDecls);
|
||||
}
|
||||
for (int i = 0 ; i < params.size() ; i++) {
|
||||
paramDecls.add(String.format("%s p%d", params.get(i).type(fields), i));
|
||||
}
|
||||
String paramNames = IntStream.range(0, params.size())
|
||||
.mapToObj(i -> "p" + i)
|
||||
.collect(Collectors.joining(","));
|
||||
Stream<String> prefixParamNames = stack ? stackParamNames.stream() : Stream.of();
|
||||
String paramNames = Stream.concat(prefixParamNames, IntStream.range(0, params.size())
|
||||
.mapToObj(i -> "p" + i))
|
||||
.collect(Collectors.joining(", "));
|
||||
String sig = paramDecls.isEmpty() ?
|
||||
"" :
|
||||
paramDecls.stream().collect(Collectors.joining(", ")) + ", ";
|
||||
String body = String.format(ret == Ret.VOID ? "{ cb(%s); }" : "{ return cb(%s); }", paramNames);
|
||||
List<String> paramTypes = params.stream().map(p -> p.type(fields)).collect(Collectors.toList());
|
||||
if (stack) {
|
||||
paramTypes.addAll(0, stackParamTypes);
|
||||
}
|
||||
String cbSig = paramTypes.isEmpty() ?
|
||||
"void" :
|
||||
paramTypes.stream().collect(Collectors.joining(", "));
|
||||
String cbParam = String.format("%s (*cb)(%s)",
|
||||
retType, cbSig);
|
||||
|
||||
String res = String.format("EXPORT %s %s(%s %s) %s", retType, fName,
|
||||
sig, cbParam, declOnly ? ";" : body);
|
||||
System.out.println(res);
|
||||
String res = String.format("EXPORT %s %s%s(%s %s) %s", retType, stack ? "s" : "", fName,
|
||||
sig, cbParam, body);
|
||||
out.println(res);
|
||||
}
|
||||
|
||||
//helper methods
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,8 @@
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
struct S_FFFF { float p0; float p1; float p2; float p3; };
|
||||
|
||||
typedef void (*writeback_t)(int,void*);
|
||||
|
||||
typedef struct {
|
||||
|
@ -119,7 +119,6 @@ struct S_PPI { void* p0; void* p1; int p2; };
|
||||
struct S_PPF { void* p0; void* p1; float p2; };
|
||||
struct S_PPD { void* p0; void* p1; double p2; };
|
||||
struct S_PPP { void* p0; void* p1; void* p2; };
|
||||
struct S_FFFF { float p0; float p1; float p2; float p3; };
|
||||
|
||||
#ifdef _AIX
|
||||
#pragma align (reset)
|
||||
|
Loading…
Reference in New Issue
Block a user