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

Thu, 31 Aug 2017 15:17:03 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:17:03 +0800
changeset 2525
2eb010b6cb22
parent 1362
c46e0c9940d6
parent 0
959103a6100f
permissions
-rw-r--r--

merge

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

mercurial