org.robovm.compiler.Symbols Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2014 RoboVM AB
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.robovm.compiler;
import org.robovm.compiler.trampoline.Trampoline;
import soot.SootClass;
import soot.SootField;
import soot.SootFieldRef;
import soot.SootMethod;
import soot.SootMethodRef;
import java.util.List;
import static org.robovm.compiler.Types.getDescriptor;
import static org.robovm.compiler.Types.getInternalName;
/**
* Generates symbols for functions and global values. All symbols generated by
* the compiler must go through this class.
*/
public class Symbols {
/**
* Prefix used for functions representing actual method implementations.
*/
public static final String EXTERNAL_SYMBOL_PREFIX = "[J]";
/**
* Prefix used for internal functions and values which doesn't correspond
* to a method.
*/
public static final String INTERNAL_SYMBOL_PREFIX = "[j]";
/**
* Prefix used for C functions.
*/
public static final String C_SYMBOL_PREFIX = "_j_";
public static String methodSymbol(SootMethod method) {
return methodSymbol(method, null);
}
@SuppressWarnings("unchecked")
public static String methodSymbol(SootMethodRef methodRef) {
return methodSymbol(methodRef, null);
}
public static String methodSymbol(String owner, String name, List parameterTypes, soot.Type returnType) {
return methodSymbol(owner, name, parameterTypes, returnType, null);
}
public static String methodSymbol(String owner, String name, String desc) {
return methodSymbol(owner, name, desc, null);
}
public static String methodAttributesSymbol(SootMethod method) {
return methodSymbol(method, "mattributes");
}
public static String callbackPtrSymbol(SootMethod method) {
return methodSymbol(method, "callbackptr");
}
public static String bridgePtrSymbol(SootMethod method) {
return methodSymbol(method, "bridgeptr");
}
public static boolean isCallbackCSymbol(String symbol) {
return symbol.startsWith(C_SYMBOL_PREFIX) && symbol.endsWith("callback");
}
public static String callbackCSymbol(SootMethod method) {
return cMethodSymbol(method, "callback");
}
public static boolean isCallbackInnerCSymbol(String symbol) {
return symbol.startsWith(C_SYMBOL_PREFIX) && symbol.endsWith("callbackinner");
}
public static String callbackInnerCSymbol(SootMethod method) {
return cMethodSymbol(method, "callbackinner");
}
public static boolean isBridgeCSymbol(String symbol) {
return symbol.startsWith(C_SYMBOL_PREFIX) && symbol.endsWith("bridge");
}
public static String bridgeCSymbol(SootMethod method) {
return cMethodSymbol(method, "bridge");
}
public static String globalValuePtrSymbol(SootMethod method) {
return methodSymbol(method, "globalvalueptr");
}
public static String nativeMethodPtrSymbol(String targetInternalName, String methodName, String methodDesc) {
return methodSymbol(targetInternalName, methodName, methodDesc, "nativeptr");
}
private static String methodSymbol(SootMethod method, String type) {
return methodSymbol(method.makeRef(), type);
}
@SuppressWarnings("unchecked")
private static String methodSymbol(SootMethodRef methodRef, String type) {
return methodSymbol(getInternalName(methodRef.declaringClass()), methodRef.name(),
methodRef.parameterTypes(), methodRef.returnType(), type);
}
private static String methodSymbol(String owner, String name, List parameterTypes, soot.Type returnType, String type) {
return methodSymbol(owner, name, getDescriptor(parameterTypes, returnType), type);
}
private static String methodSymbol(String owner, String name, String desc, String type) {
StringBuilder sb = new StringBuilder(type == null ? EXTERNAL_SYMBOL_PREFIX : INTERNAL_SYMBOL_PREFIX);
sb.append(owner.replace('/', '.'));
sb.append('.');
sb.append(name);
sb.append(desc);
if (type != null) {
sb.append('[');
sb.append(type);
sb.append(']');
}
return sb.toString();
}
private static String cMethodSymbol(SootMethod method, String type) {
return cMethodSymbol(method.makeRef(), type);
}
@SuppressWarnings("unchecked")
private static String cMethodSymbol(SootMethodRef methodRef, String type) {
return cMethodSymbol(getInternalName(methodRef.declaringClass()), methodRef.name(),
methodRef.parameterTypes(), methodRef.returnType(), type);
}
private static String cMethodSymbol(String owner, String name, List parameterTypes, soot.Type returnType, String type) {
return cMethodSymbol(owner, name, getDescriptor(parameterTypes, returnType), type);
}
private static String cMethodSymbol(String owner, String name, String desc, String type) {
StringBuilder sb = new StringBuilder(C_SYMBOL_PREFIX);
sb.append(Mangler.mangleNativeString(owner));
sb.append("_");
sb.append(Mangler.mangleNativeString(name));
sb.append("__");
sb.append(Mangler.mangleNativeString(desc.substring(1, desc.lastIndexOf(')'))));
sb.append("__");
sb.append(Mangler.mangleNativeString(desc.substring(desc.lastIndexOf(')') + 1)));
if (type != null) {
sb.append("__");
sb.append(type);
}
return sb.toString();
}
public static String linetableSymbol(String owner, String name, String desc) {
return methodSymbol(owner, name, desc, "linetable");
}
public static String linetableSymbol(SootMethod method) {
return methodSymbol(method, "linetable");
}
public static String bptableSymbol(SootMethod method) {
return methodSymbol(method, "bptable");
}
public static String methodSymbolPrefix(String owner) {
StringBuilder sb = new StringBuilder(EXTERNAL_SYMBOL_PREFIX);
sb.append(owner.replace('/', '.'));
return sb.toString();
}
public static String getterSymbol(SootField field) {
return fieldSymbol(field, "get");
}
public static String getterSymbol(SootFieldRef fieldRef) {
return fieldSymbol(fieldRef, "get");
}
public static String setterSymbol(SootField field) {
return fieldSymbol(field, "set");
}
public static String setterSymbol(SootFieldRef fieldRef) {
return fieldSymbol(fieldRef, "set");
}
public static String fieldAttributesSymbol(SootField field) {
return fieldSymbol(field, "fattributes");
}
private static String fieldSymbol(SootField field, String type) {
return fieldSymbol(getInternalName(field.getDeclaringClass()), field.getName(), getDescriptor(field.getType()), type);
}
private static String fieldSymbol(SootFieldRef fieldRef, String type) {
return fieldSymbol(getInternalName(fieldRef.declaringClass()), fieldRef.name(), getDescriptor(fieldRef.type()), type);
}
private static String fieldSymbol(String owner, String name, String desc, String type) {
StringBuilder sb = new StringBuilder(INTERNAL_SYMBOL_PREFIX);
sb.append(owner.replace('/', '.'));
sb.append('.');
sb.append(name);
sb.append('(');
sb.append(desc);
sb.append(')');
sb.append('[');
sb.append(type);
sb.append(']');
return sb.toString();
}
public static String callbackSymbol(SootMethod method) {
return functionWrapper(methodSymbol(method), "callback");
}
public static String synchronizedWrapperSymbol(SootMethod method) {
return functionWrapper(methodSymbol(method), "synchronized");
}
public static String synchronizedWrapperSymbol(String owner, String name, String desc) {
return functionWrapper(methodSymbol(owner, name, desc), "synchronized");
}
public static String lookupWrapperSymbol(SootMethod method) {
return functionWrapper(methodSymbol(method), "lookup");
}
public static String lookupWrapperSymbol(String owner, String name, String desc) {
return functionWrapper(methodSymbol(owner, name, desc), "lookup");
}
public static String clinitWrapperSymbol(String targetFnName) {
return functionWrapper(targetFnName, "clinit");
}
private static String functionWrapper(String targetFnName, String type) {
if (!targetFnName.startsWith(EXTERNAL_SYMBOL_PREFIX) && !targetFnName.startsWith(INTERNAL_SYMBOL_PREFIX)) {
throw new IllegalArgumentException("Expected symbol prefix not found: " + targetFnName);
}
return INTERNAL_SYMBOL_PREFIX + targetFnName.substring(EXTERNAL_SYMBOL_PREFIX.length()) + "[" + type + "]";
}
public static String allocatorSymbol(String classInternalName) {
return classSymbol(classInternalName, "allocator");
}
public static String instanceofSymbol(String classInternalName) {
return classSymbol(classInternalName, "instanceof");
}
public static String checkcastSymbol(String classInternalName) {
return classSymbol(classInternalName, "checkcast");
}
public static String trycatchenterSymbol(String classInternalName) {
return classSymbol(classInternalName, "trycatchenter");
}
public static String ldcInternalSymbol(String classInternalName) {
return classSymbol(classInternalName, "ldc");
}
public static String ldcExternalSymbol(String classInternalName) {
return classSymbol(classInternalName, "ldcext");
}
public static String infoSymbol(String classInternalName) {
return classSymbol(classInternalName, "info");
}
public static String infoStructSymbol(String classInternalName) {
return classSymbol(classInternalName, "infostruct");
}
public static String typeInfoSymbol(String classInternalName) {
return classSymbol(classInternalName, "typeinfo");
}
public static String vtableSymbol(String classInternalName) {
return classSymbol(classInternalName, "vtable");
}
public static String itableSymbol(String classInternalName) {
return classSymbol(classInternalName, "itable");
}
public static String itableSymbol(String classInternalName, int n) {
return classSymbol(classInternalName, "itable" + n);
}
public static String itablesSymbol(String classInternalName) {
return classSymbol(classInternalName, "itables");
}
public static String debugInfoSymbol(String classInternalName) {
return classSymbol(classInternalName, "debuginfo");
}
public static String classAttributesSymbol(SootClass sootClass) {
return classSymbol(getInternalName(sootClass), "cattributes");
}
private static String classSymbol(String classInternalName, String type) {
return INTERNAL_SYMBOL_PREFIX + classInternalName.replace('/', '.') + "[" + type + "]";
}
public static String arrayinstanceofSymbol(String descriptor) {
return arraySymbol(descriptor, "arrayinstanceof");
}
public static String arraycheckcastSymbol(String descriptor) {
return arraySymbol(descriptor, "arraycheckcast");
}
public static String anewarraySymbol(String descriptor) {
return arraySymbol(descriptor, "anewarray");
}
public static String multianewarraySymbol(String descriptor) {
return arraySymbol(descriptor, "multianewarray");
}
public static String arrayldcSymbol(String descriptor) {
return arraySymbol(descriptor, "arrayldc");
}
public static String arrayPtrSymbol(String descriptor) {
return arraySymbol(descriptor, "arrayptr");
}
private static String arraySymbol(String descriptor, String type) {
return INTERNAL_SYMBOL_PREFIX + descriptor + "[" + type + "]";
}
public static String nativeCallMethodSymbol(String owner, String name, String desc) {
return methodSymbol(owner, name, desc, "NativeCall");
}
public static String trampolineMethodSymbol(Trampoline t, String caller, String owner, String name, String desc) {
return methodSymbol(owner, name, desc, t.getClass().getSimpleName() + "(" + caller + ")");
}
public static String trampolineMethodSymbol(Trampoline t, String caller, String owner, String name, String desc, String runtimeClass) {
return methodSymbol(owner, name, desc, t.getClass().getSimpleName() + "(" + caller + "," + runtimeClass + ")");
}
public static String trampolineFieldSymbol(Trampoline t, String caller, String owner, String name, String desc) {
return fieldSymbol(owner, name, desc, t.getClass().getSimpleName() + "(" + caller + ")");
}
public static String trampolineFieldSymbol(Trampoline t, String caller, String owner, String name, String desc, String runtimeClass) {
return fieldSymbol(owner, name, desc, t.getClass().getSimpleName() + "(" + caller + "," + runtimeClass + ")");
}
public static String trampolineSymbol(Trampoline t, String caller, String targetClass) {
return classSymbol(targetClass, t.getClass().getSimpleName() + "(" + caller + ")");
}
public static String ldcStringPtrSymbol(byte[] modUtf8) {
// NOTE: The symbols generated here are also used from C code in classinfo.c. Do not change.
return Strings.getStringVarName(modUtf8) + "_ptr";
}
public static String ldcStringSymbol(byte[] modUtf8) {
return INTERNAL_SYMBOL_PREFIX + Strings.getStringVarName(modUtf8) + "[ldcstring]";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy