Search in sources :

Example 6 with SootField

use of soot.SootField in project robovm by robovm.

the class Types method getFields.

public static List<SootField> getFields(final OS os, final Arch arch, SootClass clazz, boolean ztatic) {
    List<SootField> l = new ArrayList<SootField>();
    for (SootField f : clazz.getFields()) {
        if (ztatic == f.isStatic()) {
            l.add(f);
        }
    }
    // Sort the fields. references, volatile long, double, long, float, int, char, short, boolean, byte.
    // Fields of same type are sorted by name.
    Collections.sort(l, new Comparator<SootField>() {

        @Override
        public int compare(SootField o1, SootField o2) {
            soot.Type t1 = o1.getType();
            soot.Type t2 = o2.getType();
            if (t1 instanceof RefLikeType) {
                if (!(t2 instanceof RefLikeType)) {
                    return -1;
                }
            }
            if (t2 instanceof RefLikeType) {
                if (!(t1 instanceof RefLikeType)) {
                    return 1;
                }
            }
            // Compare alignment. Higher first.
            int align1 = getFieldAlignment(os, arch, o1);
            int align2 = getFieldAlignment(os, arch, o2);
            int c = new Integer(align2).compareTo(align1);
            if (c == 0) {
                // Compare size. Larger first.
                int size1 = getFieldSize(arch, o1);
                int size2 = getFieldSize(arch, o2);
                c = new Integer(size2).compareTo(size1);
                if (c == 0) {
                    // Compare type name.
                    c = t1.getClass().getSimpleName().compareTo(t2.getClass().getSimpleName());
                    if (c == 0) {
                        // Compare name.
                        c = o1.getName().compareTo(o2.getName());
                    }
                }
            }
            return c;
        }
    });
    return l;
}
Also used : RefLikeType(soot.RefLikeType) PointerType(org.robovm.compiler.llvm.PointerType) RefType(soot.RefType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) ShortType(soot.ShortType) PackedStructureType(org.robovm.compiler.llvm.PackedStructureType) CharType(soot.CharType) LongType(soot.LongType) IntegerType(org.robovm.compiler.llvm.IntegerType) BooleanType(soot.BooleanType) OpaqueType(org.robovm.compiler.llvm.OpaqueType) StructureType(org.robovm.compiler.llvm.StructureType) RefLikeType(soot.RefLikeType) ByteType(soot.ByteType) Type(org.robovm.compiler.llvm.Type) BottomType(soot.jimple.toolkits.typing.fast.BottomType) AggregateType(org.robovm.compiler.llvm.AggregateType) PrimType(soot.PrimType) VoidType(soot.VoidType) FunctionType(org.robovm.compiler.llvm.FunctionType) ArrayList(java.util.ArrayList) SootField(soot.SootField)

Example 7 with SootField

use of soot.SootField in project robovm by robovm.

the class MethodCompiler method canAccessDirectly.

//    private Value callOrInvoke(Unit unit, Value fn, Value ... args) {
//        Variable result = null;
//        Type returnType = ((FunctionType) fn.getType()).getReturnType();
//        if (returnType != VOID) {
//            result = this.function.newVariable(returnType);
//        }
//        List<Trap> traps = getTrapsAt(unit);
//        if (!traps.isEmpty()) {
//            Label label = new Label();
//            BasicBlockRef to = function.newBasicBlockRef(label);
//            BasicBlockRef unwind = function.newBasicBlockRef(new Label(traps));
//            function.add(new Invoke(result, fn, to, unwind, args));
//            function.newBasicBlock(label);
//            recordedTraps.add(traps);
//        } else {
//            function.add(new Call(result, fn, args));
//        }
//        return result == null ? null : result.ref();
//    }
private boolean canAccessDirectly(FieldRef ref) {
    SootClass sootClass = this.sootMethod.getDeclaringClass();
    SootFieldRef fieldRef = ref.getFieldRef();
    if (!fieldRef.declaringClass().equals(sootClass)) {
        return false;
    }
    try {
        SootField field = sootClass.getField(fieldRef.name(), fieldRef.type());
        /* 
             * The field exists.
             */
        if (field.isStatic()) {
            // If not we want an exception to be thrown so we need a trampoline.
            return ref instanceof StaticFieldRef;
        }
        // If not we want an exception to be thrown so we need a trampoline.
        return ref instanceof InstanceFieldRef;
    } catch (RuntimeException e) {
        // isn't declared in the class.
        return false;
    }
}
Also used : InstanceFieldRef(soot.jimple.InstanceFieldRef) SootField(soot.SootField) SootClass(soot.SootClass) SootFieldRef(soot.SootFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef)

Example 8 with SootField

use of soot.SootField in project robovm by robovm.

the class TrampolineCompiler method compile.

public void compile(ModuleBuilder mb, Clazz currentClass, Trampoline t, Set<String> dependencies, Set<Triple<String, String, String>> methodDependencies) {
    this.mb = mb;
    addDependencyIfNeeded(dependencies, currentClass, t);
    /*
         * Check if the target class exists and is accessible. Also check that
         * field accesses and method calls are compatible with the target 
         * field/method and that the field/method is accessible to the caller.
         * If any of the tests fail the weak trampoline function created by the
         * ClassCompiler will be overridden with a function which throws an
         * appropriate exception.
         */
    Function errorFn = new FunctionBuilder(t).linkage(external).build();
    if (!checkClassExists(errorFn, t) || !checkClassAccessible(errorFn, t)) {
        mb.addFunction(errorFn);
        return;
    }
    if (t instanceof New) {
        SootClass target = config.getClazzes().load(t.getTarget()).getSootClass();
        if (target.isAbstract() || target.isInterface()) {
            call(errorFn, BC_THROW_INSTANTIATION_ERROR, errorFn.getParameterRef(0), mb.getString(t.getTarget().replace('/', '.')));
            errorFn.add(new Unreachable());
            mb.addFunction(errorFn);
            return;
        }
        String fnName = Symbols.clinitWrapperSymbol(Symbols.allocatorSymbol(t.getTarget()));
        alias(t, fnName);
    } else if (t instanceof Instanceof) {
        if (isArray(t.getTarget())) {
            FunctionRef fnRef = createInstanceofArray((Instanceof) t);
            alias(t, fnRef.getName());
        } else {
            String fnName = Symbols.instanceofSymbol(t.getTarget());
            alias(t, fnName);
        }
    } else if (t instanceof Checkcast) {
        if (isArray(t.getTarget())) {
            FunctionRef fnRef = createCheckcastArray((Checkcast) t);
            alias(t, fnRef.getName());
        } else {
            String fnName = Symbols.checkcastSymbol(t.getTarget());
            alias(t, fnName);
        }
    } else if (t instanceof LdcClass) {
        if (isArray(t.getTarget())) {
            FunctionRef fnRef = createLdcArray((LdcClass) t);
            alias(t, fnRef.getName());
        } else {
            String fnName = Symbols.ldcExternalSymbol(t.getTarget());
            alias(t, fnName);
        }
    } else if (t instanceof Anewarray) {
        FunctionRef fnRef = createAnewarray((Anewarray) t);
        alias(t, fnRef.getName());
    } else if (t instanceof Multianewarray) {
        FunctionRef fnRef = createMultianewarray((Multianewarray) t);
        alias(t, fnRef.getName());
    } else if (t instanceof FieldAccessor) {
        SootField field = resolveField(errorFn, (FieldAccessor) t);
        if (field != null) {
            dependencies.add(getInternalName(field.getDeclaringClass()));
        }
        if (field == null || !checkMemberAccessible(errorFn, t, field)) {
            mb.addFunction(errorFn);
            return;
        }
        Clazz caller = config.getClazzes().load(t.getCallingClass());
        Clazz target = config.getClazzes().load(t.getTarget());
        if (!((FieldAccessor) t).isGetter() && field.isFinal() && caller != target) {
            // Only the class declaring a final field may write to it.
            // (Actually only <init>/<clinit> methods may write to it but we 
            // don't know which method is accessing the field at this point)
            throwIllegalAccessError(errorFn, ATTEMPT_TO_WRITE_TO_FINAL_FIELD, target, field.getName(), caller);
            mb.addFunction(errorFn);
            return;
        }
        if (!field.isStatic()) {
            createInlinedAccessorForInstanceField((FieldAccessor) t, field);
        } else {
            createTrampolineAliasForField((FieldAccessor) t, field);
        }
    } else if (t instanceof Invokeinterface) {
        SootMethod rm = resolveInterfaceMethod(errorFn, (Invokeinterface) t);
        if (rm != null) {
            methodDependencies.add(new ImmutableTriple<String, String, String>(getInternalName(rm.getDeclaringClass()), rm.getName(), getDescriptor(rm)));
        }
        if (rm == null || !checkMemberAccessible(errorFn, t, rm)) {
            mb.addFunction(errorFn);
            return;
        }
        createTrampolineAliasForMethod((Invoke) t, rm);
    } else if (t instanceof Invoke) {
        SootMethod method = resolveMethod(errorFn, (Invoke) t);
        if (method != null) {
            methodDependencies.add(new ImmutableTriple<String, String, String>(getInternalName(method.getDeclaringClass()), method.getName(), getDescriptor(method)));
        }
        if (method == null || !checkMemberAccessible(errorFn, t, method)) {
            mb.addFunction(errorFn);
            return;
        }
        if (t instanceof Invokespecial && method.isAbstract()) {
            call(errorFn, BC_THROW_ABSTRACT_METHOD_ERROR, errorFn.getParameterRef(0), mb.getString(String.format(NO_SUCH_METHOD_ERROR, method.getDeclaringClass(), method.getName(), getDescriptor(method))));
            errorFn.add(new Unreachable());
            mb.addFunction(errorFn);
            return;
        }
        createTrampolineAliasForMethod((Invoke) t, method);
    }
}
Also used : New(org.robovm.compiler.trampoline.New) ImmutableTriple(org.apache.commons.lang3.tuple.ImmutableTriple) Anewarray(org.robovm.compiler.trampoline.Anewarray) Multianewarray(org.robovm.compiler.trampoline.Multianewarray) SootClass(soot.SootClass) FieldAccessor(org.robovm.compiler.trampoline.FieldAccessor) Invokeinterface(org.robovm.compiler.trampoline.Invokeinterface) Invoke(org.robovm.compiler.trampoline.Invoke) Invokespecial(org.robovm.compiler.trampoline.Invokespecial) Function(org.robovm.compiler.llvm.Function) Unreachable(org.robovm.compiler.llvm.Unreachable) LdcClass(org.robovm.compiler.trampoline.LdcClass) Instanceof(org.robovm.compiler.trampoline.Instanceof) SootMethod(soot.SootMethod) SootField(soot.SootField) Clazz(org.robovm.compiler.clazz.Clazz) Checkcast(org.robovm.compiler.trampoline.Checkcast) FunctionRef(org.robovm.compiler.llvm.FunctionRef)

Example 9 with SootField

use of soot.SootField in project robovm by robovm.

the class TrampolineCompiler method createInlinedAccessorForInstanceField.

private void createInlinedAccessorForInstanceField(FieldAccessor t, SootField field) {
    Function fn = new FunctionBuilder(t).linkage(aliasLinkage()).attribs(shouldInline(), optsize).build();
    List<SootField> classFields = Collections.emptyList();
    StructureType classType = new StructureType();
    List<SootField> instanceFields = getInstanceFields(config.getOs(), config.getArch(), field.getDeclaringClass());
    StructureType instanceType = getInstanceType(config.getOs(), config.getArch(), field.getDeclaringClass());
    if (t.isGetter()) {
        ClassCompiler.createFieldGetter(fn, field, classFields, classType, instanceFields, instanceType);
    } else {
        ClassCompiler.createFieldSetter(fn, field, classFields, classType, instanceFields, instanceType);
    }
    mb.addFunction(fn);
}
Also used : Function(org.robovm.compiler.llvm.Function) StructureType(org.robovm.compiler.llvm.StructureType) SootField(soot.SootField)

Example 10 with SootField

use of soot.SootField in project robovm by robovm.

the class Types method getInstanceType0.

private static PackedStructureType getInstanceType0(OS os, Arch arch, SootClass clazz, int subClassAlignment, int[] superSize) {
    List<Type> types = new ArrayList<Type>();
    List<SootField> fields = getInstanceFields(os, arch, clazz);
    int superAlignment = 1;
    if (!fields.isEmpty()) {
        // Pad the super type so that the first field is aligned properly
        SootField field = fields.get(0);
        superAlignment = getFieldAlignment(os, arch, field);
    }
    if (clazz.hasSuperclass()) {
        types.add(getInstanceType0(os, arch, clazz.getSuperclass(), superAlignment, superSize));
    }
    int offset = superSize[0];
    for (SootField field : fields) {
        int falign = getFieldAlignment(os, arch, field);
        int padding = (offset & (falign - 1)) != 0 ? (falign - (offset & (falign - 1))) : 0;
        types.add(padType(getType(field.getType()), padding));
        offset += padding + getFieldSize(arch, field);
    }
    int padding = (offset & (subClassAlignment - 1)) != 0 ? (subClassAlignment - (offset & (subClassAlignment - 1))) : 0;
    for (int i = 0; i < padding; i++) {
        types.add(I8);
        offset++;
    }
    superSize[0] = offset;
    return new PackedStructureType(types.toArray(new Type[types.size()]));
}
Also used : PointerType(org.robovm.compiler.llvm.PointerType) RefType(soot.RefType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) ShortType(soot.ShortType) PackedStructureType(org.robovm.compiler.llvm.PackedStructureType) CharType(soot.CharType) LongType(soot.LongType) IntegerType(org.robovm.compiler.llvm.IntegerType) BooleanType(soot.BooleanType) OpaqueType(org.robovm.compiler.llvm.OpaqueType) StructureType(org.robovm.compiler.llvm.StructureType) RefLikeType(soot.RefLikeType) ByteType(soot.ByteType) Type(org.robovm.compiler.llvm.Type) BottomType(soot.jimple.toolkits.typing.fast.BottomType) AggregateType(org.robovm.compiler.llvm.AggregateType) PrimType(soot.PrimType) VoidType(soot.VoidType) FunctionType(org.robovm.compiler.llvm.FunctionType) ArrayList(java.util.ArrayList) SootField(soot.SootField) ConstantPtrtoint(org.robovm.compiler.llvm.ConstantPtrtoint) PackedStructureType(org.robovm.compiler.llvm.PackedStructureType)

Aggregations

SootField (soot.SootField)15 SootMethod (soot.SootMethod)8 SootClass (soot.SootClass)7 ArrayList (java.util.ArrayList)5 StructureType (org.robovm.compiler.llvm.StructureType)5 PrimType (soot.PrimType)5 FunctionRef (org.robovm.compiler.llvm.FunctionRef)4 PointerType (org.robovm.compiler.llvm.PointerType)4 Type (org.robovm.compiler.llvm.Type)4 BooleanType (soot.BooleanType)4 ByteType (soot.ByteType)4 CharType (soot.CharType)4 DoubleType (soot.DoubleType)4 FloatType (soot.FloatType)4 IntType (soot.IntType)4 LongType (soot.LongType)4 RefLikeType (soot.RefLikeType)4 RefType (soot.RefType)4 ShortType (soot.ShortType)4 VoidType (soot.VoidType)4