soot.jimple.toolkits.pointer.nativemethods.JavaLangClassNative Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of robovm-soot Show documentation
Show all versions of robovm-soot Show documentation
RoboVM fork of Soot - A Java optimization framework
/* Soot - a J*va Optimization Framework
* Copyright (C) 2003 Feng Qian
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* Simulates the native method side effects in class java.lang.Class
*
* @author Feng Qian
* @author
*/
package soot.jimple.toolkits.pointer.nativemethods;
import soot.*;
import soot.jimple.toolkits.pointer.representations.*;
import soot.jimple.toolkits.pointer.util.*;
public class JavaLangClassNative extends NativeMethodClass {
public JavaLangClassNative( NativeHelper helper ) { super(helper); }
/**
* Implements the abstract method simulateMethod.
* It distributes the request to the corresponding methods
* by signatures.
*/
public void simulateMethod(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]){
String subSignature = method.getSubSignature();
if (subSignature.equals("java.lang.Class forName0(java.lang.String,boolean,java.lang.ClassLoader)")) {
java_lang_Class_forName0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.Object newInstance0()")) {
java_lang_Class_newInstance0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.String getName()")) {
java_lang_Class_getName(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.ClassLoader getClassLoader0()")){
java_lang_Class_getClassLoader0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.Class getSuperclass()")) {
java_lang_Class_getSuperclass(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.Class[] getInterfaces()")){
java_lang_Class_getInterfaces(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.Class getComponentType()")){
java_lang_Class_getComponentType(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.Object[] getSigners()")){
java_lang_Class_getSigners(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("void setSigners(java.lang.Object[])")) {
java_lang_Class_setSigners(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.Class getDeclaringClass()")){
java_lang_Class_getDeclaringClass(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("void setProtectionDomain0(java.security.ProtectionDomain)")){
java_lang_Class_setProtectionDomain0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.security.ProtectionDomain getProtectionDomain0()")) {
java_lang_Class_getProtectionDomain0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.Class getPrimitiveClass(java.lang.String)")) {
java_lang_Class_getPrimitiveClass(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.reflect.Field[] getFields0(int)")){
java_lang_Class_getFields0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.reflect.Method[] getMethods0(int)")){
java_lang_Class_getMethods0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.reflect.Constructor[] getConstructors0(int)")) {
java_lang_Class_getConstructors0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.reflect.Field getField0(java.lang.String,int)")) {
java_lang_Class_getField0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.reflect.Method getMethod0(java.lang.String,java.lang.Class[],int)")) {
java_lang_Class_getMethod0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.reflect.Constructor getConstructor0(java.lang.Class[],int)")) {
java_lang_Class_getConstructor0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.Class[] getDeclaredClasses0()")){
java_lang_Class_getDeclaredClasses0(method, thisVar, returnVar, params);
return;
} else if (subSignature.equals("java.lang.reflect.Constructor[] getDeclaredConstructors0(boolean)")){
java_lang_Class_getDeclaredConstructors0(method, thisVar, returnVar, params);
return;
} else {
defaultMethod(method, thisVar, returnVar, params);
return;
}
}
/****************************** java.lang.Class **********************/
/* A quick note for simulating java.lang.Class :
*
* In theory, the same class may have two or more representations
* at the runtime. But statically, we can assume that all variables
* of java.lang.Class type are aliased together. By looking at
* static class hierarchy, there is only one ReferenceVariable
* variable for a class in the hierarchy.
*/
/**
* NOTE: the semantic of forName0 follows forName method.
*
* Returns the Class object associated with the class or interface
* with the given string name, using the given class loader. Given
* the fully qualified name for a class or interface (in the same
* format returned by getName) this method attempts to locate,
* load, and link the class or interface. The specified class
* loader is used to load the class or interface. If the parameter
* loader is null, the class is loaded through the bootstrap class
* loader. The class is initialized only if the initialize
* parameter is true and if it has not been initialized earlier.
*
* If name denotes a primitive type or void, an attempt will be made
* to locate a user-defined class in the unnamed package whose
* name is name. Therefore, this method cannot be used to obtain
* any of the Class objects representing primitive types or void.
*
* If name denotes an array class, the component type of the array
* class is loaded but not initialized.
*
* For example, in an instance method the expression:
* Class.forName("Foo")
* is equivalent to:
* Class.forName("Foo", true, this.getClass().getClassLoader())
*
* private static native java.lang.Class forName0(java.lang.String,
* boolean,
* java.lang.ClassLoader)
* throws java.lang.ClassNotFoundException;
*/
public void java_lang_Class_forName0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]){
helper.assignObjectTo(returnVar, Environment.v().getClassObject());
}
/**
* NOTE: creates an object.
*
* private native java.lang.Object newInstance0()
* throws java.lang.InstantiationException,
* java.lang.IllegalAccessException
*/
public void java_lang_Class_newInstance0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]){
ReferenceVariable instanceVar = helper.newInstanceOf(thisVar);
helper.assign(returnVar, instanceVar);
}
/**
* Returns the class name.
*
* public native java.lang.String getName();
*/
public void java_lang_Class_getName(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
helper.assignObjectTo(returnVar, Environment.v().getStringObject());
}
/**
* returns the class loader object for this class.
*
* it is almost impossible to distinguish the dynamic class loader
* for classes. a conservative way is to use one static representation
* for all class loader, which means all class loader variable aliased
* together.
*
* private native java.lang.ClassLoader getClassLoader0();
*/
public
void java_lang_Class_getClassLoader0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
helper.assignObjectTo(returnVar, Environment.v().getClassLoaderObject());
}
/**
* returns the super class of this class
*
* public native java.lang.Class getSuperclass();
*/
public
void java_lang_Class_getSuperclass(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
helper.assignObjectTo(returnVar, Environment.v().getClassObject());
}
/**
* Determines the interfaces implemented by the class or interface
* represented by this object.
*
* public native java.lang.Class getInterfaces()[];
*/
public
void java_lang_Class_getInterfaces(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
/* currently, we do not distinguish array object and scalar object.*/
helper.assignObjectTo(returnVar, Environment.v().getClassObject());
}
/**
* Returns the Class representing the component type of an array. If
* this class does not represent an array class this method returns
* null.
*
* public native java.lang.Class getComponentType();
*/
public
void java_lang_Class_getComponentType(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
helper.assignObjectTo(returnVar, Environment.v().getClassObject());
}
/**
* Sets the signers of a class. This should be called after defining a
* class. Parameters:
* c - the Class object
* signers - the signers for the class
*
* native void setSigners(java.lang.Object[]);
*/
public
void java_lang_Class_setSigners(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
ReferenceVariable tempFld =
helper.tempField("");
helper.assign(tempFld, params[0]);
}
/**
* Gets the signers of this class.
* We need an artificial field variable to connect setSigners
* and getSigners.
*
* public native java.lang.Object getSigners()[];
*/
public
void java_lang_Class_getSigners(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
ReferenceVariable tempFld =
helper.tempField("");
helper.assign(returnVar, tempFld);
}
/**
* If the class or interface represented by this Class object is a
* member of another class, returns the Class object representing the
* class in which it was declared. This method returns null if this
* class or interface is not a member of any other class. If this
* Class object represents an array class, a primitive type, or
* void,then this method returns null.
*
* Returns:
* the declaring class for this class
*
* public native java.lang.Class getDeclaringClass();
*/
public
void java_lang_Class_getDeclaringClass(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
helper.assignObjectTo(returnVar, Environment.v().getClassObject());
}
/**
* Sets or returns the ProtectionDomain of this class,
* called by getProtectiondomain.
*
* We need an artificial field variable to handle this.
*
* native void setProtectionDomain0(java.security.ProtectionDomain);
*/
public
void java_lang_Class_setProtectionDomain0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
ReferenceVariable protdmn =
helper.tempField("");
helper.assign(protdmn, params[0]);
}
/**
* private native java.security.ProtectionDomain getProtectionDomain0();
*/
public
void java_lang_Class_getProtectionDomain0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
ReferenceVariable protdmn =
helper.tempField("");
helper.assign(returnVar, protdmn);
}
/**
* Undocumented. It is supposed to return a class object for primitive
* type named by @param0.
*
* static native java.lang.Class getPrimitiveClass(java.lang.String);
*/
public
void java_lang_Class_getPrimitiveClass(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
helper.assignObjectTo(returnVar, Environment.v().getClassObject());
}
/**
* Returns an array containing Field objects reflecting all the
* accessible public fields of the class or interface represented by
* this Class object.
*
* private native java.lang.reflect.Field getFields0(int)[];
*/
public
void java_lang_Class_getFields0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
helper.assignObjectTo(returnVar, Environment.v().getLeastArrayObject());
}
/**
* Returns an array containing Method objects reflecting all the
* public member methods of the class or interface represented by
* this Class object, including those declared by the class or
* interface and and those inherited from superclasses and
* superinterfaces.
*
* private native java.lang.reflect.Method getMethods0(int)[];
*/
public
void java_lang_Class_getMethods0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
helper.assignObjectTo(returnVar, Environment.v().getLeastArrayObject());
}
/**
* Returns a Constructor object that reflects the specified public
* constructor of the class represented by this Class object. The
* parameterTypes parameter is an array of Class objects that
* identify the constructor's formal parameter types, in declared
* order.
*
* private native java.lang.reflect.Constructor getConstructors0(int)[];
*/
public
void java_lang_Class_getConstructors0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
helper.assignObjectTo(returnVar, Environment.v().getLeastArrayObject());
}
/**
* Returns a Field object that reflects the specified public member
* field of the class or interface represented by this Class object.
*
* Called by getField(String)
*
* NOTE: getField0(String name), since the name can be dynamically
* constructed, it may be not able to know exact field name
* in static analysis. Uses a C.F to represent the class field.
*
* private native java.lang.reflect.Field getField0(java.lang.String,
* int);
*/
public
void java_lang_Class_getField0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]){
helper.assignObjectTo(returnVar, Environment.v().getFieldObject());
}
/**
* Returns a Method object that reflects the specified public member
* method of the class or interface represented by this Class
* object.
*
* Called by getMethod()
*
* private native java.lang.reflect.Method getMethod0(java.lang.String,
* java.lang.Class[],
* int);
*/
public
void java_lang_Class_getMethod0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]){
helper.assignObjectTo(returnVar, Environment.v().getMethodObject());
}
/**
* Returns a constructor of a class
*
* private native java.lang.reflect.Constructor
* getConstructor0(java.lang.Class[], int);
*/
public
void java_lang_Class_getConstructor0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]){
helper.assignObjectTo(returnVar, Environment.v().getConstructorObject());
}
/**
* Returns an array of Class objects reflecting all the classes and
* interfaces declared as members of the class represented by this
* Class object.
*
* private native java.lang.Class getDeclaredClasses0()[];
*/
public
void java_lang_Class_getDeclaredClasses0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
helper.assignObjectTo(returnVar, Environment.v().getLeastArrayObject());
}
/**
* Returns an array of Constructor objects reflecting all the classes and
* interfaces declared as members of the class represented by this
* Class object.
*
* private native java.lang.Class getDeclaredConstructors0(boolean)[];
*/
public
void java_lang_Class_getDeclaredConstructors0(SootMethod method,
ReferenceVariable thisVar,
ReferenceVariable returnVar,
ReferenceVariable params[]) {
AbstractObject array = Environment.v().getLeastArrayObject();
AbstractObject cons = Environment.v().getConstructorObject();
helper.assignObjectTo(returnVar, array);
helper.assignObjectTo(helper.arrayElementOf(returnVar), cons);
}
/**
* Following methods have NO side effects.
*
* private static native void registerNatives();
* public native boolean isInstance(java.lang.Object);
* public native boolean isAssignableFrom(java.lang.Class);
* public native boolean isInterface();
* public native boolean isArray();
* public native boolean isPrimitive();
* public native int getModifiers();
*/
}