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

Wed, 02 Jun 2010 19:08:47 -0700

author
darcy
date
Wed, 02 Jun 2010 19:08:47 -0700
changeset 575
9a7c998bf2fc
parent 554
9d9f26857129
child 581
f2fdd52e4e87
permissions
-rw-r--r--

6933147: Provided new utility visitors supporting SourceVersion.RELEASE_7
Reviewed-by: jjg

     1 /*
     2  * Copyright (c) 2002, 2008, Oracle and/or its affiliates. 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.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    27 package com.sun.tools.javah;
    29 import javax.lang.model.element.ExecutableElement;
    30 import javax.lang.model.element.TypeElement;
    31 import javax.lang.model.element.VariableElement;
    32 import javax.lang.model.util.Elements;
    33 import javax.lang.model.util.Types;
    35 /**
    36  * A utility for mangling java identifiers into C names.  Should make
    37  * this more fine grained and distribute the functionality to the
    38  * generators.
    39  *
    40  * <p><b>This is NOT part of any API supported by Sun Microsystems.
    41  * If you write code that depends on this, you do so at your own
    42  * risk.  This code and its internal interfaces are subject to change
    43  * or deletion without notice.</b></p>
    44  *
    45  * @author  Sucheta Dambalkar(Revised)
    46  */
    47 public class Mangle {
    49     public static class Type {
    50         public static final int CLASS            = 1;
    51         public static final int FIELDSTUB        = 2;
    52         public static final int FIELD            = 3;
    53         public static final int JNI              = 4;
    54         public static final int SIGNATURE        = 5;
    55         public static final int METHOD_JDK_1     = 6;
    56         public static final int METHOD_JNI_SHORT = 7;
    57         public static final int METHOD_JNI_LONG  = 8;
    58     };
    60     private Elements elems;
    61     private Types types;
    63     Mangle(Elements elems, Types types) {
    64         this.elems = elems;
    65         this.types = types;
    66     }
    68     public final String mangle(CharSequence name, int mtype) {
    69         StringBuffer result = new StringBuffer(100);
    70         int length = name.length();
    72         for (int i = 0; i < length; i++) {
    73             char ch = name.charAt(i);
    74             if (isalnum(ch)) {
    75                 result.append(ch);
    76             } else if ((ch == '.') &&
    77                        mtype == Mangle.Type.CLASS) {
    78                 result.append('_');
    79             } else if (( ch == '$') &&
    80                        mtype == Mangle.Type.CLASS) {
    81                 result.append('_');
    82                 result.append('_');
    83             } else if (ch == '_' && mtype == Mangle.Type.FIELDSTUB) {
    84                 result.append('_');
    85             } else if (ch == '_' && mtype == Mangle.Type.CLASS) {
    86                 result.append('_');
    87             } else if (mtype == Mangle.Type.JNI) {
    88                 String esc = null;
    89                 if (ch == '_')
    90                     esc = "_1";
    91                 else if (ch == '.')
    92                     esc = "_";
    93                 else if (ch == ';')
    94                     esc = "_2";
    95                 else if (ch == '[')
    96                     esc = "_3";
    97                 if (esc != null) {
    98                     result.append(esc);
    99                 } else {
   100                     result.append(mangleChar(ch));
   101                 }
   102             } else if (mtype == Mangle.Type.SIGNATURE) {
   103                 if (isprint(ch)) {
   104                     result.append(ch);
   105                 } else {
   106                     result.append(mangleChar(ch));
   107                 }
   108             } else {
   109                 result.append(mangleChar(ch));
   110             }
   111         }
   113         return result.toString();
   114     }
   116     public String mangleMethod(ExecutableElement method, TypeElement clazz,
   117                                       int mtype) {
   118         StringBuffer result = new StringBuffer(100);
   119         result.append("Java_");
   121         if (mtype == Mangle.Type.METHOD_JDK_1) {
   122             result.append(mangle(clazz.getQualifiedName(), Mangle.Type.CLASS));
   123             result.append('_');
   124             result.append(mangle(method.getSimpleName(),
   125                                  Mangle.Type.FIELD));
   126             result.append("_stub");
   127             return result.toString();
   128         }
   130         /* JNI */
   131         result.append(mangle(getInnerQualifiedName(clazz), Mangle.Type.JNI));
   132         result.append('_');
   133         result.append(mangle(method.getSimpleName(),
   134                              Mangle.Type.JNI));
   135         if (mtype == Mangle.Type.METHOD_JNI_LONG) {
   136             result.append("__");
   137             String typesig = signature(method);
   138             TypeSignature newTypeSig = new TypeSignature(elems);
   139             String sig = newTypeSig.getTypeSignature(typesig,  method.getReturnType());
   140             sig = sig.substring(1);
   141             sig = sig.substring(0, sig.lastIndexOf(')'));
   142             sig = sig.replace('/', '.');
   143             result.append(mangle(sig, Mangle.Type.JNI));
   144         }
   146         return result.toString();
   147     }
   148     //where
   149         private String getInnerQualifiedName(TypeElement clazz) {
   150             return elems.getBinaryName(clazz).toString();
   151         }
   153     public final String mangleChar(char ch) {
   154         String s = Integer.toHexString(ch);
   155         int nzeros = 5 - s.length();
   156         char[] result = new char[6];
   157         result[0] = '_';
   158         for (int i = 1; i <= nzeros; i++)
   159             result[i] = '0';
   160         for (int i = nzeros+1, j = 0; i < 6; i++, j++)
   161             result[i] = s.charAt(j);
   162         return new String(result);
   163     }
   165     // Warning: duplicated in Gen
   166     private String signature(ExecutableElement e) {
   167         StringBuffer sb = new StringBuffer();
   168         String sep = "(";
   169         for (VariableElement p: e.getParameters()) {
   170             sb.append(sep);
   171             sb.append(types.erasure(p.asType()).toString());
   172             sep = ",";
   173         }
   174         sb.append(")");
   175         return sb.toString();
   176     }
   178     /* Warning: Intentional ASCII operation. */
   179     private static final boolean isalnum(char ch) {
   180         return ch <= 0x7f && /* quick test */
   181             ((ch >= 'A' && ch <= 'Z') ||
   182              (ch >= 'a' && ch <= 'z') ||
   183              (ch >= '0' && ch <= '9'));
   184     }
   186     /* Warning: Intentional ASCII operation. */
   187     private static final boolean isprint(char ch) {
   188         return ch >= 32 && ch <= 126;
   189     }
   190 }

mercurial