--- old/src/jdk.compiler/share/classes/com/sun/tools/javah/LLNI.java 2017-11-09 15:06:37.873817535 -0800
+++ /dev/null 2017-01-21 22:54:52.877512947 -0800
@@ -1,685 +0,0 @@
-/*
- * Copyright (c) 2002, 2014, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.javah;
-
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
-import java.util.Set;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVisitor;
-import javax.lang.model.util.ElementFilter;
-import javax.lang.model.util.SimpleTypeVisitor9;
-
-import com.sun.tools.javac.util.DefinedBy;
-import com.sun.tools.javac.util.DefinedBy.Api;
-
-/*
- *
This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.
- *
- * @author Sucheta Dambalkar(Revised)
- */
-public class LLNI extends Gen {
-
- protected final char innerDelim = '$'; /* For inner classes */
- protected Set doneHandleTypes;
- List fields;
- List methods;
- private boolean doubleAlign;
- private int padFieldNum = 0;
-
- LLNI(boolean doubleAlign, Util util) {
- super(util);
- this.doubleAlign = doubleAlign;
- }
-
- protected String getIncludes() {
- return "";
- }
-
- protected void write(OutputStream o, TypeElement clazz) throws Util.Exit {
- try {
- String cname = mangleClassName(clazz.getQualifiedName().toString());
- PrintWriter pw = wrapWriter(o);
- fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
- methods = ElementFilter.methodsIn(clazz.getEnclosedElements());
- generateDeclsForClass(pw, clazz, cname);
- // FIXME check if errors occurred on the PrintWriter and throw exception if so
- } catch (TypeSignature.SignatureException e) {
- util.error("llni.sigerror", e.getMessage());
- }
- }
-
- protected void generateDeclsForClass(PrintWriter pw,
- TypeElement clazz, String cname)
- throws TypeSignature.SignatureException, Util.Exit {
- doneHandleTypes = new HashSet<>();
- /* The following handle types are predefined in "typedefs.h". Suppress
- inclusion in the output by generating them "into the blue" here. */
- genHandleType(null, "java.lang.Class");
- genHandleType(null, "java.lang.ClassLoader");
- genHandleType(null, "java.lang.Object");
- genHandleType(null, "java.lang.String");
- genHandleType(null, "java.lang.Thread");
- genHandleType(null, "java.lang.ThreadGroup");
- genHandleType(null, "java.lang.Throwable");
-
- pw.println("/* LLNI Header for class " + clazz.getQualifiedName() + " */" + lineSep);
- pw.println("#ifndef _Included_" + cname);
- pw.println("#define _Included_" + cname);
- pw.println("#include \"typedefs.h\"");
- pw.println("#include \"llni.h\"");
- pw.println("#include \"jni.h\"" + lineSep);
-
- forwardDecls(pw, clazz);
- structSectionForClass(pw, clazz, cname);
- methodSectionForClass(pw, clazz, cname);
- pw.println("#endif");
- }
-
- protected void genHandleType(PrintWriter pw, String clazzname) {
- String cname = mangleClassName(clazzname);
- if (!doneHandleTypes.contains(cname)) {
- doneHandleTypes.add(cname);
- if (pw != null) {
- pw.println("#ifndef DEFINED_" + cname);
- pw.println(" #define DEFINED_" + cname);
- pw.println(" GEN_HANDLE_TYPES(" + cname + ");");
- pw.println("#endif" + lineSep);
- }
- }
- }
-
- protected String mangleClassName(String s) {
- return s.replace('.', '_')
- .replace('/', '_')
- .replace(innerDelim, '_');
- }
-
- protected void forwardDecls(PrintWriter pw, TypeElement clazz)
- throws TypeSignature.SignatureException {
- TypeElement object = elems.getTypeElement("java.lang.Object");
- if (clazz.equals(object))
- return;
-
- genHandleType(pw, clazz.getQualifiedName().toString());
- TypeElement superClass = (TypeElement) (types.asElement(clazz.getSuperclass()));
-
- if (superClass != null) {
- String superClassName = superClass.getQualifiedName().toString();
- forwardDecls(pw, superClass);
- }
-
- for (VariableElement field: fields) {
-
- if (!field.getModifiers().contains(Modifier.STATIC)) {
- TypeMirror t = types.erasure(field.asType());
- TypeSignature newTypeSig = new TypeSignature(elems);
- String tname = newTypeSig.qualifiedTypeName(t);
- String sig = newTypeSig.getTypeSignature(tname);
-
- if (sig.charAt(0) != '[')
- forwardDeclsFromSig(pw, sig);
- }
- }
-
- for (ExecutableElement method: methods) {
-
- if (method.getModifiers().contains(Modifier.NATIVE)) {
- TypeMirror retType = types.erasure(method.getReturnType());
- String typesig = signature(method);
- TypeSignature newTypeSig = new TypeSignature(elems);
- String sig = newTypeSig.getTypeSignature(typesig, retType);
-
- if (sig.charAt(0) != '[')
- forwardDeclsFromSig(pw, sig);
-
- }
- }
- }
-
- protected void forwardDeclsFromSig(PrintWriter pw, String sig) {
- int len = sig.length();
- int i = sig.charAt(0) == '(' ? 1 : 0;
-
- /* Skip the initial "(". */
- while (i < len) {
- if (sig.charAt(i) == 'L') {
- int j = i + 1;
- while (sig.charAt(j) != ';') j++;
- genHandleType(pw, sig.substring(i + 1, j));
- i = j + 1;
- } else {
- i++;
- }
- }
- }
-
- protected void structSectionForClass(PrintWriter pw,
- TypeElement jclazz, String cname) {
-
- String jname = jclazz.getQualifiedName().toString();
-
- if (cname.equals("java_lang_Object")) {
- pw.println("/* struct java_lang_Object is defined in typedefs.h. */");
- pw.println();
- return;
- }
- pw.println("#if !defined(__i386)");
- pw.println("#pragma pack(4)");
- pw.println("#endif");
- pw.println();
- pw.println("struct " + cname + " {");
- pw.println(" ObjHeader h;");
- pw.print(fieldDefs(jclazz, cname));
-
- if (jname.equals("java.lang.Class"))
- pw.println(" Class *LLNI_mask(cClass);" +
- " /* Fake field; don't access (see oobj.h) */");
- pw.println("};" + lineSep + lineSep + "#pragma pack()");
- pw.println();
- return;
- }
-
- private static class FieldDefsRes {
- public String className; /* Name of the current class. */
- public FieldDefsRes parent;
- public String s;
- public int byteSize;
- public boolean bottomMost;
- public boolean printedOne = false;
-
- FieldDefsRes(TypeElement clazz, FieldDefsRes parent, boolean bottomMost) {
- this.className = clazz.getQualifiedName().toString();
- this.parent = parent;
- this.bottomMost = bottomMost;
- int byteSize = 0;
- if (parent == null) this.s = "";
- else this.s = parent.s;
- }
- }
-
- /* Returns "true" iff added a field. */
- private boolean doField(FieldDefsRes res, VariableElement field,
- String cname, boolean padWord) {
-
- String fieldDef = addStructMember(field, cname, padWord);
- if (fieldDef != null) {
- if (!res.printedOne) { /* add separator */
- if (res.bottomMost) {
- if (res.s.length() != 0)
- res.s = res.s + " /* local members: */" + lineSep;
- } else {
- res.s = res.s + " /* inherited members from " +
- res.className + ": */" + lineSep;
- }
- res.printedOne = true;
- }
- res.s = res.s + fieldDef;
- return true;
- }
-
- // Otherwise.
- return false;
- }
-
- private int doTwoWordFields(FieldDefsRes res, TypeElement clazz,
- int offset, String cname, boolean padWord) {
- boolean first = true;
- List fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
-
- for (VariableElement field: fields) {
- TypeKind tk = field.asType().getKind();
- boolean twoWords = (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
- if (twoWords && doField(res, field, cname, first && padWord)) {
- offset += 8; first = false;
- }
- }
- return offset;
- }
-
- String fieldDefs(TypeElement clazz, String cname) {
- FieldDefsRes res = fieldDefs(clazz, cname, true);
- return res.s;
- }
-
- FieldDefsRes fieldDefs(TypeElement clazz, String cname,
- boolean bottomMost){
- FieldDefsRes res;
- int offset;
- boolean didTwoWordFields = false;
-
- TypeElement superclazz = (TypeElement) types.asElement(clazz.getSuperclass());
-
- if (superclazz != null) {
- String supername = superclazz.getQualifiedName().toString();
- res = new FieldDefsRes(clazz,
- fieldDefs(superclazz, cname, false),
- bottomMost);
- offset = res.parent.byteSize;
- } else {
- res = new FieldDefsRes(clazz, null, bottomMost);
- offset = 0;
- }
-
- List fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
-
- for (VariableElement field: fields) {
-
- if (doubleAlign && !didTwoWordFields && (offset % 8) == 0) {
- offset = doTwoWordFields(res, clazz, offset, cname, false);
- didTwoWordFields = true;
- }
-
- TypeKind tk = field.asType().getKind();
- boolean twoWords = (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
-
- if (!doubleAlign || !twoWords) {
- if (doField(res, field, cname, false)) offset += 4;
- }
-
- }
-
- if (doubleAlign && !didTwoWordFields) {
- if ((offset % 8) != 0) offset += 4;
- offset = doTwoWordFields(res, clazz, offset, cname, true);
- }
-
- res.byteSize = offset;
- return res;
- }
-
- /* OVERRIDE: This method handles instance fields */
- protected String addStructMember(VariableElement member, String cname,
- boolean padWord) {
- String res = null;
-
- if (member.getModifiers().contains(Modifier.STATIC)) {
- res = addStaticStructMember(member, cname);
- // if (res == null) /* JNI didn't handle it, print comment. */
- // res = " /* Inaccessible static: " + member + " */" + lineSep;
- } else {
- TypeMirror mt = types.erasure(member.asType());
- if (padWord) res = " java_int padWord" + padFieldNum++ + ";" + lineSep;
- res = " " + llniType(mt, false, false) + " " + llniFieldName(member);
- if (isLongOrDouble(mt)) res = res + "[2]";
- res = res + ";" + lineSep;
- }
- return res;
- }
-
- static private final boolean isWindows =
- System.getProperty("os.name").startsWith("Windows");
-
- /*
- * This method only handles static final fields.
- */
- protected String addStaticStructMember(VariableElement field, String cname) {
- String res = null;
- Object exp = null;
-
- if (!field.getModifiers().contains(Modifier.STATIC))
- return res;
- if (!field.getModifiers().contains(Modifier.FINAL))
- return res;
-
- exp = field.getConstantValue();
-
- if (exp != null) {
- /* Constant. */
-
- String cn = cname + "_" + field.getSimpleName();
- String suffix = null;
- long val = 0;
- /* Can only handle int, long, float, and double fields. */
- if (exp instanceof Byte
- || exp instanceof Short
- || exp instanceof Integer) {
- suffix = "L";
- val = ((Number)exp).intValue();
- }
- else if (exp instanceof Long) {
- // Visual C++ supports the i64 suffix, not LL
- suffix = isWindows ? "i64" : "LL";
- val = ((Long)exp).longValue();
- }
- else if (exp instanceof Float) suffix = "f";
- else if (exp instanceof Double) suffix = "";
- else if (exp instanceof Character) {
- suffix = "L";
- Character ch = (Character) exp;
- val = ((int) ch) & 0xffff;
- }
- if (suffix != null) {
- // Some compilers will generate a spurious warning
- // for the integer constants for Integer.MIN_VALUE
- // and Long.MIN_VALUE so we handle them specially.
- if ((suffix.equals("L") && (val == Integer.MIN_VALUE)) ||
- (suffix.equals("LL") && (val == Long.MIN_VALUE))) {
- res = " #undef " + cn + lineSep
- + " #define " + cn
- + " (" + (val + 1) + suffix + "-1)" + lineSep;
- } else if (suffix.equals("L") || suffix.endsWith("LL")) {
- res = " #undef " + cn + lineSep
- + " #define " + cn + " " + val + suffix + lineSep;
- } else {
- res = " #undef " + cn + lineSep
- + " #define " + cn + " " + exp + suffix + lineSep;
- }
- }
- }
- return res;
- }
-
- protected void methodSectionForClass(PrintWriter pw,
- TypeElement clazz, String cname)
- throws TypeSignature.SignatureException, Util.Exit {
- String methods = methodDecls(clazz, cname);
-
- if (methods.length() != 0) {
- pw.println("/* Native method declarations: */" + lineSep);
- pw.println("#ifdef __cplusplus");
- pw.println("extern \"C\" {");
- pw.println("#endif" + lineSep);
- pw.println(methods);
- pw.println("#ifdef __cplusplus");
- pw.println("}");
- pw.println("#endif");
- }
- }
-
- protected String methodDecls(TypeElement clazz, String cname)
- throws TypeSignature.SignatureException, Util.Exit {
-
- String res = "";
- for (ExecutableElement method: methods) {
- if (method.getModifiers().contains(Modifier.NATIVE))
- res = res + methodDecl(method, clazz, cname);
- }
- return res;
- }
-
- protected String methodDecl(ExecutableElement method,
- TypeElement clazz, String cname)
- throws TypeSignature.SignatureException, Util.Exit {
- String res = null;
-
- TypeMirror retType = types.erasure(method.getReturnType());
- String typesig = signature(method);
- TypeSignature newTypeSig = new TypeSignature(elems);
- String sig = newTypeSig.getTypeSignature(typesig, retType);
- boolean longName = needLongName(method, clazz);
-
- if (sig.charAt(0) != '(')
- util.error("invalid.method.signature", sig);
-
-
- res = "JNIEXPORT " + jniType(retType) + " JNICALL" + lineSep + jniMethodName(method, cname, longName)
- + "(JNIEnv *, " + cRcvrDecl(method, cname);
- List extends VariableElement> params = method.getParameters();
- List argTypes = new ArrayList<>();
- for (VariableElement p: params){
- argTypes.add(types.erasure(p.asType()));
- }
-
- /* It would have been nice to include the argument names in the
- declaration, but there seems to be a bug in the "BinaryField"
- class, causing the getArguments() method to return "null" for
- most (non-constructor) methods. */
- for (TypeMirror argType: argTypes)
- res = res + ", " + jniType(argType);
- res = res + ");" + lineSep;
- return res;
- }
-
- protected final boolean needLongName(ExecutableElement method,
- TypeElement clazz) {
- Name methodName = method.getSimpleName();
- for (ExecutableElement memberMethod: methods) {
- if ((memberMethod != method) &&
- memberMethod.getModifiers().contains(Modifier.NATIVE) &&
- (methodName.equals(memberMethod.getSimpleName())))
- return true;
- }
- return false;
- }
-
- protected final String jniMethodName(ExecutableElement method, String cname,
- boolean longName)
- throws TypeSignature.SignatureException {
- String res = "Java_" + cname + "_" + method.getSimpleName();
-
- if (longName) {
- TypeMirror mType = types.erasure(method.getReturnType());
- List extends VariableElement> params = method.getParameters();
- List argTypes = new ArrayList<>();
- for (VariableElement param: params) {
- argTypes.add(types.erasure(param.asType()));
- }
-
- res = res + "__";
- for (TypeMirror t: argTypes) {
- String tname = t.toString();
- TypeSignature newTypeSig = new TypeSignature(elems);
- String sig = newTypeSig.getTypeSignature(tname);
- res = res + nameToIdentifier(sig);
- }
- }
- return res;
- }
-
- // copied from JNI.java
- protected final String jniType(TypeMirror t) throws Util.Exit {
- TypeElement throwable = elems.getTypeElement("java.lang.Throwable");
- TypeElement jClass = elems.getTypeElement("java.lang.Class");
- TypeElement jString = elems.getTypeElement("java.lang.String");
- Element tclassDoc = types.asElement(t);
-
- switch (t.getKind()) {
- case ARRAY: {
- TypeMirror ct = ((ArrayType) t).getComponentType();
- switch (ct.getKind()) {
- case BOOLEAN: return "jbooleanArray";
- case BYTE: return "jbyteArray";
- case CHAR: return "jcharArray";
- case SHORT: return "jshortArray";
- case INT: return "jintArray";
- case LONG: return "jlongArray";
- case FLOAT: return "jfloatArray";
- case DOUBLE: return "jdoubleArray";
- case ARRAY:
- case DECLARED: return "jobjectArray";
- default: throw new Error(ct.toString());
- }
- }
-
- case VOID: return "void";
- case BOOLEAN: return "jboolean";
- case BYTE: return "jbyte";
- case CHAR: return "jchar";
- case SHORT: return "jshort";
- case INT: return "jint";
- case LONG: return "jlong";
- case FLOAT: return "jfloat";
- case DOUBLE: return "jdouble";
-
- case DECLARED: {
- if (tclassDoc.equals(jString))
- return "jstring";
- else if (types.isAssignable(t, throwable.asType()))
- return "jthrowable";
- else if (types.isAssignable(t, jClass.asType()))
- return "jclass";
- else
- return "jobject";
- }
- }
-
- util.bug("jni.unknown.type");
- return null; /* dead code. */
- }
-
- protected String llniType(TypeMirror t, boolean handleize, boolean longDoubleOK) {
- String res = null;
-
- switch (t.getKind()) {
- case ARRAY: {
- TypeMirror ct = ((ArrayType) t).getComponentType();
- switch (ct.getKind()) {
- case BOOLEAN: res = "IArrayOfBoolean"; break;
- case BYTE: res = "IArrayOfByte"; break;
- case CHAR: res = "IArrayOfChar"; break;
- case SHORT: res = "IArrayOfShort"; break;
- case INT: res = "IArrayOfInt"; break;
- case LONG: res = "IArrayOfLong"; break;
- case FLOAT: res = "IArrayOfFloat"; break;
- case DOUBLE: res = "IArrayOfDouble"; break;
- case ARRAY:
- case DECLARED: res = "IArrayOfRef"; break;
- default: throw new Error(ct.getKind() + " " + ct);
- }
- if (!handleize) res = "DEREFERENCED_" + res;
- break;
- }
-
- case VOID:
- res = "void";
- break;
-
- case BOOLEAN:
- case BYTE:
- case CHAR:
- case SHORT:
- case INT:
- res = "java_int" ;
- break;
-
- case LONG:
- res = longDoubleOK ? "java_long" : "val32 /* java_long */";
- break;
-
- case FLOAT:
- res = "java_float";
- break;
-
- case DOUBLE:
- res = longDoubleOK ? "java_double" : "val32 /* java_double */";
- break;
-
- case DECLARED:
- TypeElement e = (TypeElement) types.asElement(t);
- res = "I" + mangleClassName(e.getQualifiedName().toString());
- if (!handleize) res = "DEREFERENCED_" + res;
- break;
-
- default:
- throw new Error(t.getKind() + " " + t); // FIXME
- }
-
- return res;
- }
-
- protected final String cRcvrDecl(Element field, String cname) {
- return (field.getModifiers().contains(Modifier.STATIC) ? "jclass" : "jobject");
- }
-
- protected String maskName(String s) {
- return "LLNI_mask(" + s + ")";
- }
-
- protected String llniFieldName(VariableElement field) {
- return maskName(field.getSimpleName().toString());
- }
-
- protected final boolean isLongOrDouble(TypeMirror t) {
- TypeVisitor v = new SimpleTypeVisitor9() {
- @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean defaultAction(TypeMirror t, Void p){
- return false;
- }
- @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitArray(ArrayType t, Void p) {
- return visit(t.getComponentType(), p);
- }
- @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitPrimitive(PrimitiveType t, Void p) {
- TypeKind tk = t.getKind();
- return (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
- }
- };
- return v.visit(t, null);
- }
-
- /* Do unicode to ansi C identifier conversion.
- %%% This may not be right, but should be called more often. */
- protected final String nameToIdentifier(String name) {
- int len = name.length();
- StringBuilder buf = new StringBuilder(len);
- for (int i = 0; i < len; i++) {
- char c = name.charAt(i);
- if (isASCIILetterOrDigit(c))
- buf.append(c);
- else if (c == '/')
- buf.append('_');
- else if (c == '.')
- buf.append('_');
- else if (c == '_')
- buf.append("_1");
- else if (c == ';')
- buf.append("_2");
- else if (c == '[')
- buf.append("_3");
- else
- buf.append("_0" + ((int)c));
- }
- return new String(buf);
- }
-
- protected final boolean isASCIILetterOrDigit(char c) {
- if (((c >= 'A') && (c <= 'Z')) ||
- ((c >= 'a') && (c <= 'z')) ||
- ((c >= '0') && (c <= '9')))
- return true;
- else
- return false;
- }
-}
-