use of soot.SootClass in project soot by Sable.
the class ReflectiveCallsInliner method createNewMethod.
@SuppressWarnings("unchecked")
private SootMethod createNewMethod(Kind callKind, String target, Type fieldSetGetType) {
List<Type> parameterTypes = new LinkedList<Type>();
Type returnType = null;
switch(callKind) {
case ClassForName:
returnType = RefType.v("java.lang.Class");
break;
case ClassNewInstance:
returnType = RefType.v("java.lang.Object");
break;
case ConstructorNewInstance:
parameterTypes.add(ArrayType.v(RefType.v("java.lang.Object"), 1));
returnType = RefType.v("java.lang.Object");
break;
case MethodInvoke:
parameterTypes.add(RefType.v("java.lang.Object"));
parameterTypes.add(ArrayType.v(RefType.v("java.lang.Object"), 1));
returnType = RefType.v("java.lang.Object");
break;
case FieldSet:
parameterTypes.add(RefType.v("java.lang.Object"));
parameterTypes.add(fieldSetGetType);
returnType = VoidType.v();
break;
case FieldGet:
parameterTypes.add(RefType.v("java.lang.Object"));
returnType = fieldSetGetType;
break;
default:
throw new IllegalStateException();
}
SootMethod newMethod = Scene.v().makeSootMethod("reflectiveCall" + (callNum++), parameterTypes, returnType, Modifier.PUBLIC | Modifier.STATIC);
Body newBody = Jimple.v().newBody(newMethod);
newMethod.setActiveBody(newBody);
reflectiveCallsClass.addMethod(newMethod);
PatchingChain<Unit> newUnits = newBody.getUnits();
LocalGenerator localGen = new LocalGenerator(newBody);
Local freshLocal;
Value replacement = null;
Local[] paramLocals = null;
switch(callKind) {
case ClassForName:
{
// replace by: <Class constant for <target>>
freshLocal = localGen.generateLocal(RefType.v("java.lang.Class"));
replacement = ClassConstant.v(target.replace('.', '/'));
break;
}
case ClassNewInstance:
{
// replace by: new <target>
RefType targetType = RefType.v(target);
freshLocal = localGen.generateLocal(targetType);
replacement = Jimple.v().newNewExpr(targetType);
break;
}
case ConstructorNewInstance:
{
/*
* replace r=constr.newInstance(args) by: Object p0 = args[0]; ...
* Object pn = args[n]; T0 a0 = (T0)p0; ... Tn an = (Tn)pn;
*/
SootMethod constructor = Scene.v().getMethod(target);
paramLocals = new Local[constructor.getParameterCount()];
if (constructor.getParameterCount() > 0) {
// argArrayLocal = @parameter-0
ArrayType arrayType = ArrayType.v(RefType.v("java.lang.Object"), 1);
Local argArrayLocal = localGen.generateLocal(arrayType);
newUnits.add(Jimple.v().newIdentityStmt(argArrayLocal, Jimple.v().newParameterRef(arrayType, 0)));
int i = 0;
for (Type paramType : ((Collection<Type>) constructor.getParameterTypes())) {
paramLocals[i] = localGen.generateLocal(paramType);
unboxParameter(argArrayLocal, i, paramLocals, paramType, newUnits, localGen);
i++;
}
}
RefType targetType = constructor.getDeclaringClass().getType();
freshLocal = localGen.generateLocal(targetType);
replacement = Jimple.v().newNewExpr(targetType);
break;
}
case MethodInvoke:
{
/*
* replace r=m.invoke(obj,args) by: T recv = (T)obj; Object p0 =
* args[0]; ... Object pn = args[n]; T0 a0 = (T0)p0; ... Tn an =
* (Tn)pn;
*/
SootMethod method = Scene.v().getMethod(target);
// recvObject = @parameter-0
RefType objectType = RefType.v("java.lang.Object");
Local recvObject = localGen.generateLocal(objectType);
newUnits.add(Jimple.v().newIdentityStmt(recvObject, Jimple.v().newParameterRef(objectType, 0)));
paramLocals = new Local[method.getParameterCount()];
if (method.getParameterCount() > 0) {
// argArrayLocal = @parameter-1
ArrayType arrayType = ArrayType.v(RefType.v("java.lang.Object"), 1);
Local argArrayLocal = localGen.generateLocal(arrayType);
newUnits.add(Jimple.v().newIdentityStmt(argArrayLocal, Jimple.v().newParameterRef(arrayType, 1)));
int i = 0;
for (Type paramType : ((Collection<Type>) method.getParameterTypes())) {
paramLocals[i] = localGen.generateLocal(paramType);
unboxParameter(argArrayLocal, i, paramLocals, paramType, newUnits, localGen);
i++;
}
}
RefType targetType = method.getDeclaringClass().getType();
freshLocal = localGen.generateLocal(targetType);
replacement = Jimple.v().newCastExpr(recvObject, method.getDeclaringClass().getType());
break;
}
case FieldSet:
case FieldGet:
{
/*
* replace f.set(o,v) by: Object obj = @parameter-0; T freshLocal =
* (T)obj;
*/
RefType objectType = RefType.v("java.lang.Object");
Local recvObject = localGen.generateLocal(objectType);
newUnits.add(Jimple.v().newIdentityStmt(recvObject, Jimple.v().newParameterRef(objectType, 0)));
SootField field = Scene.v().getField(target);
freshLocal = localGen.generateLocal(field.getDeclaringClass().getType());
replacement = Jimple.v().newCastExpr(recvObject, field.getDeclaringClass().getType());
break;
}
default:
throw new InternalError("Unknown kind of reflective call " + callKind);
}
AssignStmt replStmt = Jimple.v().newAssignStmt(freshLocal, replacement);
newUnits.add(replStmt);
Local retLocal = localGen.generateLocal(returnType);
switch(callKind) {
case ClassForName:
{
// add: retLocal = freshLocal;
newUnits.add(Jimple.v().newAssignStmt(retLocal, freshLocal));
break;
}
case ClassNewInstance:
{
// add: freshLocal.<init>()
SootClass targetClass = Scene.v().getSootClass(target);
SpecialInvokeExpr constrCallExpr = Jimple.v().newSpecialInvokeExpr(freshLocal, Scene.v().makeMethodRef(targetClass, SootMethod.constructorName, Collections.<Type>emptyList(), VoidType.v(), false));
InvokeStmt constrCallStmt2 = Jimple.v().newInvokeStmt(constrCallExpr);
newUnits.add(constrCallStmt2);
// add: retLocal = freshLocal
newUnits.add(Jimple.v().newAssignStmt(retLocal, freshLocal));
break;
}
case ConstructorNewInstance:
{
// add: freshLocal.<target>(a0,...,an);
SootMethod constructor = Scene.v().getMethod(target);
SpecialInvokeExpr constrCallExpr = Jimple.v().newSpecialInvokeExpr(freshLocal, constructor.makeRef(), Arrays.asList(paramLocals));
InvokeStmt constrCallStmt2 = Jimple.v().newInvokeStmt(constrCallExpr);
newUnits.add(constrCallStmt2);
// add: retLocal = freshLocal
newUnits.add(Jimple.v().newAssignStmt(retLocal, freshLocal));
break;
}
case MethodInvoke:
{
// add: freshLocal=recv.<target>(a0,...,an);
SootMethod method = Scene.v().getMethod(target);
InvokeExpr invokeExpr;
if (method.isStatic())
invokeExpr = Jimple.v().newStaticInvokeExpr(method.makeRef(), Arrays.asList(paramLocals));
else
invokeExpr = Jimple.v().newVirtualInvokeExpr(freshLocal, method.makeRef(), Arrays.<Value>asList(paramLocals));
if (method.getReturnType().equals(VoidType.v())) {
// method returns null; simply invoke it and return null
InvokeStmt invokeStmt = Jimple.v().newInvokeStmt(invokeExpr);
newUnits.add(invokeStmt);
AssignStmt assignStmt = Jimple.v().newAssignStmt(retLocal, NullConstant.v());
newUnits.add(assignStmt);
} else {
AssignStmt assignStmt = Jimple.v().newAssignStmt(retLocal, invokeExpr);
newUnits.add(assignStmt);
}
break;
}
case FieldSet:
{
// add freshLocal.<f> = v;
Local value = localGen.generateLocal(fieldSetGetType);
newUnits.insertBeforeNoRedirect(Jimple.v().newIdentityStmt(value, Jimple.v().newParameterRef(fieldSetGetType, 1)), replStmt);
SootField field = Scene.v().getField(target);
Local boxedOrCasted = localGen.generateLocal(field.getType());
insertCastOrUnboxingCode(boxedOrCasted, value, newUnits);
FieldRef fieldRef;
if (field.isStatic()) {
fieldRef = Jimple.v().newStaticFieldRef(field.makeRef());
} else {
fieldRef = Jimple.v().newInstanceFieldRef(freshLocal, field.makeRef());
}
newUnits.add(Jimple.v().newAssignStmt(fieldRef, boxedOrCasted));
break;
}
case FieldGet:
{
/*
* add: T2 temp = recv.<f>; return temp;
*/
SootField field = Scene.v().getField(target);
Local value = localGen.generateLocal(field.getType());
FieldRef fieldRef;
if (field.isStatic()) {
fieldRef = Jimple.v().newStaticFieldRef(field.makeRef());
} else {
fieldRef = Jimple.v().newInstanceFieldRef(freshLocal, field.makeRef());
}
newUnits.add(Jimple.v().newAssignStmt(value, fieldRef));
insertCastOrBoxingCode(retLocal, value, newUnits);
break;
}
}
if (!returnType.equals(VoidType.v()))
newUnits.add(Jimple.v().newReturnStmt(retLocal));
if (Options.v().validate())
newBody.validate();
cleanup(newBody);
return newMethod;
}
use of soot.SootClass in project soot by Sable.
the class OnTheFlyJimpleBasedICFG method initForMethod.
protected Body initForMethod(SootMethod m) {
assert Scene.v().hasFastHierarchy();
Body b = null;
if (m.isConcrete()) {
SootClass declaringClass = m.getDeclaringClass();
ensureClassHasBodies(declaringClass);
synchronized (Scene.v()) {
b = m.retrieveActiveBody();
}
if (b != null) {
for (Unit u : b.getUnits()) {
if (unitToOwner.put(u, b) != null) {
// simply skip the rest
break;
}
}
}
}
assert Scene.v().hasFastHierarchy();
return b;
}
use of soot.SootClass in project soot by Sable.
the class TypeDecl method refined_EmitJimple_TypeDecl_getSootClassDecl.
/**
* @ast method
* @aspect EmitJimple
* @declaredat /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/JimpleBackend/EmitJimple.jrag:32
*/
private SootClass refined_EmitJimple_TypeDecl_getSootClassDecl() {
if (compilationUnit().fromSource()) {
return sootClass();
} else {
if (options().verbose())
System.out.println("Loading .class file " + jvmName());
SootClass sc = Scene.v().loadClass(jvmName(), SootClass.SIGNATURES);
sc.setLibraryClass();
return sc;
}
}
use of soot.SootClass in project robovm by robovm.
the class ObjCMemberPlugin method init.
private void init(Config config) {
if (initialized) {
return;
}
this.config = config;
if (config.getClazzes().load(OBJC_OBJECT.replace('.', '/')) == null) {
initialized = true;
return;
}
SootResolver r = SootResolver.v();
// These have to be resolved to HIERARCHY so that isPhantom() works
// properly
org_robovm_objc_ObjCObject = r.resolveClass(OBJC_OBJECT, SootClass.HIERARCHY);
org_robovm_objc_ObjCExtensions = r.resolveClass(OBJC_EXTENSIONS, SootClass.HIERARCHY);
// These only have to be DANGLING
org_robovm_objc_ObjCClass = r.makeClassRef(OBJC_CLASS);
org_robovm_objc_ObjCSuper = r.makeClassRef(OBJC_SUPER);
org_robovm_objc_ObjCRuntime = r.makeClassRef(OBJC_RUNTIME);
org_robovm_objc_Selector = r.makeClassRef(SELECTOR);
org_robovm_apple_foundation_NSObject = r.makeClassRef(NS_OBJECT);
org_robovm_apple_foundation_NSObject$Marshaler = r.makeClassRef(NS_OBJECT$MARSHALER);
org_robovm_apple_foundation_NSString$AsStringMarshaler = r.makeClassRef(NS_STRING$AS_STRING_MARSHALER);
org_robovm_objc_$M = r.makeClassRef($M);
org_robovm_apple_uikit_UIEvent = r.makeClassRef(UI_EVENT);
org_robovm_apple_foundation_NSArray = r.makeClassRef(NS_ARRAY);
SootClass java_lang_Object = r.makeClassRef("java.lang.Object");
java_lang_String = r.makeClassRef("java.lang.String");
java_lang_Class = r.makeClassRef("java.lang.Class");
org_robovm_objc_Selector_register = Scene.v().makeMethodRef(org_robovm_objc_Selector, "register", Arrays.<Type>asList(java_lang_String.getType()), org_robovm_objc_Selector.getType(), true);
org_robovm_objc_ObjCObject_getSuper = Scene.v().makeMethodRef(org_robovm_objc_ObjCObject, "getSuper", Collections.<Type>emptyList(), org_robovm_objc_ObjCSuper.getType(), false);
org_robovm_objc_ObjCObject_updateStrongRef = Scene.v().makeMethodRef(org_robovm_objc_ObjCObject, "updateStrongRef", Arrays.<Type>asList(java_lang_Object.getType(), java_lang_Object.getType()), VoidType.v(), false);
org_robovm_objc_ObjCClass_getByType = Scene.v().makeMethodRef(org_robovm_objc_ObjCClass, "getByType", Arrays.<Type>asList(java_lang_Class.getType()), org_robovm_objc_ObjCClass.getType(), true);
org_robovm_objc_ObjCRuntime_bind = Scene.v().makeMethodRef(org_robovm_objc_ObjCRuntime, "bind", Arrays.<Type>asList(java_lang_Class.getType()), VoidType.v(), true);
org_robovm_objc_ObjCObject_customClass = Scene.v().makeFieldRef(org_robovm_objc_ObjCObject, "customClass", BooleanType.v(), false);
org_robovm_objc_ObjCExtensions_updateStrongRef = Scene.v().makeMethodRef(org_robovm_objc_ObjCExtensions, "updateStrongRef", Arrays.<Type>asList(org_robovm_objc_ObjCObject.getType(), java_lang_Object.getType(), java_lang_Object.getType()), VoidType.v(), true);
initialized = true;
}
use of soot.SootClass in project robovm by robovm.
the class ObjCMemberPlugin method beforeClass.
@Override
public void beforeClass(Config config, Clazz clazz, ModuleBuilder moduleBuilder) {
init(config);
SootClass sootClass = clazz.getSootClass();
boolean extensions = false;
if (!sootClass.isInterface() && (isObjCObject(sootClass) || (extensions = isObjCExtensions(sootClass)))) {
Set<String> selectors = new TreeSet<>();
Set<String> overridables = new HashSet<>();
for (SootMethod method : sootClass.getMethods()) {
if (!"<clinit>".equals(method.getName()) && !"<init>".equals(method.getName())) {
transformMethod(config, clazz, sootClass, method, selectors, overridables, extensions);
}
}
addBindCall(sootClass);
if (!extensions) {
addObjCClassField(sootClass);
}
registerSelectors(sootClass, selectors);
}
}
Aggregations