src/share/classes/com/sun/tools/javah/LLNI.java

Tue, 13 Jan 2009 13:27:14 +0000

author
mcimadamore
date
Tue, 13 Jan 2009 13:27:14 +0000
changeset 184
905e151a185a
parent 1
9a66ca7c79fa
child 416
c287d51c57da
permissions
-rw-r--r--

6765045: Remove rawtypes warnings from langtools
Summary: Removed all occurrences of rawtypes warnings from langtools
Reviewed-by: jjg, bpatel

     1 /*
     2  * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    27 package com.sun.tools.javah;
    29 import java.io.File;
    30 import java.io.OutputStream;
    31 import java.io.PrintWriter;
    32 import java.util.Hashtable;
    33 import com.sun.javadoc.*;
    35  /*
    36   * @author  Sucheta Dambalkar(Revised)
    37   */
    38 public class LLNI extends Gen {
    40     protected final char  pathChar = File.separatorChar;
    41     protected final char  innerDelim = '$';     /* For inner classes */
    42     protected Hashtable<Object, Object>   doneHandleTypes;
    43     MemberDoc []fields;
    44     MemberDoc [] methods;
    45     private boolean       doubleAlign;
    46     private int           padFieldNum = 0;
    49     LLNI(boolean doubleAlign, RootDoc root) {
    50         super(root);
    51         this.doubleAlign = doubleAlign;
    52     }
    55     protected String getIncludes() {
    56         return "";
    57     }
    59     protected void write(OutputStream o, ClassDoc clazz)
    60         throws ClassNotFoundException {
    61         String cname     = mangleClassName(clazz.qualifiedName());
    62         PrintWriter pw   = wrapWriter(o);
    63         fields = clazz.fields();
    64         methods = clazz.methods();
    65         generateDeclsForClass(pw, clazz, cname);
    66     }
    68     protected void generateDeclsForClass(PrintWriter pw,
    69                                          ClassDoc clazz, String cname)
    70         throws ClassNotFoundException {
    71         doneHandleTypes  = new Hashtable<Object, Object>();
    72         /* The following handle types are predefined in "typedefs.h". Suppress
    73            inclusion in the output by generating them "into the blue" here. */
    74         genHandleType(null, "java.lang.Class");
    75         genHandleType(null, "java.lang.ClassLoader");
    76         genHandleType(null, "java.lang.Object");
    77         genHandleType(null, "java.lang.String");
    78         genHandleType(null, "java.lang.Thread");
    79         genHandleType(null, "java.lang.ThreadGroup");
    80         genHandleType(null, "java.lang.Throwable");
    82         pw.println("/* LLNI Header for class " + clazz.qualifiedName() + " */" + lineSep);
    83         pw.println("#ifndef _Included_" + cname);
    84         pw.println("#define _Included_" + cname);
    85         pw.println("#include \"typedefs.h\"");
    86         pw.println("#include \"llni.h\"");
    87         pw.println("#include \"jni.h\"" + lineSep);
    89         forwardDecls(pw, clazz);
    90         structSectionForClass(pw, clazz, cname);
    91         methodSectionForClass(pw, clazz, cname);
    92         pw.println("#endif");
    93     }
    95     protected void genHandleType(PrintWriter pw, String clazzname) {
    96         String cname = mangleClassName(clazzname);
    97         if (!doneHandleTypes.containsKey(cname)) {
    98             doneHandleTypes.put(cname, cname);
    99             if (pw != null) {
   100                 pw.println("#ifndef DEFINED_" + cname);
   101                 pw.println("    #define DEFINED_" + cname);
   102                 pw.println("    GEN_HANDLE_TYPES(" + cname + ");");
   103                 pw.println("#endif" + lineSep);
   104             }
   105         }
   106     }
   108     protected String mangleClassName(String s) {
   109         return s.replace('.', '_')
   110             .replace(pathChar, '_')
   111             .replace(innerDelim, '_');
   112     }
   114     protected void forwardDecls(PrintWriter pw, ClassDoc clazz)
   115         throws ClassNotFoundException {
   116         ClassDoc clazzfield = null;
   118         if (clazz.qualifiedName().equals("java.lang.Object"))
   119             return;
   120         genHandleType(pw, clazz.qualifiedName());
   121         ClassDoc superClass = clazz.superclass();
   123         if(superClass != null){
   124             String superClassName = superClass.qualifiedName();
   125             forwardDecls(pw, superClass);
   126         }
   128         for (int i = 0; i < fields.length; i++) {
   129             FieldDoc field = (FieldDoc)fields[i];
   131             if (!field.isStatic()) {
   132                 Type t = field.type();
   133                 String tname = t.qualifiedTypeName();
   134                 TypeSignature newTypeSig = new TypeSignature(root);
   135                 String sig = newTypeSig.getTypeSignature(tname);
   137                 if (sig.charAt(0) != '[')
   138                     forwardDeclsFromSig(pw, sig);
   139             }
   140         }
   142         for (int i = 0; i < methods.length; i++) {
   143             MethodDoc method = (MethodDoc)methods[i];
   145             if (method.isNative()) {
   146                 Type retType = method.returnType();
   147                 String typesig = method.signature();
   148                 TypeSignature newTypeSig = new TypeSignature(root);
   149                 String sig = newTypeSig.getTypeSignature(typesig, retType);
   151                 if (sig.charAt(0) != '[')
   152                     forwardDeclsFromSig(pw, sig);
   154             }
   155         }
   156     }
   158     protected void forwardDeclsFromSig(PrintWriter pw, String sig) {
   159         int    len = sig.length();
   160         int    i   = sig.charAt(0) == '(' ? 1 : 0;
   162         /* Skip the initial "(". */
   163         while (i < len) {
   164             if (sig.charAt(i) == 'L') {
   165                 int j = i + 1;
   166                 while (sig.charAt(j) != ';') j++;
   167                 genHandleType(pw, sig.substring(i + 1, j));
   168                 i = j + 1;
   169             } else {
   170                 i++;
   171             }
   172         }
   173     }
   175     protected void structSectionForClass(PrintWriter pw,
   176                                          ClassDoc jclazz, String cname)
   177         throws ClassNotFoundException {
   179         String jname = jclazz.qualifiedName();
   181         if (cname.equals("java_lang_Object")) {
   182             pw.println("/* struct java_lang_Object is defined in typedefs.h. */");
   183             pw.println();
   184             return;
   185         }
   186         pw.println("#if !defined(__i386)");
   187         pw.println("#pragma pack(4)");
   188         pw.println("#endif");
   189         pw.println();
   190         pw.println("struct " + cname + " {");
   191         pw.println("    ObjHeader h;");
   192         pw.print(fieldDefs(jclazz, cname));
   194         if (jname.equals("java.lang.Class"))
   195             pw.println("    Class *LLNI_mask(cClass);" +
   196                        "  /* Fake field; don't access (see oobj.h) */");
   197         pw.println("};" + lineSep + lineSep + "#pragma pack()");
   198         pw.println();
   199         return;
   200     }
   202     private static class FieldDefsRes {
   203         public String className;        /* Name of the current class. */
   204         public FieldDefsRes parent;
   205         public String s;
   206         public int byteSize;
   207         public boolean bottomMost;
   208         public boolean printedOne = false;
   210         FieldDefsRes(ClassDoc clazz, FieldDefsRes parent, boolean bottomMost) {
   211             this.className = clazz.qualifiedName();
   212             this.parent = parent;
   213             this.bottomMost = bottomMost;
   214             int byteSize = 0;
   215             if (parent == null) this.s = "";
   216             else this.s = parent.s;
   217         }
   218     }
   220     /* Returns "true" iff added a field. */
   221     private boolean doField(FieldDefsRes res, FieldDoc field,
   222                             String cname, boolean padWord)
   223         throws ClassNotFoundException {
   225         String fieldDef = addStructMember(field, cname, padWord);
   226         if (fieldDef != null) {
   227             if (!res.printedOne) { /* add separator */
   228                 if (res.bottomMost) {
   229                     if (res.s.length() != 0)
   230                         res.s = res.s + "    /* local members: */" + lineSep;
   231                 } else {
   232                     res.s = res.s + "    /* inherited members from " +
   233                         res.className + ": */" + lineSep;
   234                 }
   235                 res.printedOne = true;
   236             }
   237             res.s = res.s + fieldDef;
   238             return true;
   239         }
   241         // Otherwise.
   242         return false;
   243     }
   245     private int doTwoWordFields(FieldDefsRes res, ClassDoc clazz,
   246                                 int offset, String cname, boolean padWord)
   247         throws ClassNotFoundException {
   248         boolean first = true;
   249         FieldDoc[] fields = clazz.fields();
   251         for (int i = 0; i <fields.length; i++) {
   252             FieldDoc field = fields[i];
   253             String tc =field.type().typeName();
   254             boolean twoWords = (tc.equals("long") || tc.equals("double"));
   255             if (twoWords && doField(res, field, cname, first && padWord)) {
   256                 offset += 8; first = false;
   257             }
   258         }
   259         return offset;
   260     }
   262     protected String fieldDefs(ClassDoc clazz, String cname)
   263         throws ClassNotFoundException {
   264         FieldDefsRes res = fieldDefs(clazz, cname, true);
   265         return res.s;
   266     }
   268     protected FieldDefsRes fieldDefs(ClassDoc clazz, String cname,
   269                                      boolean bottomMost)
   270         throws ClassNotFoundException {
   271         FieldDefsRes res;
   272         int offset;
   273         boolean didTwoWordFields = false;
   274         ClassDoc superclazz = clazz.superclass();
   276         if (superclazz != null) {
   277             String supername = superclazz.qualifiedName();
   278             res = new FieldDefsRes(clazz,
   279                                    fieldDefs(superclazz, cname, false),
   280                                    bottomMost);
   281             offset = res.parent.byteSize;
   282         } else {
   283             res = new FieldDefsRes(clazz, null, bottomMost);
   284             offset = 0;
   285         }
   287         FieldDoc[] fields = clazz.fields();
   289         for (int i = 0; i < fields.length; i++) {
   290             FieldDoc field = fields[i];
   292             if (doubleAlign && !didTwoWordFields && (offset % 8) == 0) {
   293                 offset = doTwoWordFields(res, clazz, offset, cname, false);
   294                 didTwoWordFields = true;
   295             }
   297             String tc = field.type().typeName();
   298             boolean twoWords = (tc.equals("long") ||tc.equals("double"));
   300             if (!doubleAlign || !twoWords) {
   301                 if (doField(res, field, cname, false)) offset += 4;
   302             }
   304         }
   306         if (doubleAlign && !didTwoWordFields) {
   307             if ((offset % 8) != 0) offset += 4;
   308             offset = doTwoWordFields(res, clazz, offset, cname, true);
   309         }
   311         res.byteSize = offset;
   312         return res;
   313     }
   315     /* OVERRIDE: This method handles instance fields */
   316     protected String addStructMember(FieldDoc member, String cname,
   317                                      boolean padWord)
   318         throws ClassNotFoundException {
   319         String res = null;
   321         if (member.isStatic()) {
   322             res = addStaticStructMember(member, cname);
   323             //   if (res == null) /* JNI didn't handle it, print comment. */
   324             //  res = "    /* Inaccessible static: " + member + " */" + lineSep;
   325         } else {
   326             if (padWord) res = "    java_int padWord" + padFieldNum++ + ";" + lineSep;
   327             res = "    " + llniType(member.type(), false, false) + " " + llniFieldName(member);
   328             if (isLongOrDouble(member.type())) res = res + "[2]";
   329             res = res + ";" + lineSep;
   330         }
   331         return res;
   332     }
   334     static private final boolean isWindows =
   335         System.getProperty("os.name").startsWith("Windows");
   337     /*
   338      * This method only handles static final fields.
   339      */
   340     protected String addStaticStructMember(FieldDoc field, String cname)
   341         throws ClassNotFoundException {
   342         String res = null;
   343         Object exp = null;
   345         if (!field.isStatic())
   346             return res;
   347         if (!field.isFinal())
   348             return res;
   350         exp = field.constantValue();
   352         if (exp != null) {
   353             /* Constant. */
   355             String     cn     = cname + "_" + field.name();
   356             String     suffix = null;
   357             long           val = 0;
   358             /* Can only handle int, long, float, and double fields. */
   359             if (exp instanceof Integer) {
   360                 suffix = "L";
   361                 val = ((Integer)exp).intValue();
   362             }
   363             if (exp instanceof Long) {
   364                 // Visual C++ supports the i64 suffix, not LL
   365                 suffix = isWindows ? "i64" : "LL";
   366                 val = ((Long)exp).longValue();
   367             }
   368             if (exp instanceof Float)  suffix = "f";
   369             if (exp instanceof Double) suffix = "";
   370             if (suffix != null) {
   371                 // Some compilers will generate a spurious warning
   372                 // for the integer constants for Integer.MIN_VALUE
   373                 // and Long.MIN_VALUE so we handle them specially.
   374                 if ((suffix.equals("L") && (val == Integer.MIN_VALUE)) ||
   375                     (suffix.equals("LL") && (val == Long.MIN_VALUE))) {
   376                     res = "    #undef  " + cn + lineSep
   377                         + "    #define " + cn
   378                         + " (" + (val + 1) + suffix + "-1)" + lineSep;
   379                 } else {
   380                     res = "    #undef  " + cn + lineSep
   381                         + "    #define " + cn + " "+ exp.toString() + suffix + lineSep;
   382                 }
   383             }
   384         }
   385         return res;
   386     }
   388     protected void methodSectionForClass(PrintWriter pw,
   389                                          ClassDoc clazz, String cname)
   390         throws ClassNotFoundException {
   391         String methods = methodDecls(clazz, cname);
   393         if (methods.length() != 0) {
   394             pw.println("/* Native method declarations: */" + lineSep);
   395             pw.println("#ifdef __cplusplus");
   396             pw.println("extern \"C\" {");
   397             pw.println("#endif" + lineSep);
   398             pw.println(methods);
   399             pw.println("#ifdef __cplusplus");
   400             pw.println("}");
   401             pw.println("#endif");
   402         }
   403     }
   405     protected String methodDecls(ClassDoc clazz, String cname)
   406         throws ClassNotFoundException {
   408         String res = "";
   409         for (int i = 0; i < methods.length; i++) {
   410             MethodDoc method = (MethodDoc)methods[i];
   411             if (method.isNative())
   412                 res = res + methodDecl(method, clazz, cname);
   413         }
   414         return res;
   415     }
   417     protected String methodDecl(MethodDoc method,
   418                                 ClassDoc clazz, String cname)
   419         throws ClassNotFoundException {
   420         String res = null;
   422         Type retType = method.returnType();
   423         String typesig = method.signature();
   424         TypeSignature newTypeSig = new TypeSignature(root);
   425         String sig = newTypeSig.getTypeSignature(typesig, retType);
   426         boolean longName = needLongName(method, clazz);
   428         if (sig.charAt(0) != '(')
   429             Util.error("invalid.method.signature", sig);
   432         res = "JNIEXPORT " + jniType(retType) + " JNICALL" + lineSep + jniMethodName(method, cname, longName)
   433             + "(JNIEnv *, " + cRcvrDecl(method, cname);
   434         Parameter[] params = method.parameters();
   435         Type argTypes[] = new Type[params.length];
   436         for(int p = 0; p <  params.length; p++){
   437             argTypes[p] =  params[p].type();
   438         }
   440         /* It would have been nice to include the argument names in the
   441            declaration, but there seems to be a bug in the "BinaryField"
   442            class, causing the getArguments() method to return "null" for
   443            most (non-constructor) methods. */
   444         for (int i = 0; i < argTypes.length; i++)
   445             res = res + ", " + jniType(argTypes[i]);
   446         res = res + ");" + lineSep;
   447         return res;
   448     }
   450     protected final boolean needLongName(MethodDoc method,
   451                                          ClassDoc clazz)
   452         throws ClassNotFoundException {
   453         String methodName = method.name();
   454         for (int i = 0; i < methods.length; i++) {
   455             MethodDoc memberMethod = (MethodDoc) methods[i];
   456             if ((memberMethod != method) &&
   457                 memberMethod.isNative() && (methodName == memberMethod.name()))
   458                 return true;
   459         }
   460         return false;
   461     }
   463     protected final String jniMethodName(MethodDoc method, String cname,
   464                                          boolean longName) {
   465         String res = "Java_" + cname + "_" + method.name();
   467         if (longName) {
   468             Type mType =  method.returnType();
   469             Parameter[] params = method.parameters();
   470             Type argTypes[] = new Type[params.length];
   471             for(int p = 0; p <  params.length; p++){
   472                 argTypes[p] =  params[p].type();
   473             }
   475             res = res + "__";
   476             for (int i = 0; i < argTypes.length; i++){
   477                 Type t = argTypes[i];
   478                 String tname = t.typeName();
   479                 TypeSignature newTypeSig = new TypeSignature(root);
   480                 String sig = newTypeSig.getTypeSignature(tname);
   481                 res = res + nameToIdentifier(sig);
   482             }
   483         }
   484         return res;
   485     }
   487     protected final String jniType(Type t) {
   488         String elmT =t.typeName();
   489         if (t.dimension().indexOf("[]") != -1) {
   490             if(elmT.equals("boolean"))return "jbooleanArray";
   491             else if(elmT.equals("byte"))return "jbyteArray";
   492             else if(elmT.equals("char"))return "jcharArray";
   493             else if(elmT.equals("short"))return "jshortArray";
   494             else if(elmT.equals("int"))return "jintArray";
   495             else if(elmT.equals("long"))return "jlongArray";
   496             else if(elmT.equals("float"))return "jfloatArray";
   497             else if(elmT.equals("double"))return "jdoubleArray";
   498             else if((t.dimension().indexOf("[][]") != -1) || (t.asClassDoc() != null))  return "jobjectArray";
   499         } else {
   500             if(elmT.equals("void"))return "void";
   501             else if(elmT.equals("boolean"))return "jboolean";
   502             else if(elmT.equals("byte"))return "jbyte";
   503             else if(elmT.equals("char"))return "jchar";
   504             else if(elmT.equals("short"))return "jshort";
   505             else if(elmT.equals("int"))return "jint";
   506             else if(elmT.equals("long"))return "jlong";
   507             else if(elmT.equals("float"))return "jfloat";
   508             else if(elmT.equals("double"))return "jdouble";
   509             else if (t.asClassDoc() != null) {
   510                 if (elmT.equals("String"))
   511                     return "jstring";
   512                 else if (t.asClassDoc().subclassOf(root.classNamed("java.lang.Class")))
   513                     return "jclass";
   514                 else
   515                     return "jobject";
   516             }
   517         }
   518         Util.bug("jni.unknown.type");
   519         return null; /* dead code. */
   520     }
   522     protected String llniType(Type t, boolean handleize, boolean longDoubleOK) {
   523         String res = null;
   524         String elmt = t.typeName();
   525         if (t.dimension().indexOf("[]") != -1) {
   526             if((t.dimension().indexOf("[][]") != -1)
   527                || (t.asClassDoc() != null)) res = "IArrayOfRef";
   528             else if(elmt.equals("boolean")) res =  "IArrayOfBoolean";
   529             else if(elmt.equals("byte")) res =  "IArrayOfByte";
   530             else if(elmt.equals("char")) res =  "IArrayOfChar";
   531             else if(elmt.equals("int")) res =  "IArrayOfInt";
   532             else if(elmt.equals("long")) res =  "IArrayOfLong";
   533             else if(elmt.equals("float")) res =  "IArrayOfFloat";
   534             else if(elmt.equals("double")) res =  "IArrayOfDouble";
   535             if (!handleize) res = "DEREFERENCED_" + res;
   536         } else {
   537             if(elmt.equals("void")) res =  "void";
   538             else if( (elmt.equals("boolean")) || (elmt.equals("byte"))
   539                      ||(elmt.equals("char")) || (elmt.equals("short"))
   540                      || (elmt.equals("int")))   res = "java_int";
   541             else   if(elmt.equals("long")) res = longDoubleOK
   542                                                ? "java_long" : "val32 /* java_long */";
   543             else   if(elmt.equals("float")) res =  "java_float";
   544             else   if(elmt.equals("double")) res =  res = longDoubleOK
   545                                                  ? "java_double" : "val32 /* java_double */";
   546             else if(t.asClassDoc() != null) {
   547                 res = "I" +  mangleClassName(t.asClassDoc().qualifiedName());
   548                 if (!handleize) res = "DEREFERENCED_" + res;
   549             }
   550         }
   551         return res;
   552     }
   554     protected final String cRcvrDecl(MemberDoc field, String cname) {
   555         return (field.isStatic() ? "jclass" : "jobject");
   556     }
   558     protected String maskName(String s) {
   559         return "LLNI_mask(" + s + ")";
   560     }
   562     protected String llniFieldName(MemberDoc field) {
   563         return maskName(field.name());
   564     }
   566     protected final boolean isLongOrDouble(Type t) {
   567         String tc = t.typeName();
   568         return (tc.equals("long") || tc.equals("double"));
   569     }
   571     /* Do unicode to ansi C identifier conversion.
   572        %%% This may not be right, but should be called more often. */
   573     protected final String nameToIdentifier(String name) {
   574         int len = name.length();
   575         StringBuffer buf = new StringBuffer(len);
   576         for (int i = 0; i < len; i++) {
   577             char c = name.charAt(i);
   578             if (isASCIILetterOrDigit(c))
   579                 buf.append(c);
   580             else if (c == '/')
   581                 buf.append('_');
   582             else if (c == '.')
   583                 buf.append('_');
   584             else if (c == '_')
   585                 buf.append("_1");
   586             else if (c == ';')
   587                 buf.append("_2");
   588             else if (c == '[')
   589                 buf.append("_3");
   590             else
   591                 buf.append("_0" + ((int)c));
   592         }
   593         return new String(buf);
   594     }
   596     protected final boolean isASCIILetterOrDigit(char c) {
   597         if (((c >= 'A') && (c <= 'Z')) ||
   598             ((c >= 'a') && (c <= 'z')) ||
   599             ((c >= '0') && (c <= '9')))
   600             return true;
   601         else
   602             return false;
   603     }
   604 }

mercurial