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

org.robovm.compiler.FunctionBuilder Maven / Gradle / Ivy

/*
 * Copyright (C) 2012 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 static org.robovm.compiler.Symbols.*;
import static org.robovm.compiler.Types.*;
import static org.robovm.compiler.llvm.FunctionAttribute.*;
import static org.robovm.compiler.llvm.Linkage.*;
import static org.robovm.compiler.llvm.Type.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.robovm.compiler.clazz.Clazz;
import org.robovm.compiler.clazz.ClazzInfo;
import org.robovm.compiler.clazz.MethodInfo;
import org.robovm.compiler.llvm.Function;
import org.robovm.compiler.llvm.FunctionAttribute;
import org.robovm.compiler.llvm.FunctionRef;
import org.robovm.compiler.llvm.FunctionType;
import org.robovm.compiler.llvm.Linkage;
import org.robovm.compiler.llvm.Type;
import org.robovm.compiler.trampoline.Trampoline;

import soot.SootClass;
import soot.SootField;
import soot.SootMethod;

/**
 * Builds {@link Function} objects. Always adds {@link FunctionAttribute#nounwind}
 * to the function's attributes.
 */
public class FunctionBuilder {
    private FunctionType type;
    private String name;
    private Linkage linkage = null;
    private List attributes = new ArrayList();
    private String section = null;
    private List parameterNames = new ArrayList();
    
    public FunctionBuilder(Trampoline t) {
        this(t.getFunctionRef());
    }

    public FunctionBuilder(FunctionRef ref) {
        this(ref.getName(), ref.getType());
    }

    public FunctionBuilder(String name, FunctionRef ref) {
        this(name, ref.getType());
    }
    
    public FunctionBuilder(String name, FunctionType type) {
        this.name = name;
        this.type = type;
        attributes.add(FunctionAttribute.nounwind);
    }

    public FunctionBuilder name(String name) {
        this.name = name;
        return this;
    }
    
    public FunctionBuilder type(FunctionType type) {
        this.type = type;
        return this;
    }
    
    public FunctionBuilder attrib(FunctionAttribute a) {
        attributes.add(a);
        return this;
    }
    
    public FunctionBuilder attribs(FunctionAttribute ... a) {
        attributes.addAll(Arrays.asList(a));
        return this;
    }
    
    public FunctionBuilder paramName(String p) {
        parameterNames.add(p);
        return this;
    }
    
    public FunctionBuilder paramNames(String ... p) {
        parameterNames.addAll(Arrays.asList(p));
        return this;
    }
    
    public FunctionBuilder linkage(Linkage linkage) {
        this.linkage = linkage;
        return this;
    }

    public FunctionBuilder section(String section) {
        this.section = section;
        return this;
    }
    
    public Function build() {
        Type[] ptypes = type.getParameterTypes();
        for (int i = parameterNames.size(); i < ptypes.length; i++) {
            parameterNames.add("p" + i);
        }
        return new Function(linkage, 
                attributes.toArray(new FunctionAttribute[attributes.size()]), 
                section, name, type, parameterNames.toArray(new String[parameterNames.size()]));
    }
    
    public static Function allocator(SootClass sootClass) {
        return new FunctionBuilder(allocatorSymbol(getInternalName(sootClass)), new FunctionType(OBJECT_PTR, ENV_PTR))
                .linkage(_private).attribs(alwaysinline, optsize).build();
    }
    
    public static Function instanceOf(Clazz clazz) {
        return instanceOf(clazz.getInternalName());
    }
    public static Function instanceOf(SootClass sootClass) {
        return instanceOf(getInternalName(sootClass));
    }
    public static Function instanceOf(String internalName) {
        return new FunctionBuilder(instanceofSymbol(internalName), new FunctionType(I32, ENV_PTR, OBJECT_PTR))
                .linkage(external).attribs(alwaysinline, optsize).build();
    }
    
    public static Function checkcast(Clazz clazz) {
        return checkcast(clazz.getInternalName());
    }
    public static Function checkcast(SootClass sootClass) {
        return checkcast(getInternalName(sootClass));
    }
    public static Function checkcast(String internalName) {
        return new FunctionBuilder(checkcastSymbol(internalName), new FunctionType(OBJECT_PTR, ENV_PTR, OBJECT_PTR))
                .linkage(external).attribs(alwaysinline, optsize).build();
    }

    public static Function trycatchEnter(SootClass sootClass) {
        return new FunctionBuilder(trycatchenterSymbol(getInternalName(sootClass)), new FunctionType(OBJECT_PTR, ENV_PTR))
                .linkage(external).attribs(alwaysinline, optsize).build();
    }
    
    public static Function ldcInternal(String internalName) {
        return new FunctionBuilder(ldcInternalSymbol(internalName), new FunctionType(OBJECT_PTR, ENV_PTR))
                .linkage(_private).attribs(alwaysinline, optsize).build();
    }
    
    public static Function ldcInternal(SootClass sootClass) {
        return ldcInternal(getInternalName(sootClass));
    }
    
    public static Function ldcExternal(SootClass sootClass) {
        return new FunctionBuilder(ldcExternalSymbol(getInternalName(sootClass)), new FunctionType(OBJECT_PTR, ENV_PTR))
                .linkage(external).attribs(noinline, optsize).build();
    }
    
    public static Function getter(SootField field) {
        String name = getterSymbol(field);
        if (field.isStatic()) {
            return new FunctionBuilder(name, new FunctionType(getType(field.getType()), ENV_PTR))
                .linkage(_private).attribs(alwaysinline, optsize).build();
        } else {
            return new FunctionBuilder(name, new FunctionType(getType(field.getType()), ENV_PTR, OBJECT_PTR))
                .linkage(field.isPrivate() ? _private : external).attribs(alwaysinline, optsize).build();
        }
    }
    
    public static Function setter(SootField field) {
        String name = setterSymbol(field);
        if (field.isStatic()) {
            return new FunctionBuilder(name, new FunctionType(VOID, ENV_PTR, getType(field.getType())))
                .linkage(_private).attribs(alwaysinline, optsize).build();
        } else {
            return new FunctionBuilder(name, new FunctionType(VOID, ENV_PTR, OBJECT_PTR, getType(field.getType())))
                .linkage(field.isPrivate() || field.isFinal() ? _private : external).attribs(alwaysinline, optsize).build();
        }
    }
    
    public static Function clinitWrapper(FunctionRef targetFn) {
        return new FunctionBuilder(clinitWrapperSymbol(targetFn.getName()), targetFn)
                .linkage(external).attribs(noinline, optsize).build();
    }

    public static Function lookup(SootMethod method, boolean isWeak) {
        return new FunctionBuilder(lookupWrapperSymbol(method), 
                getFunctionType(method)).linkage(isWeak ? weak : external).build();
    }

    public static Function lookup(ClazzInfo ci, MethodInfo mi, boolean isWeak) {
        return new FunctionBuilder(
                lookupWrapperSymbol(ci.getInternalName(), mi.getName(), mi.getDesc()), 
                getFunctionType(mi.getDesc(),  mi.isStatic()))
            .linkage(isWeak ? weak : external).build();
    }

    public static Function synchronizedWrapper(SootMethod method) {
        return new FunctionBuilder(synchronizedWrapperSymbol(method), getFunctionType(method))
                .linkage(external).attribs(noinline, optsize).build();
    }
    
    public static Function method(SootMethod method, boolean weak) {
        return new FunctionBuilder(methodSymbol(method), getFunctionType(method)).linkage(weak ? Linkage.weak : external)
                .attribs(noinline, optsize).build();
    }

    public static Function info(String internalName) {
        return new FunctionBuilder(infoSymbol(internalName), new FunctionType(I8_PTR_PTR))
                .linkage(external).attribs(alwaysinline, optsize).build();
    }
    
    public static Function infoStruct(SootClass sootClass) {
        return info(getInternalName(sootClass));
    }
    
    public static Function callback(SootMethod method, FunctionType functionType) {
        return new FunctionBuilder(callbackSymbol(method), functionType)
                .linkage(internal).attribs(noinline, optsize).build();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy