< prev index next >

src/jdk.jextract/share/classes/com/sun/tools/jextract/AsmCodeFactory.java

Print this page




  74 
  75     private final Context ctx;
  76     private final ClassWriter global_cw;
  77     // to avoid duplicate generation of methods, field accessors
  78     private final Set<String> global_methods = new HashSet<>();
  79     private final Set<String> global_fields = new HashSet<>();
  80     private final String internal_name;
  81     private final HeaderFile owner;
  82     private final Map<String, byte[]> types;
  83     private final Logger logger = Logger.getLogger(getClass().getPackage().getName());
  84     private final List<String> headerDeclarations = new ArrayList<>();
  85     private transient boolean built = false;
  86 
  87     AsmCodeFactory(Context ctx, HeaderFile header) {
  88         this.ctx = ctx;
  89         logger.info(() -> "Instantiate AsmCodeFactory for " + header.path);
  90         this.owner = header;
  91         this.internal_name = Utils.toInternalName(owner.pkgName, owner.clsName);
  92         this.global_cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
  93         this.types = new HashMap<>();
  94         global_cw.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE,
  95                 internal_name,
  96                 null, "java/lang/Object", null);




  97     }
  98 
  99     private void generateNativeHeader() {
 100         generateMacros();
 101         AnnotationVisitor av = global_cw.visitAnnotation(NATIVE_HEADER, true);
 102         av.visit("path", owner.path.toAbsolutePath().toString());
 103         if (owner.libraries != null && !owner.libraries.isEmpty()) {
 104             AnnotationVisitor libNames = av.visitArray("libraries");
 105             for (String name : owner.libraries) {
 106                 libNames.visit(null, name);
 107             }
 108             libNames.visitEnd();
 109             if (owner.libraryPaths != null && !owner.libraryPaths.isEmpty()) {
 110                 AnnotationVisitor libPaths = av.visitArray("libraryPaths");
 111                 for (String path : owner.libraryPaths) {
 112                     libPaths.visit(null, path);
 113                 }
 114                 libPaths.visitEnd();
 115             }
 116         }


 540                 } else if (macroType.equals(double.class)) {
 541                     mv.visitInsn(DRETURN);
 542                 } else if (macroType.equals(String.class)) {
 543                     mv.visitInsn(ARETURN);
 544                 }
 545                 mv.visitMaxs(0, 0);
 546                 mv.visitEnd();
 547             } else {
 548                 logger.fine(() -> "Skipping unrecognized object-like macro " + macro.name());
 549             }
 550         }
 551 
 552         return this;
 553     }
 554 
 555     protected synchronized void produce() {
 556         if (built) {
 557             throw new IllegalStateException("Produce is called multiple times");
 558         }
 559         built = true;



 560         generateNativeHeader();
 561         try {
 562             writeClassFile(global_cw, owner.clsName);
 563         } catch (IOException ex) {
 564             handleException(ex);
 565         }
 566     }
 567 
 568     protected Map<String, byte[]> collect() {
 569         // Ensure classes are produced
 570         if (!built) produce();
 571         HashMap<String, byte[]> rv = new HashMap<>();
 572         // Not copying byte[] for efficiency, perhaps not a safe idea though
 573         if (owner.pkgName.isEmpty()) {
 574             types.forEach((clsName, bytecodes) -> {
 575                 rv.put(clsName, bytecodes);
 576             });
 577         } else {
 578             types.forEach((clsName, bytecodes) -> {
 579                 rv.put(owner.pkgName + "." + clsName, bytecodes);


  74 
  75     private final Context ctx;
  76     private final ClassWriter global_cw;
  77     // to avoid duplicate generation of methods, field accessors
  78     private final Set<String> global_methods = new HashSet<>();
  79     private final Set<String> global_fields = new HashSet<>();
  80     private final String internal_name;
  81     private final HeaderFile owner;
  82     private final Map<String, byte[]> types;
  83     private final Logger logger = Logger.getLogger(getClass().getPackage().getName());
  84     private final List<String> headerDeclarations = new ArrayList<>();
  85     private transient boolean built = false;
  86 
  87     AsmCodeFactory(Context ctx, HeaderFile header) {
  88         this.ctx = ctx;
  89         logger.info(() -> "Instantiate AsmCodeFactory for " + header.path);
  90         this.owner = header;
  91         this.internal_name = Utils.toInternalName(owner.pkgName, owner.clsName);
  92         this.global_cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
  93         this.types = new HashMap<>();
  94     }
  95 
  96     private String[] getSuperInterfaces() {
  97         String[] interfaces = owner.getIncludedFiles().
  98             map(hf -> Utils.toInternalName(hf.pkgName, hf.clsName)).
  99             toArray(String[]::new);
 100         return interfaces.length != 0 ? interfaces : null;
 101     }
 102 
 103     private void generateNativeHeader() {
 104         generateMacros();
 105         AnnotationVisitor av = global_cw.visitAnnotation(NATIVE_HEADER, true);
 106         av.visit("path", owner.path.toAbsolutePath().toString());
 107         if (owner.libraries != null && !owner.libraries.isEmpty()) {
 108             AnnotationVisitor libNames = av.visitArray("libraries");
 109             for (String name : owner.libraries) {
 110                 libNames.visit(null, name);
 111             }
 112             libNames.visitEnd();
 113             if (owner.libraryPaths != null && !owner.libraryPaths.isEmpty()) {
 114                 AnnotationVisitor libPaths = av.visitArray("libraryPaths");
 115                 for (String path : owner.libraryPaths) {
 116                     libPaths.visit(null, path);
 117                 }
 118                 libPaths.visitEnd();
 119             }
 120         }


 544                 } else if (macroType.equals(double.class)) {
 545                     mv.visitInsn(DRETURN);
 546                 } else if (macroType.equals(String.class)) {
 547                     mv.visitInsn(ARETURN);
 548                 }
 549                 mv.visitMaxs(0, 0);
 550                 mv.visitEnd();
 551             } else {
 552                 logger.fine(() -> "Skipping unrecognized object-like macro " + macro.name());
 553             }
 554         }
 555 
 556         return this;
 557     }
 558 
 559     protected synchronized void produce() {
 560         if (built) {
 561             throw new IllegalStateException("Produce is called multiple times");
 562         }
 563         built = true;
 564         global_cw.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE,
 565                 internal_name,
 566                 null, "java/lang/Object", getSuperInterfaces());
 567         generateNativeHeader();
 568         try {
 569             writeClassFile(global_cw, owner.clsName);
 570         } catch (IOException ex) {
 571             handleException(ex);
 572         }
 573     }
 574 
 575     protected Map<String, byte[]> collect() {
 576         // Ensure classes are produced
 577         if (!built) produce();
 578         HashMap<String, byte[]> rv = new HashMap<>();
 579         // Not copying byte[] for efficiency, perhaps not a safe idea though
 580         if (owner.pkgName.isEmpty()) {
 581             types.forEach((clsName, bytecodes) -> {
 582                 rv.put(clsName, bytecodes);
 583             });
 584         } else {
 585             types.forEach((clsName, bytecodes) -> {
 586                 rv.put(owner.pkgName + "." + clsName, bytecodes);
< prev index next >