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