Search in sources :

Example 6 with Label

use of org.robovm.compiler.llvm.Label in project robovm by robovm.

the class MethodCompiler method lookupSwitch.

private void lookupSwitch(LookupSwitchStmt stmt) {
    Map<IntegerConstant, BasicBlockRef> targets = new HashMap<IntegerConstant, BasicBlockRef>();
    for (int i = 0; i < stmt.getTargetCount(); i++) {
        int value = stmt.getLookupValue(i);
        Unit target = stmt.getTarget(i);
        targets.put(new IntegerConstant(value), function.newBasicBlockRef(new Label(target)));
    }
    BasicBlockRef def = function.newBasicBlockRef(new Label(stmt.getDefaultTarget()));
    Value key = immediate(stmt, (Immediate) stmt.getKey());
    function.add(new Switch(key, def, targets)).attach(stmt);
}
Also used : BasicBlockRef(org.robovm.compiler.llvm.BasicBlockRef) Switch(org.robovm.compiler.llvm.Switch) HashMap(java.util.HashMap) Label(org.robovm.compiler.llvm.Label) Value(org.robovm.compiler.llvm.Value) Unit(soot.Unit) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant)

Example 7 with Label

use of org.robovm.compiler.llvm.Label in project robovm by robovm.

the class GlobalValueMethodCompiler method doCompile.

protected Function doCompile(ModuleBuilder moduleBuilder, SootMethod method) {
    AnnotationTag globalValueAnnotation = getAnnotation(method, GLOBAL_VALUE);
    validateGlobalValueMethod(method, globalValueAnnotation);
    boolean optional = readBooleanElem(globalValueAnnotation, "optional", false);
    boolean dereference = readBooleanElem(globalValueAnnotation, "dereference", true);
    Function fn = createMethodFunction(method);
    moduleBuilder.addFunction(fn);
    Type valueType = getStructMemberType(method);
    // Load the address of the resolved @GlobalValue method
    Variable valuePtr = fn.newVariable(new PointerType(valueType));
    Global valuePtrPtr = new Global(Symbols.globalValuePtrSymbol(method), _private, new NullConstant(I8_PTR));
    moduleBuilder.addGlobal(valuePtrPtr);
    fn.add(new Load(valuePtr, new ConstantBitcast(valuePtrPtr.ref(), new PointerType(valuePtr.getType()))));
    Label nullLabel = new Label();
    Label notNullLabel = new Label();
    Variable nullCheck = fn.newVariable(I1);
    fn.add(new Icmp(nullCheck, Condition.eq, valuePtr.ref(), new NullConstant(valuePtr.getType())));
    fn.add(new Br(nullCheck.ref(), fn.newBasicBlockRef(nullLabel), fn.newBasicBlockRef(notNullLabel)));
    fn.newBasicBlock(nullLabel);
    VariableRef env = fn.getParameterRef(0);
    call(fn, BC_THROW_UNSATISIFED_LINK_ERROR, env, moduleBuilder.getString(String.format((optional ? "Optional " : "") + "@GlobalValue method %s.%s%s not bound", className, method.getName(), getDescriptor(method))));
    fn.add(new Unreachable());
    fn.newBasicBlock(notNullLabel);
    if (method.getParameterCount() == 0) {
        // Getter
        Value result = loadValueForGetter(method, fn, valueType, valuePtr.ref(), env, dereference, MarshalerFlags.CALL_TYPE_GLOBAL_VALUE);
        fn.add(new Ret(result));
    } else {
        // Setter
        // 'env' is parameter 0, the value we're interested in is at index 1
        Value value = fn.getParameterRef(1);
        storeValueForSetter(method, fn, valueType, valuePtr.ref(), env, value, MarshalerFlags.CALL_TYPE_GLOBAL_VALUE);
        fn.add(new Ret());
    }
    return fn;
}
Also used : Ret(org.robovm.compiler.llvm.Ret) Load(org.robovm.compiler.llvm.Load) VariableRef(org.robovm.compiler.llvm.VariableRef) Variable(org.robovm.compiler.llvm.Variable) ConstantBitcast(org.robovm.compiler.llvm.ConstantBitcast) Label(org.robovm.compiler.llvm.Label) NullConstant(org.robovm.compiler.llvm.NullConstant) PointerType(org.robovm.compiler.llvm.PointerType) Global(org.robovm.compiler.llvm.Global) Br(org.robovm.compiler.llvm.Br) AnnotationTag(soot.tagkit.AnnotationTag) Function(org.robovm.compiler.llvm.Function) PointerType(org.robovm.compiler.llvm.PointerType) Type(org.robovm.compiler.llvm.Type) VoidType(soot.VoidType) Unreachable(org.robovm.compiler.llvm.Unreachable) Value(org.robovm.compiler.llvm.Value) Icmp(org.robovm.compiler.llvm.Icmp)

Example 8 with Label

use of org.robovm.compiler.llvm.Label in project robovm by robovm.

the class NativeMethodCompiler method createNative.

private FunctionRef createNative(ModuleBuilder mb, SootMethod method) {
    String targetInternalName = getInternalName(method.getDeclaringClass());
    String methodName = method.getName();
    String methodDesc = getDescriptor(method);
    FunctionType nativeFunctionType = Types.getNativeFunctionType(methodDesc, method.isStatic());
    String shortName = mangleNativeMethod(targetInternalName, methodName);
    String longName = mangleNativeMethod(targetInternalName, methodName, methodDesc);
    /*
         * To support statically linked native method implementation we create
         * weak stub functions with the same names as the expected JNI functions
         * (long and short names). These will be discarded by the linker if
         * proper functions are available at link time.
         * 
         * The weak stub with the short JNI name just calls the weak stub with
         * the long name.
         * 
         * The weak stub with the long name calls _bcResolveNative() which will
         * try to resolve the native method against dynamically loaded JNI libs.
         * If _bcResolveNative() finds a matching symbol in a dynamic lib or an
         * implementation has previously been registered using JNI
         * RegisterNatives() that will be stored in the native method pointer
         * passed to it and returned. The stub will call the implementation
         * returned by _bcResolveNative(). If no implementation can be found
         * _bcResolveNative() throws an UnsatisfiedLinkError and doesn't return
         * to the stub.
         * 
         * The limitation of this approach is that RegisterNatives() only works
         * for dynamically linked native methods and can only be used prior to
         * the first call of such a method. Native methods can never be rewired
         * or unregistered.
         */
    /*
         * The function with the long JNI name. This is the one that calls
         * _bcResolveNative() and then calls the implementation.
         */
    Function fn = new FunctionBuilder(longName, nativeFunctionType).linkage(weak).build();
    Global g = new Global(Symbols.nativeMethodPtrSymbol(targetInternalName, methodName, methodDesc), new NullConstant(I8_PTR));
    mb.addGlobal(g);
    FunctionRef ldcFn = FunctionBuilder.ldcInternal(targetInternalName).ref();
    Value theClass = call(fn, ldcFn, fn.getParameterRef(0));
    Value implI8Ptr = call(fn, BC_RESOLVE_NATIVE, fn.getParameterRef(0), theClass, mb.getString(methodName), mb.getString(methodDesc), mb.getString(shortName), mb.getString(longName), g.ref());
    Variable nullTest = fn.newVariable(I1);
    fn.add(new Icmp(nullTest, Condition.ne, implI8Ptr, new NullConstant(I8_PTR)));
    Label trueLabel = new Label();
    Label falseLabel = new Label();
    fn.add(new Br(nullTest.ref(), fn.newBasicBlockRef(trueLabel), fn.newBasicBlockRef(falseLabel)));
    fn.newBasicBlock(falseLabel);
    if (fn.getType().getReturnType() instanceof IntegerType) {
        fn.add(new Ret(new IntegerConstant(0, (IntegerType) fn.getType().getReturnType())));
    } else if (fn.getType().getReturnType() instanceof FloatingPointType) {
        fn.add(new Ret(new FloatingPointConstant(0.0, (FloatingPointType) fn.getType().getReturnType())));
    } else if (fn.getType().getReturnType() instanceof PointerType) {
        fn.add(new Ret(new NullConstant((PointerType) fn.getType().getReturnType())));
    } else {
        fn.add(new Ret());
    }
    fn.newBasicBlock(trueLabel);
    Variable impl = fn.newVariable(nativeFunctionType);
    fn.add(new Bitcast(impl, implI8Ptr, impl.getType()));
    Value result = call(fn, impl.ref(), fn.getParameterRefs());
    fn.add(new Ret(result));
    mb.addFunction(fn);
    FunctionRef targetFn = fn.ref();
    if (!isLongNativeFunctionNameRequired(method)) {
        /*
             * Generate a function with the short JNI name. This just calls the
             * function with the long name.
             */
        Function fnShort = new FunctionBuilder(shortName, nativeFunctionType).linkage(weak).build();
        Value resultInner = call(fnShort, fn.ref(), fnShort.getParameterRefs());
        fnShort.add(new Ret(resultInner));
        mb.addFunction(fnShort);
        targetFn = fnShort.ref();
    }
    return targetFn;
}
Also used : Ret(org.robovm.compiler.llvm.Ret) Variable(org.robovm.compiler.llvm.Variable) FloatingPointConstant(org.robovm.compiler.llvm.FloatingPointConstant) FunctionType(org.robovm.compiler.llvm.FunctionType) Label(org.robovm.compiler.llvm.Label) NullConstant(org.robovm.compiler.llvm.NullConstant) PointerType(org.robovm.compiler.llvm.PointerType) FloatingPointType(org.robovm.compiler.llvm.FloatingPointType) Global(org.robovm.compiler.llvm.Global) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) Br(org.robovm.compiler.llvm.Br) IntegerType(org.robovm.compiler.llvm.IntegerType) Function(org.robovm.compiler.llvm.Function) Bitcast(org.robovm.compiler.llvm.Bitcast) Value(org.robovm.compiler.llvm.Value) FunctionRef(org.robovm.compiler.llvm.FunctionRef) Icmp(org.robovm.compiler.llvm.Icmp)

Example 9 with Label

use of org.robovm.compiler.llvm.Label in project robovm by robovm.

the class MethodCompiler method if_.

private void if_(IfStmt stmt) {
    ConditionExpr condition = (ConditionExpr) stmt.getCondition();
    Value op1 = immediate(stmt, (Immediate) condition.getOp1());
    Value op2 = immediate(stmt, (Immediate) condition.getOp2());
    Icmp.Condition c = null;
    if (condition instanceof EqExpr) {
        c = Icmp.Condition.eq;
    } else if (condition instanceof NeExpr) {
        c = Icmp.Condition.ne;
    } else if (condition instanceof GtExpr) {
        c = Icmp.Condition.sgt;
    } else if (condition instanceof LtExpr) {
        c = Icmp.Condition.slt;
    } else if (condition instanceof GeExpr) {
        c = Icmp.Condition.sge;
    } else if (condition instanceof LeExpr) {
        c = Icmp.Condition.sle;
    }
    Variable result = function.newVariable(Type.I1);
    function.add(new Icmp(result, c, op1, op2)).attach(stmt);
    Unit nextUnit = sootMethod.getActiveBody().getUnits().getSuccOf(stmt);
    function.add(new Br(new VariableRef(result), function.newBasicBlockRef(new Label(stmt.getTarget())), function.newBasicBlockRef(new Label(nextUnit)))).attach(stmt);
}
Also used : VariableRef(org.robovm.compiler.llvm.VariableRef) Condition(org.robovm.compiler.llvm.Icmp.Condition) Variable(org.robovm.compiler.llvm.Variable) NeExpr(soot.jimple.NeExpr) Label(org.robovm.compiler.llvm.Label) GtExpr(soot.jimple.GtExpr) LtExpr(soot.jimple.LtExpr) GeExpr(soot.jimple.GeExpr) Unit(soot.Unit) LeExpr(soot.jimple.LeExpr) Br(org.robovm.compiler.llvm.Br) EqExpr(soot.jimple.EqExpr) ConditionExpr(soot.jimple.ConditionExpr) Value(org.robovm.compiler.llvm.Value) Icmp(org.robovm.compiler.llvm.Icmp)

Example 10 with Label

use of org.robovm.compiler.llvm.Label in project robovm by robovm.

the class AbstractMethodCompiler method compileSynchronizedWrapper.

private void compileSynchronizedWrapper(ModuleBuilder moduleBuilder, SootMethod method) {
    String targetName = Symbols.methodSymbol(method);
    Function syncFn = FunctionBuilder.synchronizedWrapper(method);
    moduleBuilder.addFunction(syncFn);
    FunctionType functionType = syncFn.getType();
    FunctionRef target = new FunctionRef(targetName, functionType);
    Value monitor = null;
    if (method.isStatic()) {
        FunctionRef fn = FunctionBuilder.ldcInternal(sootMethod.getDeclaringClass()).ref();
        monitor = call(syncFn, fn, syncFn.getParameterRef(0));
    } else {
        monitor = syncFn.getParameterRef(1);
    }
    call(syncFn, MONITORENTER, syncFn.getParameterRef(0), monitor);
    BasicBlockRef bbSuccess = syncFn.newBasicBlockRef(new Label("success"));
    BasicBlockRef bbFailure = syncFn.newBasicBlockRef(new Label("failure"));
    trycatchAllEnter(syncFn, bbSuccess, bbFailure);
    syncFn.newBasicBlock(bbSuccess.getLabel());
    Value result = call(syncFn, target, syncFn.getParameterRefs());
    trycatchLeave(syncFn);
    call(syncFn, MONITOREXIT, syncFn.getParameterRef(0), monitor);
    syncFn.add(new Ret(result));
    syncFn.newBasicBlock(bbFailure.getLabel());
    trycatchLeave(syncFn);
    call(syncFn, MONITOREXIT, syncFn.getParameterRef(0), monitor);
    call(syncFn, BC_THROW_IF_EXCEPTION_OCCURRED, syncFn.getParameterRef(0));
    syncFn.add(new Unreachable());
}
Also used : Ret(org.robovm.compiler.llvm.Ret) Function(org.robovm.compiler.llvm.Function) BasicBlockRef(org.robovm.compiler.llvm.BasicBlockRef) Unreachable(org.robovm.compiler.llvm.Unreachable) FunctionType(org.robovm.compiler.llvm.FunctionType) Value(org.robovm.compiler.llvm.Value) Label(org.robovm.compiler.llvm.Label) FunctionRef(org.robovm.compiler.llvm.FunctionRef)

Aggregations

Label (org.robovm.compiler.llvm.Label)10 Value (org.robovm.compiler.llvm.Value)10 IntegerConstant (org.robovm.compiler.llvm.IntegerConstant)7 Ret (org.robovm.compiler.llvm.Ret)7 BasicBlockRef (org.robovm.compiler.llvm.BasicBlockRef)6 Br (org.robovm.compiler.llvm.Br)6 Function (org.robovm.compiler.llvm.Function)6 Variable (org.robovm.compiler.llvm.Variable)6 FunctionType (org.robovm.compiler.llvm.FunctionType)5 Icmp (org.robovm.compiler.llvm.Icmp)5 PointerType (org.robovm.compiler.llvm.PointerType)5 Bitcast (org.robovm.compiler.llvm.Bitcast)4 ConstantBitcast (org.robovm.compiler.llvm.ConstantBitcast)4 FunctionRef (org.robovm.compiler.llvm.FunctionRef)4 Global (org.robovm.compiler.llvm.Global)4 NullConstant (org.robovm.compiler.llvm.NullConstant)4 Type (org.robovm.compiler.llvm.Type)4 Unreachable (org.robovm.compiler.llvm.Unreachable)4 Unit (soot.Unit)4 ArrayList (java.util.ArrayList)3