langtools/src/share/classes/com/sun/tools/javah/Mangle.java
author briangoetz
Wed, 18 Dec 2013 16:05:18 -0500
changeset 22163 3651128c74eb
parent 14263 473b1eaede64
permissions -rw-r--r--
8030244: Update langtools to use Diamond Reviewed-by: darcy
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     1
/*
14263
473b1eaede64 8000310: Clean up use of StringBuffer in langtools
jjg
parents: 7681
diff changeset
     2
 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
06bc494ca11e Initial load
duke
parents:
diff changeset
     4
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
06bc494ca11e Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5520
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 3996
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5520
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 3996
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    10
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
06bc494ca11e Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
06bc494ca11e Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
06bc494ca11e Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
06bc494ca11e Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
06bc494ca11e Initial load
duke
parents:
diff changeset
    16
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
06bc494ca11e Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
06bc494ca11e Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
06bc494ca11e Initial load
duke
parents:
diff changeset
    20
 *
5520
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 3996
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 3996
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 3996
diff changeset
    23
 * questions.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    24
 */
06bc494ca11e Initial load
duke
parents:
diff changeset
    25
06bc494ca11e Initial load
duke
parents:
diff changeset
    26
06bc494ca11e Initial load
duke
parents:
diff changeset
    27
package com.sun.tools.javah;
06bc494ca11e Initial load
duke
parents:
diff changeset
    28
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    29
import javax.lang.model.element.ExecutableElement;
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    30
import javax.lang.model.element.TypeElement;
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    31
import javax.lang.model.element.VariableElement;
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    32
import javax.lang.model.util.Elements;
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    33
import javax.lang.model.util.Types;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    34
06bc494ca11e Initial load
duke
parents:
diff changeset
    35
/**
06bc494ca11e Initial load
duke
parents:
diff changeset
    36
 * A utility for mangling java identifiers into C names.  Should make
06bc494ca11e Initial load
duke
parents:
diff changeset
    37
 * this more fine grained and distribute the functionality to the
06bc494ca11e Initial load
duke
parents:
diff changeset
    38
 * generators.
06bc494ca11e Initial load
duke
parents:
diff changeset
    39
 *
5847
1908176fd6e3 6944312: Potential rebranding issues in openjdk/langtools repository sources
jjg
parents: 5520
diff changeset
    40
 * <p><b>This is NOT part of any supported API.
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    41
 * If you write code that depends on this, you do so at your own
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    42
 * risk.  This code and its internal interfaces are subject to change
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    43
 * or deletion without notice.</b></p>
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    44
 *
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    45
 * @author  Sucheta Dambalkar(Revised)
06bc494ca11e Initial load
duke
parents:
diff changeset
    46
 */
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    47
public class Mangle {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    48
06bc494ca11e Initial load
duke
parents:
diff changeset
    49
    public static class Type {
06bc494ca11e Initial load
duke
parents:
diff changeset
    50
        public static final int CLASS            = 1;
06bc494ca11e Initial load
duke
parents:
diff changeset
    51
        public static final int FIELDSTUB        = 2;
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    52
        public static final int FIELD            = 3;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    53
        public static final int JNI              = 4;
06bc494ca11e Initial load
duke
parents:
diff changeset
    54
        public static final int SIGNATURE        = 5;
06bc494ca11e Initial load
duke
parents:
diff changeset
    55
        public static final int METHOD_JDK_1     = 6;
06bc494ca11e Initial load
duke
parents:
diff changeset
    56
        public static final int METHOD_JNI_SHORT = 7;
06bc494ca11e Initial load
duke
parents:
diff changeset
    57
        public static final int METHOD_JNI_LONG  = 8;
22163
3651128c74eb 8030244: Update langtools to use Diamond
briangoetz
parents: 14263
diff changeset
    58
    }
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    59
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    60
    private Elements elems;
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    61
    private Types types;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    62
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    63
    Mangle(Elements elems, Types types) {
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    64
        this.elems = elems;
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    65
        this.types = types;
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    66
    }
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    67
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
    68
    public final String mangle(CharSequence name, int mtype) {
14263
473b1eaede64 8000310: Clean up use of StringBuffer in langtools
jjg
parents: 7681
diff changeset
    69
        StringBuilder result = new StringBuilder(100);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    70
        int length = name.length();
06bc494ca11e Initial load
duke
parents:
diff changeset
    71
06bc494ca11e Initial load
duke
parents:
diff changeset
    72
        for (int i = 0; i < length; i++) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    73
            char ch = name.charAt(i);
06bc494ca11e Initial load
duke
parents:
diff changeset
    74
            if (isalnum(ch)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    75
                result.append(ch);
06bc494ca11e Initial load
duke
parents:
diff changeset
    76
            } else if ((ch == '.') &&
06bc494ca11e Initial load
duke
parents:
diff changeset
    77
                       mtype == Mangle.Type.CLASS) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    78
                result.append('_');
06bc494ca11e Initial load
duke
parents:
diff changeset
    79
            } else if (( ch == '$') &&
06bc494ca11e Initial load
duke
parents:
diff changeset
    80
                       mtype == Mangle.Type.CLASS) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    81
                result.append('_');
06bc494ca11e Initial load
duke
parents:
diff changeset
    82
                result.append('_');
06bc494ca11e Initial load
duke
parents:
diff changeset
    83
            } else if (ch == '_' && mtype == Mangle.Type.FIELDSTUB) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    84
                result.append('_');
06bc494ca11e Initial load
duke
parents:
diff changeset
    85
            } else if (ch == '_' && mtype == Mangle.Type.CLASS) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    86
                result.append('_');
06bc494ca11e Initial load
duke
parents:
diff changeset
    87
            } else if (mtype == Mangle.Type.JNI) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    88
                String esc = null;
06bc494ca11e Initial load
duke
parents:
diff changeset
    89
                if (ch == '_')
06bc494ca11e Initial load
duke
parents:
diff changeset
    90
                    esc = "_1";
06bc494ca11e Initial load
duke
parents:
diff changeset
    91
                else if (ch == '.')
06bc494ca11e Initial load
duke
parents:
diff changeset
    92
                    esc = "_";
06bc494ca11e Initial load
duke
parents:
diff changeset
    93
                else if (ch == ';')
06bc494ca11e Initial load
duke
parents:
diff changeset
    94
                    esc = "_2";
06bc494ca11e Initial load
duke
parents:
diff changeset
    95
                else if (ch == '[')
06bc494ca11e Initial load
duke
parents:
diff changeset
    96
                    esc = "_3";
06bc494ca11e Initial load
duke
parents:
diff changeset
    97
                if (esc != null) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    98
                    result.append(esc);
06bc494ca11e Initial load
duke
parents:
diff changeset
    99
                } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   100
                    result.append(mangleChar(ch));
06bc494ca11e Initial load
duke
parents:
diff changeset
   101
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   102
            } else if (mtype == Mangle.Type.SIGNATURE) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   103
                if (isprint(ch)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   104
                    result.append(ch);
06bc494ca11e Initial load
duke
parents:
diff changeset
   105
                } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   106
                    result.append(mangleChar(ch));
06bc494ca11e Initial load
duke
parents:
diff changeset
   107
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   108
            } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   109
                result.append(mangleChar(ch));
06bc494ca11e Initial load
duke
parents:
diff changeset
   110
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   111
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   112
06bc494ca11e Initial load
duke
parents:
diff changeset
   113
        return result.toString();
06bc494ca11e Initial load
duke
parents:
diff changeset
   114
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   115
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   116
    public String mangleMethod(ExecutableElement method, TypeElement clazz,
6930
b6fea484cbb2 4942232: missing param class processes without error
jjg
parents: 5847
diff changeset
   117
                                      int mtype) throws TypeSignature.SignatureException {
14263
473b1eaede64 8000310: Clean up use of StringBuffer in langtools
jjg
parents: 7681
diff changeset
   118
        StringBuilder result = new StringBuilder(100);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   119
        result.append("Java_");
06bc494ca11e Initial load
duke
parents:
diff changeset
   120
06bc494ca11e Initial load
duke
parents:
diff changeset
   121
        if (mtype == Mangle.Type.METHOD_JDK_1) {
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   122
            result.append(mangle(clazz.getQualifiedName(), Mangle.Type.CLASS));
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   123
            result.append('_');
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   124
            result.append(mangle(method.getSimpleName(),
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   125
                                 Mangle.Type.FIELD));
06bc494ca11e Initial load
duke
parents:
diff changeset
   126
            result.append("_stub");
06bc494ca11e Initial load
duke
parents:
diff changeset
   127
            return result.toString();
06bc494ca11e Initial load
duke
parents:
diff changeset
   128
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   129
06bc494ca11e Initial load
duke
parents:
diff changeset
   130
        /* JNI */
06bc494ca11e Initial load
duke
parents:
diff changeset
   131
        result.append(mangle(getInnerQualifiedName(clazz), Mangle.Type.JNI));
06bc494ca11e Initial load
duke
parents:
diff changeset
   132
        result.append('_');
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   133
        result.append(mangle(method.getSimpleName(),
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   134
                             Mangle.Type.JNI));
06bc494ca11e Initial load
duke
parents:
diff changeset
   135
        if (mtype == Mangle.Type.METHOD_JNI_LONG) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   136
            result.append("__");
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   137
            String typesig = signature(method);
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   138
            TypeSignature newTypeSig = new TypeSignature(elems);
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   139
            String sig = newTypeSig.getTypeSignature(typesig,  method.getReturnType());
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   140
            sig = sig.substring(1);
06bc494ca11e Initial load
duke
parents:
diff changeset
   141
            sig = sig.substring(0, sig.lastIndexOf(')'));
06bc494ca11e Initial load
duke
parents:
diff changeset
   142
            sig = sig.replace('/', '.');
06bc494ca11e Initial load
duke
parents:
diff changeset
   143
            result.append(mangle(sig, Mangle.Type.JNI));
06bc494ca11e Initial load
duke
parents:
diff changeset
   144
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   145
06bc494ca11e Initial load
duke
parents:
diff changeset
   146
        return result.toString();
06bc494ca11e Initial load
duke
parents:
diff changeset
   147
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   148
    //where
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   149
        private String getInnerQualifiedName(TypeElement clazz) {
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   150
            return elems.getBinaryName(clazz).toString();
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   151
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   152
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   153
    public final String mangleChar(char ch) {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   154
        String s = Integer.toHexString(ch);
06bc494ca11e Initial load
duke
parents:
diff changeset
   155
        int nzeros = 5 - s.length();
06bc494ca11e Initial load
duke
parents:
diff changeset
   156
        char[] result = new char[6];
06bc494ca11e Initial load
duke
parents:
diff changeset
   157
        result[0] = '_';
06bc494ca11e Initial load
duke
parents:
diff changeset
   158
        for (int i = 1; i <= nzeros; i++)
06bc494ca11e Initial load
duke
parents:
diff changeset
   159
            result[i] = '0';
06bc494ca11e Initial load
duke
parents:
diff changeset
   160
        for (int i = nzeros+1, j = 0; i < 6; i++, j++)
06bc494ca11e Initial load
duke
parents:
diff changeset
   161
            result[i] = s.charAt(j);
06bc494ca11e Initial load
duke
parents:
diff changeset
   162
        return new String(result);
06bc494ca11e Initial load
duke
parents:
diff changeset
   163
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   164
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   165
    // Warning: duplicated in Gen
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   166
    private String signature(ExecutableElement e) {
14263
473b1eaede64 8000310: Clean up use of StringBuffer in langtools
jjg
parents: 7681
diff changeset
   167
        StringBuilder sb = new StringBuilder();
3996
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   168
        String sep = "(";
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   169
        for (VariableElement p: e.getParameters()) {
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   170
            sb.append(sep);
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   171
            sb.append(types.erasure(p.asType()).toString());
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   172
            sep = ",";
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   173
        }
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   174
        sb.append(")");
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   175
        return sb.toString();
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   176
    }
dc676a9093b3 6572945: javah should be written as an annotation processor, not a doclet
jjg
parents: 10
diff changeset
   177
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   178
    /* Warning: Intentional ASCII operation. */
22163
3651128c74eb 8030244: Update langtools to use Diamond
briangoetz
parents: 14263
diff changeset
   179
    private static boolean isalnum(char ch) {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   180
        return ch <= 0x7f && /* quick test */
06bc494ca11e Initial load
duke
parents:
diff changeset
   181
            ((ch >= 'A' && ch <= 'Z') ||
06bc494ca11e Initial load
duke
parents:
diff changeset
   182
             (ch >= 'a' && ch <= 'z') ||
06bc494ca11e Initial load
duke
parents:
diff changeset
   183
             (ch >= '0' && ch <= '9'));
06bc494ca11e Initial load
duke
parents:
diff changeset
   184
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   185
06bc494ca11e Initial load
duke
parents:
diff changeset
   186
    /* Warning: Intentional ASCII operation. */
22163
3651128c74eb 8030244: Update langtools to use Diamond
briangoetz
parents: 14263
diff changeset
   187
    private static boolean isprint(char ch) {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   188
        return ch >= 32 && ch <= 126;
06bc494ca11e Initial load
duke
parents:
diff changeset
   189
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   190
}