All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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