81 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
81 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
82 */ |
82 */ |
83 |
83 |
84 package jdk.internal.dynalink.support; |
84 package jdk.internal.dynalink.support; |
85 |
85 |
86 import jdk.internal.dynalink.CallSiteDescriptor; |
|
87 |
86 |
88 /** |
87 /** |
89 * Implements the name mangling and demangling as specified by John Rose's |
88 * Implements the name mangling and demangling as specified by John Rose's |
90 * <a href="https://blogs.oracle.com/jrose/entry/symbolic_freedom_in_the_vm" |
89 * <a href="https://blogs.oracle.com/jrose/entry/symbolic_freedom_in_the_vm" |
91 * target="_blank">"Symbolic Freedom in the VM"</a> article. It is recommended |
90 * target="_blank">"Symbolic Freedom in the VM"</a> article. Normally, you would |
92 * that implementers of languages on the JVM uniformly adopt this for symbolic |
91 * mangle the names in the call sites as you're generating bytecode, and then |
93 * interoperability between languages. Normally, you would mangle the names as |
92 * demangle them when you receive them in bootstrap methods. |
94 * you're generating bytecode, and then demangle them when you're creating |
|
95 * {@link CallSiteDescriptor} objects. Note that you are expected to mangle |
|
96 * individual tokens, and not the whole name at the call site, i.e. the colon |
|
97 * character normally separating the tokens is never mangled. I.e. you wouldn't |
|
98 * mangle {@code dyn:getProp:color} into {@code dyn\!getProp\!color}, but you |
|
99 * would mangle {@code dyn:getProp:color$} into {@code dyn:getProp:\=color\%} |
|
100 * (only mangling the individual token containing the symbol {@code color$}). |
|
101 * {@link CallSiteDescriptor#tokenizeName(String)} already uses |
|
102 * {@link #decode(String)} to perform demangling on the passed names. If you use |
|
103 * that method when creating call site descriptors, (it is recommended that you |
|
104 * do), then you have demangling handled for you already, and only need to |
|
105 * ensure that you mangle the names using {@link #encode(String)} when you're |
|
106 * emitting them in the bytecode. |
|
107 */ |
93 */ |
108 public final class NameCodec { |
94 public final class NameCodec { |
109 private static final char ESCAPE_CHAR = '\\'; |
95 private static final char ESCAPE_CHAR = '\\'; |
110 private static final char EMPTY_ESCAPE = '='; |
96 private static final char EMPTY_ESCAPE = '='; |
111 private static final String EMPTY_NAME = new String(new char[] { ESCAPE_CHAR, EMPTY_ESCAPE }); |
97 private static final String EMPTY_NAME = new String(new char[] { ESCAPE_CHAR, EMPTY_ESCAPE }); |
178 * Decodes ("demangles") an encoded symbolic name. |
164 * Decodes ("demangles") an encoded symbolic name. |
179 * @param name the symbolic name to demangle |
165 * @param name the symbolic name to demangle |
180 * @return the demangled form of the symbolic name. |
166 * @return the demangled form of the symbolic name. |
181 */ |
167 */ |
182 public static String decode(final String name) { |
168 public static String decode(final String name) { |
183 if(name.charAt(0) != ESCAPE_CHAR) { |
169 if(name.isEmpty() || name.charAt(0) != ESCAPE_CHAR) { |
184 return name; |
170 return name; |
185 } |
171 } |
186 final int l = name.length(); |
172 final int l = name.length(); |
187 if(l == 2 && name.charAt(1) == EMPTY_CHAR) { |
173 if(l == 2 && name.charAt(1) == EMPTY_CHAR) { |
188 return ""; |
174 return ""; |