Search in sources :

Example 1 with PrimType

use of soot.PrimType in project robovm by robovm.

the class ObjCBlockPlugin method generateTargetMethod.

private void generateTargetMethod(String owner, SootMethod targetMethod, Type[] actualGenericTypes, soot.Type[] actualRawTypes, soot.Type[] unboxedTypes, Set<String> usedBoxMethods, Set<String> usedUnboxMethods, ClassWriter cw) {
    String name = targetMethod.getName();
    String signature = getGenericSignature(Arrays.asList(actualGenericTypes).subList(1, actualGenericTypes.length), actualGenericTypes[0]);
    String desc = getDescriptor(targetMethod);
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, name, desc, signature, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, owner, "objCBlock", "L" + getInternalName(org_robovm_objc_ObjCBlock) + ";");
    mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(org_robovm_objc_ObjCBlock), "invoke", "()J");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, owner, "objCBlock", "L" + getInternalName(org_robovm_objc_ObjCBlock) + ";");
    for (int i = 1, var = 1; i < actualRawTypes.length; i++, var++) {
        soot.Type from = actualRawTypes[i];
        if (from == LongType.v()) {
            mv.visitVarInsn(LLOAD, var);
            // longs need 2 slots
            var++;
        } else if (from == FloatType.v()) {
            mv.visitVarInsn(FLOAD, var);
        } else if (from == DoubleType.v()) {
            mv.visitVarInsn(DLOAD, var);
            // doubles need 2 slots
            var++;
        } else if (from instanceof PrimType) {
            // boolean, byte, short, char and int are loaded using ILOAD
            mv.visitVarInsn(ILOAD, var);
        } else {
            // Reference
            mv.visitVarInsn(ALOAD, var);
        }
        soot.Type to = unboxedTypes[i];
        if (from != to) {
            mv.visitTypeInsn(CHECKCAST, getInternalName(from));
            // Unbox the value on the top of the stack.
            String unboxDesc = getDescriptor(Collections.singletonList(from), to);
            usedUnboxMethods.add(unboxDesc);
            mv.visitMethodInsn(INVOKESTATIC, owner, "unbox", unboxDesc);
        }
    }
    // Now the function pointer, block and all arguments are on the stack 
    // (unboxed if needed). Call the invoke() bridge method.
    List<soot.Type> paramTypes = new ArrayList<>();
    paramTypes.add(LongType.v());
    paramTypes.add(org_robovm_objc_ObjCBlock.getType());
    paramTypes.addAll(Arrays.asList(unboxedTypes).subList(1, unboxedTypes.length));
    mv.visitMethodInsn(INVOKESTATIC, owner, "invoke", getDescriptor(paramTypes, unboxedTypes[0]));
    if (unboxedTypes[0] != actualRawTypes[0]) {
        // Box the value on the top of the stack.
        String boxDesc = getDescriptor(Collections.singletonList(unboxedTypes[0]), actualRawTypes[0]);
        usedBoxMethods.add(boxDesc);
        mv.visitMethodInsn(INVOKESTATIC, owner, "box", boxDesc);
    }
    if (actualRawTypes[0] == VoidType.v()) {
        mv.visitInsn(RETURN);
    } else if (actualRawTypes[0] == LongType.v()) {
        mv.visitInsn(LRETURN);
    } else if (actualRawTypes[0] == FloatType.v()) {
        mv.visitInsn(FRETURN);
    } else if (actualRawTypes[0] == DoubleType.v()) {
        mv.visitInsn(DRETURN);
    } else if (actualRawTypes[0] instanceof PrimType) {
        mv.visitInsn(IRETURN);
    } else {
        mv.visitInsn(ARETURN);
    }
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}
Also used : RefType(soot.RefType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) SootTypeType(org.robovm.compiler.util.generic.SootTypeType) WildcardType(org.robovm.compiler.util.generic.WildcardType) SootMethodType(org.robovm.compiler.util.generic.SootMethodType) SootClassType(org.robovm.compiler.util.generic.SootClassType) ByteType(soot.ByteType) Type(org.robovm.compiler.util.generic.Type) DoubleType(soot.DoubleType) GenericArrayType(org.robovm.compiler.util.generic.GenericArrayType) FloatType(soot.FloatType) IntType(soot.IntType) ImplForType(org.robovm.compiler.util.generic.ImplForType) CharType(soot.CharType) LongType(soot.LongType) ParameterizedType(org.robovm.compiler.util.generic.ParameterizedType) PrimType(soot.PrimType) VoidType(soot.VoidType) ArrayList(java.util.ArrayList) PrimType(soot.PrimType) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 2 with PrimType

use of soot.PrimType in project robovm by robovm.

the class MethodCompiler method assign.

private void assign(DefinitionStmt stmt) {
    /*
         * leftOp is either a Local, an ArrayRef or a FieldRef
         * rightOp is either a Local, a Ref, or an Expr
         */
    soot.Value rightOp = stmt.getRightOp();
    Value result;
    if (rightOp instanceof Immediate) {
        Immediate immediate = (Immediate) rightOp;
        result = immediate(stmt, immediate);
    } else if (rightOp instanceof ThisRef) {
        result = function.getParameterRef(1);
    } else if (rightOp instanceof ParameterRef) {
        ParameterRef ref = (ParameterRef) rightOp;
        int index = (sootMethod.isStatic() ? 1 : 2) + ref.getIndex();
        Value p = new VariableRef("p" + index, getType(ref.getType()));
        result = widenToI32Value(stmt, p, isUnsigned(ref.getType()));
    } else if (rightOp instanceof CaughtExceptionRef) {
        result = call(stmt, BC_EXCEPTION_CLEAR, env);
    } else if (rightOp instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) rightOp;
        VariableRef base = (VariableRef) immediate(stmt, (Immediate) ref.getBase());
        if (ref.getType() instanceof NullType) {
            // The base value is always null. Do a null check which will
            // always throw NPE.
            checkNull(stmt, base);
            return;
        } else {
            Value index = immediate(stmt, (Immediate) ref.getIndex());
            checkNull(stmt, base);
            checkBounds(stmt, base, index);
            result = call(stmt, getArrayLoad(ref.getType()), base, index);
            result = widenToI32Value(stmt, result, isUnsigned(ref.getType()));
        }
    } else if (rightOp instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) rightOp;
        Value base = immediate(stmt, (Immediate) ref.getBase());
        checkNull(stmt, base);
        FunctionRef fn = null;
        if (canAccessDirectly(ref)) {
            fn = new FunctionRef(Symbols.getterSymbol(ref.getFieldRef()), new FunctionType(getType(ref.getType()), ENV_PTR, OBJECT_PTR));
        } else {
            soot.Type runtimeType = ref.getBase().getType();
            String targetClassName = getInternalName(ref.getFieldRef().declaringClass());
            String runtimeClassName = runtimeType == NullType.v() ? targetClassName : getInternalName(runtimeType);
            Trampoline trampoline = new GetField(this.className, targetClassName, ref.getFieldRef().name(), getDescriptor(ref.getFieldRef().type()), runtimeClassName);
            trampolines.add(trampoline);
            fn = trampoline.getFunctionRef();
        }
        result = call(stmt, fn, env, base);
        result = widenToI32Value(stmt, result, isUnsigned(ref.getType()));
    } else if (rightOp instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) rightOp;
        FunctionRef fn = config.isDebug() ? null : Intrinsics.getIntrinsic(sootMethod, stmt);
        if (fn == null) {
            if (canAccessDirectly(ref)) {
                fn = new FunctionRef(Symbols.getterSymbol(ref.getFieldRef()), new FunctionType(getType(ref.getType()), ENV_PTR));
            } else {
                String targetClassName = getInternalName(ref.getFieldRef().declaringClass());
                Trampoline trampoline = new GetStatic(this.className, targetClassName, ref.getFieldRef().name(), getDescriptor(ref.getFieldRef().type()));
                trampolines.add(trampoline);
                fn = trampoline.getFunctionRef();
            }
        }
        result = call(stmt, fn, env);
        result = widenToI32Value(stmt, result, isUnsigned(ref.getType()));
    } else if (rightOp instanceof Expr) {
        if (rightOp instanceof BinopExpr) {
            BinopExpr expr = (BinopExpr) rightOp;
            Type rightType = getLocalType(expr.getType());
            Variable resultVar = function.newVariable(rightType);
            result = resultVar.ref();
            Value op1 = immediate(stmt, (Immediate) expr.getOp1());
            Value op2 = immediate(stmt, (Immediate) expr.getOp2());
            if (rightOp instanceof AddExpr) {
                if (rightType instanceof IntegerType) {
                    function.add(new Add(resultVar, op1, op2)).attach(stmt);
                } else {
                    function.add(new Fadd(resultVar, op1, op2)).attach(stmt);
                }
            } else if (rightOp instanceof AndExpr) {
                function.add(new And(resultVar, op1, op2)).attach(stmt);
            } else if (rightOp instanceof CmpExpr) {
                Variable t1 = function.newVariable(I1);
                Variable t2 = function.newVariable(I1);
                Variable t3 = function.newVariable(resultVar.getType());
                Variable t4 = function.newVariable(resultVar.getType());
                function.add(new Icmp(t1, Condition.slt, op1, op2)).attach(stmt);
                function.add(new Icmp(t2, Condition.sgt, op1, op2)).attach(stmt);
                function.add(new Zext(t3, new VariableRef(t1), resultVar.getType())).attach(stmt);
                function.add(new Zext(t4, new VariableRef(t2), resultVar.getType())).attach(stmt);
                function.add(new Sub(resultVar, new VariableRef(t4), new VariableRef(t3))).attach(stmt);
            } else if (rightOp instanceof DivExpr) {
                if (rightType instanceof IntegerType) {
                    FunctionRef f = rightType == I64 ? LDIV : IDIV;
                    result = call(stmt, f, env, op1, op2);
                } else {
                    // float or double
                    function.add(new Fdiv(resultVar, op1, op2)).attach(stmt);
                }
            } else if (rightOp instanceof MulExpr) {
                if (rightType instanceof IntegerType) {
                    function.add(new Mul(resultVar, op1, op2)).attach(stmt);
                } else {
                    function.add(new Fmul(resultVar, op1, op2)).attach(stmt);
                }
            } else if (rightOp instanceof OrExpr) {
                function.add(new Or(resultVar, op1, op2)).attach(stmt);
            } else if (rightOp instanceof RemExpr) {
                if (rightType instanceof IntegerType) {
                    FunctionRef f = rightType == I64 ? LREM : IREM;
                    result = call(stmt, f, env, op1, op2);
                } else {
                    FunctionRef f = rightType == DOUBLE ? DREM : FREM;
                    result = call(stmt, f, env, op1, op2);
                }
            } else if (rightOp instanceof ShlExpr || rightOp instanceof ShrExpr || rightOp instanceof UshrExpr) {
                IntegerType type = (IntegerType) op1.getType();
                int bits = type.getBits();
                Variable t = function.newVariable(op2.getType());
                function.add(new And(t, op2, new IntegerConstant(bits - 1, (IntegerType) op2.getType()))).attach(stmt);
                Value shift = t.ref();
                if (((IntegerType) shift.getType()).getBits() < bits) {
                    Variable tmp = function.newVariable(type);
                    function.add(new Zext(tmp, shift, type)).attach(stmt);
                    shift = tmp.ref();
                }
                if (rightOp instanceof ShlExpr) {
                    function.add(new Shl(resultVar, op1, shift)).attach(stmt);
                } else if (rightOp instanceof ShrExpr) {
                    function.add(new Ashr(resultVar, op1, shift)).attach(stmt);
                } else {
                    function.add(new Lshr(resultVar, op1, shift)).attach(stmt);
                }
            } else if (rightOp instanceof SubExpr) {
                if (rightType instanceof IntegerType) {
                    function.add(new Sub(resultVar, op1, op2)).attach(stmt);
                } else {
                    function.add(new Fsub(resultVar, op1, op2)).attach(stmt);
                }
            } else if (rightOp instanceof XorExpr) {
                function.add(new Xor(resultVar, op1, op2)).attach(stmt);
            } else if (rightOp instanceof XorExpr) {
                function.add(new Xor(resultVar, op1, op2)).attach(stmt);
            } else if (rightOp instanceof CmplExpr) {
                FunctionRef f = op1.getType() == FLOAT ? FCMPL : DCMPL;
                function.add(new Call(resultVar, f, op1, op2)).attach(stmt);
            } else if (rightOp instanceof CmpgExpr) {
                FunctionRef f = op1.getType() == FLOAT ? FCMPG : DCMPG;
                function.add(new Call(resultVar, f, op1, op2)).attach(stmt);
            } else {
                throw new IllegalArgumentException("Unknown type for rightOp: " + rightOp.getClass());
            }
        } else if (rightOp instanceof CastExpr) {
            Value op = immediate(stmt, (Immediate) ((CastExpr) rightOp).getOp());
            soot.Type sootTargetType = ((CastExpr) rightOp).getCastType();
            soot.Type sootSourceType = ((CastExpr) rightOp).getOp().getType();
            if (sootTargetType instanceof PrimType) {
                Type targetType = getType(sootTargetType);
                Type sourceType = getType(sootSourceType);
                if (targetType instanceof IntegerType && sourceType instanceof IntegerType) {
                    // op is at least I32 and has already been widened if source type had fewer bits then I32
                    IntegerType toType = (IntegerType) targetType;
                    IntegerType fromType = (IntegerType) op.getType();
                    Variable v = function.newVariable(toType);
                    if (fromType.getBits() < toType.getBits()) {
                        // Widening
                        if (isUnsigned(sootSourceType)) {
                            function.add(new Zext(v, op, toType)).attach(stmt);
                        } else {
                            function.add(new Sext(v, op, toType)).attach(stmt);
                        }
                    } else if (fromType.getBits() == toType.getBits()) {
                        function.add(new Bitcast(v, op, toType)).attach(stmt);
                    } else {
                        // Narrow
                        function.add(new Trunc(v, op, toType)).attach(stmt);
                    }
                    result = widenToI32Value(stmt, v.ref(), isUnsigned(sootTargetType));
                } else if (targetType instanceof FloatingPointType && sourceType instanceof IntegerType) {
                    // we always to a signed conversion since if op is char it has already been zero extended to I32
                    Variable v = function.newVariable(targetType);
                    function.add(new Sitofp(v, op, targetType)).attach(stmt);
                    result = v.ref();
                } else if (targetType instanceof FloatingPointType && sourceType instanceof FloatingPointType) {
                    Variable v = function.newVariable(targetType);
                    if (targetType == FLOAT && sourceType == DOUBLE) {
                        function.add(new Fptrunc(v, op, targetType)).attach(stmt);
                    } else if (targetType == DOUBLE && sourceType == FLOAT) {
                        function.add(new Fpext(v, op, targetType)).attach(stmt);
                    } else {
                        function.add(new Bitcast(v, op, targetType)).attach(stmt);
                    }
                    result = v.ref();
                } else {
                    // F2I, F2L, D2I, D2L
                    FunctionRef f = null;
                    if (targetType == I32 && sourceType == FLOAT) {
                        f = F2I;
                    } else if (targetType == I64 && sourceType == FLOAT) {
                        f = F2L;
                    } else if (targetType == I32 && sourceType == DOUBLE) {
                        f = D2I;
                    } else if (targetType == I64 && sourceType == DOUBLE) {
                        f = D2L;
                    } else {
                        throw new IllegalArgumentException();
                    }
                    Variable v = function.newVariable(targetType);
                    function.add(new Call(v, f, op)).attach(stmt);
                    result = v.ref();
                }
            } else {
                if (sootTargetType instanceof soot.ArrayType && ((soot.ArrayType) sootTargetType).getElementType() instanceof PrimType) {
                    soot.Type primType = ((soot.ArrayType) sootTargetType).getElementType();
                    GlobalRef arrayClassPtr = new GlobalRef("array_" + getDescriptor(primType), CLASS_PTR);
                    Variable arrayClass = function.newVariable(CLASS_PTR);
                    function.add(new Load(arrayClass, arrayClassPtr)).attach(stmt);
                    result = call(stmt, CHECKCAST_PRIM_ARRAY, env, arrayClass.ref(), op);
                } else {
                    String targetClassName = getInternalName(sootTargetType);
                    Trampoline trampoline = new Checkcast(this.className, targetClassName);
                    trampolines.add(trampoline);
                    result = call(stmt, trampoline.getFunctionRef(), env, op);
                }
            }
        } else if (rightOp instanceof InstanceOfExpr) {
            Value op = immediate(stmt, (Immediate) ((InstanceOfExpr) rightOp).getOp());
            soot.Type checkType = ((InstanceOfExpr) rightOp).getCheckType();
            if (checkType instanceof soot.ArrayType && ((soot.ArrayType) checkType).getElementType() instanceof PrimType) {
                soot.Type primType = ((soot.ArrayType) checkType).getElementType();
                GlobalRef arrayClassPtr = new GlobalRef("array_" + getDescriptor(primType), CLASS_PTR);
                Variable arrayClass = function.newVariable(CLASS_PTR);
                function.add(new Load(arrayClass, arrayClassPtr)).attach(stmt);
                result = call(stmt, INSTANCEOF_PRIM_ARRAY, env, arrayClass.ref(), op);
            } else {
                String targetClassName = getInternalName(checkType);
                Trampoline trampoline = new Instanceof(this.className, targetClassName);
                trampolines.add(trampoline);
                result = call(stmt, trampoline.getFunctionRef(), env, op);
            }
        } else if (rightOp instanceof NewExpr) {
            String targetClassName = getInternalName(((NewExpr) rightOp).getBaseType());
            FunctionRef fn = null;
            if (targetClassName.equals(this.className)) {
                fn = FunctionBuilder.allocator(sootMethod.getDeclaringClass()).ref();
            } else {
                Trampoline trampoline = new New(this.className, targetClassName);
                trampolines.add(trampoline);
                fn = trampoline.getFunctionRef();
            }
            result = call(stmt, fn, env);
        } else if (rightOp instanceof NewArrayExpr) {
            NewArrayExpr expr = (NewArrayExpr) rightOp;
            Value size = immediate(stmt, (Immediate) expr.getSize());
            if (expr.getBaseType() instanceof PrimType) {
                result = call(stmt, getNewArray(expr.getBaseType()), env, size);
            } else {
                String targetClassName = getInternalName(expr.getType());
                Trampoline trampoline = new Anewarray(this.className, targetClassName);
                trampolines.add(trampoline);
                result = call(stmt, trampoline.getFunctionRef(), env, size);
            }
        } else if (rightOp instanceof NewMultiArrayExpr) {
            NewMultiArrayExpr expr = (NewMultiArrayExpr) rightOp;
            if (expr.getBaseType().numDimensions == 1 && expr.getBaseType().getElementType() instanceof PrimType) {
                Value size = immediate(stmt, (Immediate) expr.getSize(0));
                result = call(stmt, getNewArray(expr.getBaseType().getElementType()), env, size);
            } else {
                for (int i = 0; i < expr.getSizeCount(); i++) {
                    Value size = immediate(stmt, (Immediate) expr.getSize(i));
                    Variable ptr = function.newVariable(new PointerType(I32));
                    function.add(new Getelementptr(ptr, dims.ref(), 0, i)).attach(stmt);
                    function.add(new Store(size, ptr.ref())).attach(stmt);
                }
                Variable dimsI32 = function.newVariable(new PointerType(I32));
                function.add(new Bitcast(dimsI32, dims.ref(), dimsI32.getType())).attach(stmt);
                String targetClassName = getInternalName(expr.getType());
                Trampoline trampoline = new Multianewarray(this.className, targetClassName);
                trampolines.add(trampoline);
                result = call(stmt, trampoline.getFunctionRef(), env, new IntegerConstant(expr.getSizeCount()), dimsI32.ref());
            }
        } else if (rightOp instanceof InvokeExpr) {
            result = invokeExpr(stmt, (InvokeExpr) rightOp);
        } else if (rightOp instanceof LengthExpr) {
            Value op = immediate(stmt, (Immediate) ((LengthExpr) rightOp).getOp());
            checkNull(stmt, op);
            Variable v = function.newVariable(I32);
            function.add(new Call(v, ARRAY_LENGTH, op)).attach(stmt);
            result = v.ref();
        } else if (rightOp instanceof NegExpr) {
            NegExpr expr = (NegExpr) rightOp;
            Value op = immediate(stmt, (Immediate) expr.getOp());
            Type rightType = op.getType();
            Variable v = function.newVariable(op.getType());
            if (rightType instanceof IntegerType) {
                function.add(new Sub(v, new IntegerConstant(0, (IntegerType) rightType), op)).attach(stmt);
            } else {
                function.add(new Fmul(v, new FloatingPointConstant(-1.0, (FloatingPointType) rightType), op)).attach(stmt);
            }
            result = v.ref();
        } else {
            throw new IllegalArgumentException("Unknown type for rightOp: " + rightOp.getClass());
        }
    } else {
        throw new IllegalArgumentException("Unknown type for rightOp: " + rightOp.getClass());
    }
    soot.Value leftOp = stmt.getLeftOp();
    if (leftOp instanceof Local) {
        Local local = (Local) leftOp;
        VariableRef v = new VariableRef(local.getName(), new PointerType(getLocalType(leftOp.getType())));
        function.add(new Store(result, v, !sootMethod.getActiveBody().getTraps().isEmpty())).attach(stmt);
    } else {
        Type leftType = getType(leftOp.getType());
        Value narrowedResult = narrowFromI32Value(stmt, leftType, result);
        if (leftOp instanceof ArrayRef) {
            ArrayRef ref = (ArrayRef) leftOp;
            VariableRef base = (VariableRef) immediate(stmt, (Immediate) ref.getBase());
            Value index = immediate(stmt, (Immediate) ref.getIndex());
            checkNull(stmt, base);
            checkBounds(stmt, base, index);
            if (leftOp.getType() instanceof RefLikeType) {
                call(stmt, BC_SET_OBJECT_ARRAY_ELEMENT, env, base, index, narrowedResult);
            } else {
                call(stmt, getArrayStore(leftOp.getType()), base, index, narrowedResult);
            }
        } else if (leftOp instanceof InstanceFieldRef) {
            InstanceFieldRef ref = (InstanceFieldRef) leftOp;
            Value base = immediate(stmt, (Immediate) ref.getBase());
            checkNull(stmt, base);
            FunctionRef fn = null;
            if (canAccessDirectly(ref)) {
                fn = new FunctionRef(Symbols.setterSymbol(ref.getFieldRef()), new FunctionType(VOID, ENV_PTR, OBJECT_PTR, getType(ref.getType())));
            } else {
                soot.Type runtimeType = ref.getBase().getType();
                String targetClassName = getInternalName(ref.getFieldRef().declaringClass());
                String runtimeClassName = runtimeType == NullType.v() ? targetClassName : getInternalName(runtimeType);
                Trampoline trampoline = new PutField(this.className, targetClassName, ref.getFieldRef().name(), getDescriptor(ref.getFieldRef().type()), runtimeClassName);
                trampolines.add(trampoline);
                fn = trampoline.getFunctionRef();
            }
            call(stmt, fn, env, base, narrowedResult);
        } else if (leftOp instanceof StaticFieldRef) {
            StaticFieldRef ref = (StaticFieldRef) leftOp;
            FunctionRef fn = null;
            if (canAccessDirectly(ref)) {
                fn = new FunctionRef(Symbols.setterSymbol(ref.getFieldRef()), new FunctionType(VOID, ENV_PTR, getType(ref.getType())));
            } else {
                String targetClassName = getInternalName(ref.getFieldRef().declaringClass());
                Trampoline trampoline = new PutStatic(this.className, targetClassName, ref.getFieldRef().name(), getDescriptor(ref.getFieldRef().type()));
                trampolines.add(trampoline);
                fn = trampoline.getFunctionRef();
            }
            call(stmt, fn, env, narrowedResult);
        } else {
            throw new IllegalArgumentException("Unknown type for leftOp: " + leftOp.getClass());
        }
    }
}
Also used : Add(org.robovm.compiler.llvm.Add) AndExpr(soot.jimple.AndExpr) New(org.robovm.compiler.trampoline.New) Or(org.robovm.compiler.llvm.Or) Store(org.robovm.compiler.llvm.Store) FloatingPointType(org.robovm.compiler.llvm.FloatingPointType) ArrayType(org.robovm.compiler.llvm.ArrayType) RefLikeType(soot.RefLikeType) GetStatic(org.robovm.compiler.trampoline.GetStatic) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) Shl(org.robovm.compiler.llvm.Shl) CastExpr(soot.jimple.CastExpr) PrimType(soot.PrimType) Fsub(org.robovm.compiler.llvm.Fsub) ShlExpr(soot.jimple.ShlExpr) Checkcast(org.robovm.compiler.trampoline.Checkcast) FunctionRef(org.robovm.compiler.llvm.FunctionRef) Fmul(org.robovm.compiler.llvm.Fmul) Sub(org.robovm.compiler.llvm.Sub) GetField(org.robovm.compiler.trampoline.GetField) Load(org.robovm.compiler.llvm.Load) FloatingPointConstant(org.robovm.compiler.llvm.FloatingPointConstant) Mul(org.robovm.compiler.llvm.Mul) XorExpr(soot.jimple.XorExpr) Fptrunc(org.robovm.compiler.llvm.Fptrunc) Local(soot.Local) AddExpr(soot.jimple.AddExpr) Fdiv(org.robovm.compiler.llvm.Fdiv) Zext(org.robovm.compiler.llvm.Zext) InstanceOfExpr(soot.jimple.InstanceOfExpr) OrExpr(soot.jimple.OrExpr) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) StaticFieldRef(soot.jimple.StaticFieldRef) NegExpr(soot.jimple.NegExpr) UshrExpr(soot.jimple.UshrExpr) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) GeExpr(soot.jimple.GeExpr) DivExpr(soot.jimple.DivExpr) ConditionExpr(soot.jimple.ConditionExpr) SubExpr(soot.jimple.SubExpr) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) OrExpr(soot.jimple.OrExpr) Expr(soot.jimple.Expr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) LengthExpr(soot.jimple.LengthExpr) ShlExpr(soot.jimple.ShlExpr) NeExpr(soot.jimple.NeExpr) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) CmpExpr(soot.jimple.CmpExpr) MulExpr(soot.jimple.MulExpr) BinopExpr(soot.jimple.BinopExpr) LtExpr(soot.jimple.LtExpr) ShrExpr(soot.jimple.ShrExpr) CmpgExpr(soot.jimple.CmpgExpr) EqExpr(soot.jimple.EqExpr) NewArrayExpr(soot.jimple.NewArrayExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) AndExpr(soot.jimple.AndExpr) LeExpr(soot.jimple.LeExpr) CastExpr(soot.jimple.CastExpr) InvokeExpr(soot.jimple.InvokeExpr) NewExpr(soot.jimple.NewExpr) CmplExpr(soot.jimple.CmplExpr) InstanceOfExpr(soot.jimple.InstanceOfExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) RemExpr(soot.jimple.RemExpr) XorExpr(soot.jimple.XorExpr) AddExpr(soot.jimple.AddExpr) GtExpr(soot.jimple.GtExpr) Bitcast(org.robovm.compiler.llvm.Bitcast) ConstantBitcast(org.robovm.compiler.llvm.ConstantBitcast) NewArrayExpr(soot.jimple.NewArrayExpr) And(org.robovm.compiler.llvm.And) CmpExpr(soot.jimple.CmpExpr) RemExpr(soot.jimple.RemExpr) ShrExpr(soot.jimple.ShrExpr) Value(org.robovm.compiler.llvm.Value) NewExpr(soot.jimple.NewExpr) Fadd(org.robovm.compiler.llvm.Fadd) Xor(org.robovm.compiler.llvm.Xor) NullType(soot.NullType) CmplExpr(soot.jimple.CmplExpr) BinopExpr(soot.jimple.BinopExpr) MulExpr(soot.jimple.MulExpr) GlobalRef(org.robovm.compiler.llvm.GlobalRef) VariableRef(org.robovm.compiler.llvm.VariableRef) Variable(org.robovm.compiler.llvm.Variable) Ashr(org.robovm.compiler.llvm.Ashr) CaughtExceptionRef(soot.jimple.CaughtExceptionRef) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) Sext(org.robovm.compiler.llvm.Sext) NegExpr(soot.jimple.NegExpr) PointerType(org.robovm.compiler.llvm.PointerType) Getelementptr(org.robovm.compiler.llvm.Getelementptr) Multianewarray(org.robovm.compiler.trampoline.Multianewarray) UshrExpr(soot.jimple.UshrExpr) ArrayRef(soot.jimple.ArrayRef) Lshr(org.robovm.compiler.llvm.Lshr) InstanceFieldRef(soot.jimple.InstanceFieldRef) Trunc(org.robovm.compiler.llvm.Trunc) ConstantTrunc(org.robovm.compiler.llvm.ConstantTrunc) Instanceof(org.robovm.compiler.trampoline.Instanceof) Sitofp(org.robovm.compiler.llvm.Sitofp) PutField(org.robovm.compiler.trampoline.PutField) Call(org.robovm.compiler.llvm.Call) Trampoline(org.robovm.compiler.trampoline.Trampoline) LengthExpr(soot.jimple.LengthExpr) Immediate(soot.Immediate) FunctionType(org.robovm.compiler.llvm.FunctionType) SubExpr(soot.jimple.SubExpr) Anewarray(org.robovm.compiler.trampoline.Anewarray) PutStatic(org.robovm.compiler.trampoline.PutStatic) IntegerType(org.robovm.compiler.llvm.IntegerType) FloatingPointType(org.robovm.compiler.llvm.FloatingPointType) IntegerType(org.robovm.compiler.llvm.IntegerType) PointerType(org.robovm.compiler.llvm.PointerType) NullType(soot.NullType) FunctionType(org.robovm.compiler.llvm.FunctionType) ArrayType(org.robovm.compiler.llvm.ArrayType) CharType(soot.CharType) RefLikeType(soot.RefLikeType) Type(org.robovm.compiler.llvm.Type) PrimType(soot.PrimType) DivExpr(soot.jimple.DivExpr) ParameterRef(soot.jimple.ParameterRef) ThisRef(soot.jimple.ThisRef) CmpgExpr(soot.jimple.CmpgExpr) Fpext(org.robovm.compiler.llvm.Fpext) Icmp(org.robovm.compiler.llvm.Icmp)

Example 3 with PrimType

use of soot.PrimType in project robovm by robovm.

the class MarshalerLookup method getBaseType.

private soot.Type getBaseType(SootMethod m, AnnotationTag anno) {
    AnnotationClassElem el = (AnnotationClassElem) getElemByName(anno, "baseType");
    if (el != null) {
        switch(el.getDesc().charAt(0)) {
            case 'Z':
                return BooleanType.v();
            case 'B':
                return ByteType.v();
            case 'S':
                return ShortType.v();
            case 'C':
                return CharType.v();
            case 'I':
                return IntType.v();
            case 'J':
                return LongType.v();
            case 'F':
                return FloatType.v();
            case 'D':
                return DoubleType.v();
        }
        return null;
    }
    soot.Type t = m.getReturnType();
    if (t == VoidType.v()) {
        t = m.getParameterType(0);
    }
    if (t instanceof RefType) {
        SootClass c = ((RefType) t).getSootClass();
        if (isInstanceOfClass(c, "java.nio.ByteBuffer")) {
            return ByteType.v();
        } else if (isInstanceOfClass(c, "java.nio.ShortBuffer")) {
            return ShortType.v();
        } else if (isInstanceOfClass(c, "java.nio.CharBuffer")) {
            return CharType.v();
        } else if (isInstanceOfClass(c, "java.nio.IntBuffer")) {
            return IntType.v();
        } else if (isInstanceOfClass(c, "java.nio.LongBuffer")) {
            return LongType.v();
        } else if (isInstanceOfClass(c, "java.nio.FloatBuffer")) {
            return FloatType.v();
        } else if (isInstanceOfClass(c, "java.nio.DoubleBuffer")) {
            return DoubleType.v();
        } else if (isInstanceOfClass(c, "org.robovm.rt.bro.Struct")) {
            return config.getClazzes().load("org/robovm/rt/bro/Struct").getSootClass().getType();
        }
    } else if (t instanceof ArrayType) {
        ArrayType arrayType = (ArrayType) t;
        if (arrayType.baseType instanceof PrimType || isInstanceOfClass(arrayType.baseType, "org.robovm.rt.bro.Struct")) {
            return arrayType.baseType;
        }
    }
    return null;
}
Also used : RefType(soot.RefType) ArrayType(soot.ArrayType) AnnotationClassElem(soot.tagkit.AnnotationClassElem) PrimType(soot.PrimType) SootClass(soot.SootClass)

Example 4 with PrimType

use of soot.PrimType in project robovm by robovm.

the class BroMethodCompiler method getReturnType.

private Type getReturnType(String anno, SootMethod method) {
    soot.Type sootType = method.getReturnType();
    if (hasPointerAnnotation(method)) {
        if (!sootType.equals(LongType.v())) {
            throw new IllegalArgumentException(anno + " annotated method " + method + " must return long when annotated with @Pointer");
        }
        return I8_PTR;
    }
    if (hasMachineSizedFloatAnnotation(method)) {
        if (!sootType.equals(DoubleType.v()) && !sootType.equals(FloatType.v())) {
            throw new IllegalArgumentException(anno + " annotated method " + method + " must return float or double when annotated with @MachineSizedFloat");
        }
        return config.getArch().is32Bit() ? FLOAT : DOUBLE;
    }
    if (hasMachineSizedSIntAnnotation(method) || hasMachineSizedUIntAnnotation(method)) {
        if (!sootType.equals(LongType.v())) {
            throw new IllegalArgumentException(anno + " annotated method " + method + " must return long when annotated with @MachineSizedSInt or @MachineSizedUInt");
        }
        return config.getArch().is32Bit() ? I32 : I64;
    }
    if (isStruct(sootType)) {
        if (!isPassByValue(method)) {
            // Structs are returned by reference by default
            return new PointerType(getStructType(sootType));
        }
        return getStructType(sootType);
    } else if (isNativeObject(sootType)) {
        // NativeObjects are always returned by reference.
        return I8_PTR;
    } else if (sootType instanceof PrimType || sootType == VoidType.v()) {
        return getType(sootType);
    }
    MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method));
    if (marshalerMethod instanceof ValueMarshalerMethod) {
        return ((ValueMarshalerMethod) marshalerMethod).getNativeType(config.getArch());
    } else {
        return I8_PTR;
    }
}
Also used : MarshalSite(org.robovm.compiler.MarshalerLookup.MarshalSite) ValueMarshalerMethod(org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod) PrimType(soot.PrimType) PointerType(org.robovm.compiler.llvm.PointerType) MarshalerMethod(org.robovm.compiler.MarshalerLookup.MarshalerMethod) ValueMarshalerMethod(org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod) ArrayMarshalerMethod(org.robovm.compiler.MarshalerLookup.ArrayMarshalerMethod)

Example 5 with PrimType

use of soot.PrimType in project soot by Sable.

the class ConstantFieldValueFinder method valuesForPrimTypeFields.

/*
	 * This method gives values to all the fields in all the classes if they can be determined statically
	 * We only care about fields which have primitive types
	 */
private void valuesForPrimTypeFields() {
    // go through all the classes
    Iterator classIt = appClasses.iterator();
    while (classIt.hasNext()) {
        SootClass s = (SootClass) classIt.next();
        debug("\nvaluesforPrimTypeFields", "Processing class " + s.getName());
        String declaringClass = s.getName();
        Iterator fieldIt = s.getFields().iterator();
        while (fieldIt.hasNext()) {
            SootField f = (SootField) fieldIt.next();
            String fieldName = f.getName();
            Type fieldType = f.getType();
            if (!(fieldType instanceof PrimType))
                continue;
            String combined = declaringClass + combiner + fieldName;
            classNameFieldNameToSootFieldMapping.put(combined, f);
            Object value = null;
            // check for constant value tags
            if (fieldType instanceof DoubleType && f.hasTag("DoubleConstantValueTag")) {
                double val = ((DoubleConstantValueTag) f.getTag("DoubleConstantValueTag")).getDoubleValue();
                value = new Double(val);
            } else if (fieldType instanceof FloatType && f.hasTag("FloatConstantValueTag")) {
                float val = ((FloatConstantValueTag) f.getTag("FloatConstantValueTag")).getFloatValue();
                value = new Float(val);
            } else if (fieldType instanceof LongType && f.hasTag("LongConstantValueTag")) {
                long val = ((LongConstantValueTag) f.getTag("LongConstantValueTag")).getLongValue();
                value = new Long(val);
            } else if (fieldType instanceof CharType && f.hasTag("IntegerConstantValueTag")) {
                int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
                value = new Integer(val);
            } else if (fieldType instanceof BooleanType && f.hasTag("IntegerConstantValueTag")) {
                int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
                if (val == 0)
                    value = new Boolean(false);
                else
                    value = new Boolean(true);
            } else if ((fieldType instanceof IntType || fieldType instanceof ByteType || fieldType instanceof ShortType) && f.hasTag("IntegerConstantValueTag")) {
                int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
                value = new Integer(val);
            }
            // if there was a constant value tag we have its value now
            if (value != null) {
                debug("TAGGED value found for field: " + combined);
                primTypeFieldValueToUse.put(combined, value);
                // continue with next field
                continue;
            }
            // see if the field was never assigned in which case it gets default values
            Object temp = fieldToValues.get(combined);
            if (temp == null) {
                if (fieldType instanceof DoubleType)
                    value = new Double(0);
                else if (fieldType instanceof FloatType)
                    value = new Float(0);
                else if (fieldType instanceof LongType)
                    value = new Long(0);
                else if (fieldType instanceof BooleanType)
                    value = new Boolean(false);
                else if ((fieldType instanceof IntType || fieldType instanceof ByteType || fieldType instanceof ShortType) || fieldType instanceof CharType) {
                    value = new Integer(0);
                } else
                    throw new DecompilationException("Unknown primitive type...please report to developer");
                primTypeFieldValueToUse.put(combined, value);
                debug("DEFAULT value for field: " + combined);
                // continue with next field
                continue;
            }
            // havent got a tag with value and havent use default since SOME method did define the field atleast once
            // there was some value assigned!!!!!!!!!
            debug("CHECKING USER ASSIGNED VALUES FOR: " + combined);
            ArrayList values = (ArrayList) temp;
            // check if they are all constants and that too the same constant
            Iterator it = values.iterator();
            NumericConstant tempConstant = null;
            while (it.hasNext()) {
                Value val = (Value) it.next();
                if (!(val instanceof NumericConstant)) {
                    tempConstant = null;
                    debug("Not numeric constant hence giving up");
                    break;
                }
                if (tempConstant == null) {
                    tempConstant = (NumericConstant) val;
                } else {
                    // check that this value is the same as previous
                    if (!tempConstant.equals(val)) {
                        tempConstant = null;
                        break;
                    }
                }
            }
            if (tempConstant == null) {
                // continue with next field cant do anything about this one
                continue;
            }
            if (tempConstant instanceof LongConstant) {
                Long tempVal = new Long(((LongConstant) tempConstant).value);
                if (tempVal.compareTo(new Long(0)) == 0)
                    primTypeFieldValueToUse.put(combined, tempVal);
                else
                    debug("Not assigning the agreed value since that is not the default value for " + combined);
            } else if (tempConstant instanceof DoubleConstant) {
                Double tempVal = new Double(((DoubleConstant) tempConstant).value);
                if (tempVal.compareTo(new Double(0)) == 0)
                    primTypeFieldValueToUse.put(combined, tempVal);
                else
                    debug("Not assigning the agreed value since that is not the default value for " + combined);
            } else if (tempConstant instanceof FloatConstant) {
                Float tempVal = new Float(((FloatConstant) tempConstant).value);
                if (tempVal.compareTo(new Float(0)) == 0)
                    primTypeFieldValueToUse.put(combined, tempVal);
                else
                    debug("Not assigning the agreed value since that is not the default value for " + combined);
            } else if (tempConstant instanceof IntConstant) {
                Integer tempVal = new Integer(((IntConstant) tempConstant).value);
                if (tempVal.compareTo(new Integer(0)) == 0) {
                    SootField tempField = classNameFieldNameToSootFieldMapping.get(combined);
                    if (tempField.getType() instanceof BooleanType) {
                        primTypeFieldValueToUse.put(combined, new Boolean(false));
                    // System.out.println("puttingvalue false for"+combined);
                    } else {
                        primTypeFieldValueToUse.put(combined, tempVal);
                    // System.out.println("puttingvalue 0 for"+combined);
                    }
                } else
                    debug("Not assigning the agreed value since that is not the default value for " + combined);
            } else {
                throw new DecompilationException("Un handled Numberic Constant....report to programmer");
            }
        }
    // all fields of the class
    }
// all classes
}
Also used : DoubleConstant(soot.jimple.DoubleConstant) LongType(soot.LongType) FloatConstant(soot.jimple.FloatConstant) ArrayList(java.util.ArrayList) DecompilationException(soot.dava.DecompilationException) ByteType(soot.ByteType) FloatType(soot.FloatType) IntType(soot.IntType) Iterator(java.util.Iterator) PrimType(soot.PrimType) LongConstantValueTag(soot.tagkit.LongConstantValueTag) IntConstant(soot.jimple.IntConstant) LongConstant(soot.jimple.LongConstant) ShortType(soot.ShortType) BooleanType(soot.BooleanType) IntegerConstantValueTag(soot.tagkit.IntegerConstantValueTag) DoubleConstantValueTag(soot.tagkit.DoubleConstantValueTag) SootClass(soot.SootClass) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) ShortType(soot.ShortType) CharType(soot.CharType) LongType(soot.LongType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) PrimType(soot.PrimType) DoubleType(soot.DoubleType) NumericConstant(soot.jimple.NumericConstant) Value(soot.Value) SootField(soot.SootField) CharType(soot.CharType)

Aggregations

PrimType (soot.PrimType)31 RefType (soot.RefType)15 ArrayList (java.util.ArrayList)12 Type (soot.Type)10 Value (soot.Value)10 DoubleType (soot.DoubleType)9 FloatType (soot.FloatType)9 IntType (soot.IntType)9 Local (soot.Local)9 LongType (soot.LongType)9 BooleanType (soot.BooleanType)8 SootClass (soot.SootClass)8 SootMethod (soot.SootMethod)8 ByteType (soot.ByteType)7 CharType (soot.CharType)7 ShortType (soot.ShortType)7 ArrayType (soot.ArrayType)6 VoidType (soot.VoidType)6 MethodVisitor (org.objectweb.asm.MethodVisitor)4 PointerType (org.robovm.compiler.llvm.PointerType)4