9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package com.sun.tools.jextract; 24 25 import java.foreign.Libraries; 26 import java.lang.invoke.MethodHandles; 27 import java.lang.invoke.MethodHandles.Lookup; 28 import java.lang.reflect.Method; 29 30 import jdk.internal.org.objectweb.asm.FieldVisitor; 31 import jdk.internal.org.objectweb.asm.ClassWriter; 32 import jdk.internal.org.objectweb.asm.MethodVisitor; 33 import jdk.internal.org.objectweb.asm.Type; 34 import com.sun.tools.jextract.tree.EnumTree; 35 import com.sun.tools.jextract.tree.FieldTree; 36 import com.sun.tools.jextract.tree.FunctionTree; 37 import com.sun.tools.jextract.tree.MacroTree; 38 import com.sun.tools.jextract.tree.VarTree; 39 40 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL; 41 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; 42 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE; 43 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC; 44 import static jdk.internal.org.objectweb.asm.Opcodes.CHECKCAST; 45 import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC; 46 import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD; 47 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE; 48 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC; 49 import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN; 121 } 122 } 123 124 @Override 125 public Boolean visitMacro(MacroTree macroTree, JType jt) { 126 if (super.visitMacro(macroTree, jt)) { 127 String name = macroTree.name(); 128 Object value = macroTree.value().get(); 129 logger.fine(() -> "Adding macro " + name); 130 Class<?> macroType = Utils.unboxIfNeeded(value.getClass()); 131 String sig = Type.getType(macroType).getDescriptor(); 132 FieldVisitor fv = cw.visitField(ACC_PUBLIC | ACC_STATIC, name, sig, null, value); 133 fv.visitEnd(); 134 return true; 135 } else { 136 return false; 137 } 138 } 139 140 @Override 141 protected synchronized void produce() { 142 super.produce(); 143 types.put(getSimpleClassName(), getClassBytes()); 144 } 145 146 // Internals only below this point 147 // not fully qualified 148 private String getSimpleClassName() { 149 return headerFile.clsName + STATICS_CLASS_NAME_SUFFIX; 150 } 151 152 private String getClassName() { 153 return headerClassName + STATICS_CLASS_NAME_SUFFIX; 154 } 155 156 // return the generated static forwarder class bytes 157 private byte[] getClassBytes() { 158 cw.visitEnd(); 159 return cw.toByteArray(); 160 } 161 162 // map each C enum constant as a static final field of the static forwarder class 163 private void addEnumConstant(FieldTree fieldTree) { 164 assert (fieldTree.isEnumConstant()); 165 String name = fieldTree.name(); 166 String desc = dict.lookup(fieldTree.type()).getDescriptor(); 167 if (desc.length() != 1) { 168 throw new AssertionError("expected single char descriptor: " + desc); 169 } 170 FieldVisitor fv = null; 171 switch (desc.charAt(0)) { 172 case 'J': 173 long lvalue = fieldTree.enumConstant().get(); 174 fv = cw.visitField(ACC_PUBLIC | ACC_STATIC, name, desc, null, lvalue); 175 break; 176 case 'I': 177 int ivalue = fieldTree.enumConstant().get().intValue(); 178 fv = cw.visitField(ACC_PUBLIC | ACC_STATIC, name, desc, null, ivalue); 179 break; 180 default: 181 throw new AssertionError("should not reach here"); 182 } 183 fv.visitEnd(); 184 } 185 186 // emit library interface static field and <clinit> initializer for that field | 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package com.sun.tools.jextract; 24 25 import java.foreign.Libraries; 26 import java.lang.invoke.MethodHandles; 27 import java.lang.invoke.MethodHandles.Lookup; 28 import java.lang.reflect.Method; 29 import java.util.Collections; 30 import java.util.HashMap; 31 import java.util.List; 32 import java.util.Map; 33 34 import com.sun.tools.jextract.tree.Tree; 35 import jdk.internal.org.objectweb.asm.FieldVisitor; 36 import jdk.internal.org.objectweb.asm.ClassWriter; 37 import jdk.internal.org.objectweb.asm.MethodVisitor; 38 import jdk.internal.org.objectweb.asm.Type; 39 import com.sun.tools.jextract.tree.EnumTree; 40 import com.sun.tools.jextract.tree.FieldTree; 41 import com.sun.tools.jextract.tree.FunctionTree; 42 import com.sun.tools.jextract.tree.MacroTree; 43 import com.sun.tools.jextract.tree.VarTree; 44 45 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL; 46 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; 47 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE; 48 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC; 49 import static jdk.internal.org.objectweb.asm.Opcodes.CHECKCAST; 50 import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC; 51 import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD; 52 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE; 53 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC; 54 import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN; 126 } 127 } 128 129 @Override 130 public Boolean visitMacro(MacroTree macroTree, JType jt) { 131 if (super.visitMacro(macroTree, jt)) { 132 String name = macroTree.name(); 133 Object value = macroTree.value().get(); 134 logger.fine(() -> "Adding macro " + name); 135 Class<?> macroType = Utils.unboxIfNeeded(value.getClass()); 136 String sig = Type.getType(macroType).getDescriptor(); 137 FieldVisitor fv = cw.visitField(ACC_PUBLIC | ACC_STATIC, name, sig, null, value); 138 fv.visitEnd(); 139 return true; 140 } else { 141 return false; 142 } 143 } 144 145 @Override 146 public Map<String, byte[]> generateNativeHeader(List<Tree> decls) { 147 Map<String, byte[]> results = new HashMap<>(); 148 results.putAll(super.generateNativeHeader(decls)); 149 results.put(getClassName(), getClassBytes()); 150 return Collections.unmodifiableMap(results); 151 } 152 153 // Internals only below this point 154 155 private String getClassName() { 156 return headerClassName + STATICS_CLASS_NAME_SUFFIX; 157 } 158 159 // return the generated static forwarder class bytes 160 private byte[] getClassBytes() { 161 cw.visitEnd(); 162 return cw.toByteArray(); 163 } 164 165 // map each C enum constant as a static final field of the static forwarder class 166 private void addEnumConstant(FieldTree fieldTree) { 167 assert (fieldTree.isEnumConstant()); 168 String name = fieldTree.name(); 169 String desc = headerFile.dictionary().lookup(fieldTree.type()).getDescriptor(); 170 if (desc.length() != 1) { 171 throw new AssertionError("expected single char descriptor: " + desc); 172 } 173 FieldVisitor fv = null; 174 switch (desc.charAt(0)) { 175 case 'J': 176 long lvalue = fieldTree.enumConstant().get(); 177 fv = cw.visitField(ACC_PUBLIC | ACC_STATIC, name, desc, null, lvalue); 178 break; 179 case 'I': 180 int ivalue = fieldTree.enumConstant().get().intValue(); 181 fv = cw.visitField(ACC_PUBLIC | ACC_STATIC, name, desc, null, ivalue); 182 break; 183 default: 184 throw new AssertionError("should not reach here"); 185 } 186 fv.visitEnd(); 187 } 188 189 // emit library interface static field and <clinit> initializer for that field |