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 26package com.sun.tools.javah; 27 28import javax.lang.model.element.ExecutableElement; 29import javax.lang.model.element.TypeElement; 30import javax.lang.model.element.VariableElement; 31import javax.lang.model.util.Elements; 32import 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 */ 46public 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} 190