< prev index next >
src/jdk.jextract/share/classes/com/sun/tools/jextract/AsmCodeFactory.java
Print this page
*** 43,82 ****
* file.
*/
final class AsmCodeFactory extends CodeFactory {
private static final String ANNOTATION_PKG_PREFIX = "Ljava/nicl/metadata/";
private static final String ARRAY = ANNOTATION_PKG_PREFIX + "Array;";
! private static final String C = ANNOTATION_PKG_PREFIX + "C;";
! private static final String CALLING_CONVENTION = ANNOTATION_PKG_PREFIX + "CallingConvention;";
private static final String NATIVE_HEADER = ANNOTATION_PKG_PREFIX + "NativeHeader;";
private static final String NATIVE_TYPE = ANNOTATION_PKG_PREFIX + "NativeType;";
private static final String OFFSET = ANNOTATION_PKG_PREFIX + "Offset;";
private final Context ctx;
private final ClassWriter global_cw;
private final String internal_name;
private final HeaderFile owner;
private final Map<String, byte[]> types;
private final HashSet<String> handledMacros = new HashSet<>();
private final Logger logger = Logger.getLogger(getClass().getPackage().getName());
AsmCodeFactory(Context ctx, HeaderFile header) {
this.ctx = ctx;
logger.info(() -> "Instantiate AsmCodeFactory for " + header.path);
this.owner = header;
this.internal_name = Utils.toInternalName(owner.pkgName, owner.clsName);
this.global_cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
this.types = new HashMap<>();
- init();
- }
-
- private void init() {
global_cw.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE,
internal_name,
null, "java/lang/Object", null);
AnnotationVisitor av = global_cw.visitAnnotation(NATIVE_HEADER, true);
! av.visit("headerPath", owner.path.toAbsolutePath().toString());
if (owner.libraries != null && !owner.libraries.isEmpty()) {
AnnotationVisitor libNames = av.visitArray("libraries");
for (String name : owner.libraries) {
libNames.visit(null, name);
}
--- 43,82 ----
* file.
*/
final class AsmCodeFactory extends CodeFactory {
private static final String ANNOTATION_PKG_PREFIX = "Ljava/nicl/metadata/";
private static final String ARRAY = ANNOTATION_PKG_PREFIX + "Array;";
! private static final String NATIVE_CALLBACK = ANNOTATION_PKG_PREFIX + "NativeCallback;";
private static final String NATIVE_HEADER = ANNOTATION_PKG_PREFIX + "NativeHeader;";
+ private static final String NATIVE_LOCATION = ANNOTATION_PKG_PREFIX + "NativeLocation;";
private static final String NATIVE_TYPE = ANNOTATION_PKG_PREFIX + "NativeType;";
private static final String OFFSET = ANNOTATION_PKG_PREFIX + "Offset;";
private final Context ctx;
private final ClassWriter global_cw;
private final String internal_name;
private final HeaderFile owner;
private final Map<String, byte[]> types;
private final HashSet<String> handledMacros = new HashSet<>();
private final Logger logger = Logger.getLogger(getClass().getPackage().getName());
+ private final StringBuilder headerDeclarations = new StringBuilder();
AsmCodeFactory(Context ctx, HeaderFile header) {
this.ctx = ctx;
logger.info(() -> "Instantiate AsmCodeFactory for " + header.path);
this.owner = header;
this.internal_name = Utils.toInternalName(owner.pkgName, owner.clsName);
this.global_cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
this.types = new HashMap<>();
global_cw.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE,
internal_name,
null, "java/lang/Object", null);
+ }
+
+ private void generateNativeHeader() {
AnnotationVisitor av = global_cw.visitAnnotation(NATIVE_HEADER, true);
! av.visit("path", owner.path.toAbsolutePath().toString());
if (owner.libraries != null && !owner.libraries.isEmpty()) {
AnnotationVisitor libNames = av.visitArray("libraries");
for (String name : owner.libraries) {
libNames.visit(null, name);
}
*** 87,108 ****
libPaths.visit(null, path);
}
libPaths.visitEnd();
}
}
av.visitEnd();
}
private void handleException(Exception ex) {
ctx.err.println(Main.format("cannot.write.class.file", owner.pkgName + "." + owner.clsName, ex));
if (Main.DEBUG) {
ex.printStackTrace(ctx.err);
}
}
! private void annotateC(ClassVisitor cw, Cursor dcl) {
! AnnotationVisitor av = cw.visitAnnotation(C, true);
SourceLocation src = dcl.getSourceLocation();
SourceLocation.Location loc = src.getFileLocation();
Path p = loc.path();
av.visit("file", p == null ? "builtin" : p.toAbsolutePath().toString());
av.visit("line", loc.line());
--- 87,109 ----
libPaths.visit(null, path);
}
libPaths.visitEnd();
}
}
+ av.visit("declarations", headerDeclarations.toString());
av.visitEnd();
}
private void handleException(Exception ex) {
ctx.err.println(Main.format("cannot.write.class.file", owner.pkgName + "." + owner.clsName, ex));
if (Main.DEBUG) {
ex.printStackTrace(ctx.err);
}
}
! private void annotateNativeLocation(ClassVisitor cw, Cursor dcl) {
! AnnotationVisitor av = cw.visitAnnotation(NATIVE_LOCATION, true);
SourceLocation src = dcl.getSourceLocation();
SourceLocation.Location loc = src.getFileLocation();
Path p = loc.path();
av.visit("file", p == null ? "builtin" : p.toAbsolutePath().toString());
av.visit("line", loc.line());
*** 132,142 ****
JType jt = owner.globalLookup(t);
assert (jt != null);
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, fieldName + "$get",
"()" + jt.getDescriptor(), "()" + jt.getSignature(), null);
! AnnotationVisitor av = mv.visitAnnotation(C, true);
SourceLocation src = c.getSourceLocation();
SourceLocation.Location loc = src.getFileLocation();
Path p = loc.path();
av.visit("file", p == null ? "builtin" : p.toAbsolutePath().toString());
av.visit("line", loc.line());
--- 133,143 ----
JType jt = owner.globalLookup(t);
assert (jt != null);
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, fieldName + "$get",
"()" + jt.getDescriptor(), "()" + jt.getSignature(), null);
! AnnotationVisitor av = mv.visitAnnotation(NATIVE_LOCATION, true);
SourceLocation src = c.getSourceLocation();
SourceLocation.Location loc = src.getFileLocation();
Path p = loc.path();
av.visit("file", p == null ? "builtin" : p.toAbsolutePath().toString());
av.visit("line", loc.line());
*** 145,155 ****
av.visitEnd();
av = mv.visitAnnotation(NATIVE_TYPE, true);
av.visit("layout", Utils.getLayout(t));
av.visit("ctype", t.spelling());
- av.visit("size", t.size());
av.visit("name", fieldName);
av.visitEnd();
if (t.kind() == TypeKind.ConstantArray || t.kind() == TypeKind.IncompleteArray) {
logger.finer(() -> "Array field " + fieldName + ", type " + t.kind().name());
--- 146,155 ----
*** 210,225 ****
global_cw.visitInnerClass(name, internal_name, intf, ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(V1_8, ACC_PUBLIC /*| ACC_STATIC*/ | ACC_INTERFACE | ACC_ABSTRACT,
name, "Ljava/lang/Object;Ljava/nicl/types/Struct<L" + name + ";>;",
"java/lang/Object", new String[] {"java/nicl/types/Struct"});
! annotateC(cw, cursor);
AnnotationVisitor av = cw.visitAnnotation(NATIVE_TYPE, true);
av.visit("layout", Utils.getLayout(t));
av.visit("ctype", t.spelling());
av.visit("size", t.size());
- av.visit("isRecordType", true);
av.visitEnd();
cw.visitInnerClass(name, internal_name, intf, ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);
// fields
Printer dbg = new Printer();
--- 210,224 ----
global_cw.visitInnerClass(name, internal_name, intf, ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(V1_8, ACC_PUBLIC /*| ACC_STATIC*/ | ACC_INTERFACE | ACC_ABSTRACT,
name, "Ljava/lang/Object;Ljava/nicl/types/Struct<L" + name + ";>;",
"java/lang/Object", new String[] {"java/nicl/types/Struct"});
! annotateNativeLocation(cw, cursor);
AnnotationVisitor av = cw.visitAnnotation(NATIVE_TYPE, true);
av.visit("layout", Utils.getLayout(t));
av.visit("ctype", t.spelling());
av.visit("size", t.size());
av.visitEnd();
cw.visitInnerClass(name, internal_name, intf, ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);
// fields
Printer dbg = new Printer();
*** 267,277 ****
ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE | ACC_ANNOTATION);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
String[] superAnno = { "java/lang/annotation/Annotation" };
cw.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE | ACC_ANNOTATION,
name, null, "java/lang/Object", superAnno);
! annotateC(cw, dcl);
Type t = dcl.type().canonicalType();
AnnotationVisitor av = cw.visitAnnotation(NATIVE_TYPE, true);
av.visit("layout", Utils.getLayout(t));
av.visit("ctype", t.spelling());
av.visit("size", t.size());
--- 266,276 ----
ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE | ACC_ANNOTATION);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
String[] superAnno = { "java/lang/annotation/Annotation" };
cw.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE | ACC_ANNOTATION,
name, null, "java/lang/Object", superAnno);
! annotateNativeLocation(cw, dcl);
Type t = dcl.type().canonicalType();
AnnotationVisitor av = cw.visitAnnotation(NATIVE_TYPE, true);
av.visit("layout", Utils.getLayout(t));
av.visit("ctype", t.spelling());
av.visit("size", t.size());
*** 308,330 ****
cw.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE,
name, null, "java/lang/Object", null);
AnnotationVisitor av = cw.visitAnnotation(
"Ljava/lang/FunctionalInterface;", true);
av.visitEnd();
cw.visitInnerClass(name, internal_name, intf, ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);
// add the method
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, "fn",
fn.getDescriptor(), fn.getSignature(), null);
- av = mv.visitAnnotation(NATIVE_TYPE, true);
- av.visit("layout", nDesc);
- av.visit("ctype", "N/A");
- av.visit("size", -1);
- av.visitEnd();
- // FIXME: We need calling convention
- av = mv.visitAnnotation(CALLING_CONVENTION, true);
- av.visit("value", jt2.getCallingConvention());
av.visitEnd();
mv.visitEnd();
// Write class
try {
--- 307,324 ----
cw.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE,
name, null, "java/lang/Object", null);
AnnotationVisitor av = cw.visitAnnotation(
"Ljava/lang/FunctionalInterface;", true);
av.visitEnd();
+ av = cw.visitAnnotation(NATIVE_CALLBACK, true);
+ av.visit("value", nDesc);
+ av.visitEnd();
cw.visitInnerClass(name, internal_name, intf, ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);
// add the method
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, "fn",
fn.getDescriptor(), fn.getSignature(), null);
av.visitEnd();
mv.visitEnd();
// Write class
try {
*** 353,383 ****
global_cw.visitInnerClass(name, internal_name, intf, ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE,
name, null, "java/lang/Object", null);
if (dcl != null) {
! annotateC(cw, dcl);
}
AnnotationVisitor av = cw.visitAnnotation(
"Ljava/lang/FunctionalInterface;", true);
av.visitEnd();
cw.visitInnerClass(name, internal_name, intf, ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);
// add the method
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, "fn",
fn.getDescriptor(), fn.getSignature(), null);
- if (dcl != null) {
- av = mv.visitAnnotation(NATIVE_TYPE, true);
- Type t = dcl.type().canonicalType();
- av.visit("layout", Utils.getLayout(t));
- av.visit("ctype", t.spelling());
- av.visit("size", t.size());
- av.visitEnd();
- av = mv.visitAnnotation(CALLING_CONVENTION, true);
- av.visit("value", t.getCallingConvention().value());
- av.visitEnd();
- }
mv.visitEnd();
// Write class
try {
writeClassFile(cw, owner.clsName + "$" + intf);
} catch (IOException ex) {
--- 347,372 ----
global_cw.visitInnerClass(name, internal_name, intf, ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE,
name, null, "java/lang/Object", null);
if (dcl != null) {
! annotateNativeLocation(cw, dcl);
}
AnnotationVisitor av = cw.visitAnnotation(
"Ljava/lang/FunctionalInterface;", true);
av.visitEnd();
+ if (dcl != null) {
+ av = cw.visitAnnotation(NATIVE_CALLBACK, true);
+ Type t = dcl.type().canonicalType();
+ av.visit("value", Utils.getLayout(t));
+ av.visitEnd();
+ }
cw.visitInnerClass(name, internal_name, intf, ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);
// add the method
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, "fn",
fn.getDescriptor(), fn.getSignature(), null);
mv.visitEnd();
// Write class
try {
writeClassFile(cw, owner.clsName + "$" + intf);
} catch (IOException ex) {
*** 410,439 ****
String name = dcl.getArgument(i).spelling();
final int tmp = i;
logger.finer(() -> " arg " + tmp + ": " + name);
mv.visitParameter(name, 0);
}
! AnnotationVisitor av = mv.visitAnnotation(C, true);
SourceLocation src = dcl.getSourceLocation();
SourceLocation.Location loc = src.getFileLocation();
Path p = loc.path();
av.visit("file", p == null ? "builtin" : p.toAbsolutePath().toString());
av.visit("line", loc.line());
av.visit("column", loc.column());
av.visit("USR", dcl.USR());
av.visitEnd();
av = mv.visitAnnotation(NATIVE_TYPE, true);
Type t = dcl.type();
! av.visit("layout", Utils.getLayout(t));
av.visit("ctype", t.spelling());
av.visit("name", dcl.spelling());
- av.visit("size", t.size());
- av.visitEnd();
- av = mv.visitAnnotation(CALLING_CONVENTION, true);
- av.visit("value", t.getCallingConvention().value());
av.visitEnd();
int idx = 0;
for (JType arg: fn.args) {
if (arg instanceof TypeAlias) {
TypeAlias alias = (TypeAlias) arg;
final int tmp = idx;
--- 399,430 ----
String name = dcl.getArgument(i).spelling();
final int tmp = i;
logger.finer(() -> " arg " + tmp + ": " + name);
mv.visitParameter(name, 0);
}
! AnnotationVisitor av = mv.visitAnnotation(NATIVE_LOCATION, true);
SourceLocation src = dcl.getSourceLocation();
SourceLocation.Location loc = src.getFileLocation();
Path p = loc.path();
av.visit("file", p == null ? "builtin" : p.toAbsolutePath().toString());
av.visit("line", loc.line());
av.visit("column", loc.column());
av.visit("USR", dcl.USR());
av.visitEnd();
av = mv.visitAnnotation(NATIVE_TYPE, true);
Type t = dcl.type();
! String layout = Utils.getLayout(t);
! av.visit("layout", layout);
av.visit("ctype", t.spelling());
av.visit("name", dcl.spelling());
av.visitEnd();
+ headerDeclarations.append(dcl.spelling());
+ headerDeclarations.append('=');
+ headerDeclarations.append(layout);
+ headerDeclarations.append(' ');
+
int idx = 0;
for (JType arg: fn.args) {
if (arg instanceof TypeAlias) {
TypeAlias alias = (TypeAlias) arg;
final int tmp = idx;
*** 656,666 ****
}
String sig = jdk.internal.org.objectweb.asm.Type.getMethodDescriptor(jdk.internal.org.objectweb.asm.Type.getType(l.type().getTypeClass()));
MethodVisitor mv = global_cw.visitMethod(flags, macroName, sig, sig, null);
! AnnotationVisitor av = mv.visitAnnotation(C, true);
SourceLocation src = cursor.getSourceLocation();
SourceLocation.Location loc = src.getFileLocation();
Path p = loc.path();
av.visit("file", p == null ? "builtin" : p.toAbsolutePath().toString());
av.visit("line", loc.line());
--- 647,657 ----
}
String sig = jdk.internal.org.objectweb.asm.Type.getMethodDescriptor(jdk.internal.org.objectweb.asm.Type.getType(l.type().getTypeClass()));
MethodVisitor mv = global_cw.visitMethod(flags, macroName, sig, sig, null);
! AnnotationVisitor av = mv.visitAnnotation(NATIVE_LOCATION, true);
SourceLocation src = cursor.getSourceLocation();
SourceLocation.Location loc = src.getFileLocation();
Path p = loc.path();
av.visit("file", p == null ? "builtin" : p.toAbsolutePath().toString());
av.visit("line", loc.line());
*** 689,698 ****
--- 680,690 ----
return this;
}
@Override
protected void produce() {
+ generateNativeHeader();
try {
writeClassFile(global_cw, owner.clsName);
} catch (IOException ex) {
handleException(ex);
}
< prev index next >