use of org.objectweb.asm.Type in project android_frameworks_base by DirtyUnicorns.
the class TransformClassAdapter method visitMethod.
/* Visits a method. */
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (mDeleteReturns != null) {
Type t = Type.getReturnType(desc);
if (t.getSort() == Type.OBJECT) {
String returnType = t.getInternalName();
if (returnType != null) {
if (mDeleteReturns.contains(returnType)) {
return null;
}
}
}
}
String methodSignature = mClassName.replace('/', '.') + "#" + name;
// remove final
access = access & ~Opcodes.ACC_FINAL;
// and don't try to stub interfaces nor abstract non-native methods.
if (!mIsInterface && ((access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) != Opcodes.ACC_ABSTRACT) && (mStubAll || (access & Opcodes.ACC_NATIVE) != 0) || mStubMethods.contains(methodSignature)) {
boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
// remove abstract, final and native
access = access & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_NATIVE);
String invokeSignature = methodSignature + desc;
mLog.debug(" Stub: %s (%s)", invokeSignature, isNative ? "native" : "");
MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature, isStatic, isNative);
} else {
mLog.debug(" Keep: %s %s", name, desc);
return super.visitMethod(access, name, desc, signature, exceptions);
}
}
use of org.objectweb.asm.Type in project hudson-2.x by hudson.
the class SubClassGenerator method generate.
public <T> Class<? extends T> generate(Class<T> base, String name) {
//?
ClassWriter cw = new ClassWriter(false, false);
cw.visit(49, ACC_PUBLIC, name.replace('.', '/'), null, Type.getInternalName(base), null);
for (Constructor c : base.getDeclaredConstructors()) {
Class[] et = c.getExceptionTypes();
String[] exceptions = new String[et.length];
for (int i = 0; i < et.length; i++) exceptions[i] = Type.getInternalName(et[i]);
String methodDescriptor = getMethodDescriptor(c);
MethodVisitor m = cw.visitMethod(c.getModifiers(), "<init>", methodDescriptor, null, exceptions);
m.visitCode();
int index = 1;
m.visitVarInsn(ALOAD, 0);
for (Class param : c.getParameterTypes()) {
Type t = Type.getType(param);
m.visitVarInsn(t.getOpcode(ILOAD), index);
index += t.getSize();
}
m.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(base), "<init>", methodDescriptor);
m.visitInsn(RETURN);
m.visitMaxs(index, index);
m.visitEnd();
}
cw.visitEnd();
byte[] image = cw.toByteArray();
Class<? extends T> c = defineClass(name, image, 0, image.length).asSubclass(base);
Hudson h = Hudson.getInstance();
if (// null only during tests.
h != null)
// can't change the field type as it breaks binary compatibility
((UberClassLoader) h.pluginManager.uberClassLoader).addNamedClass(name, c);
return c;
}
use of org.objectweb.asm.Type in project aries by apache.
the class TCCLSetterVisitor method visitEnd.
@Override
public void visitEnd() {
if (!woven) {
// if this class wasn't woven, then don't add the synthesized method either.
super.visitEnd();
return;
}
// Add generated static method
Set<String> methodNames = new HashSet<String>();
for (WeavingData wd : weavingData) {
/* Equivalent to:
* private static void $$FCCL$$<className>$<methodName>(Class<?> cls) {
* Util.fixContextClassLoader("java.util.ServiceLoader", "load", cls, WovenClass.class.getClassLoader());
* }
*/
String methodName = getGeneratedMethodName(wd);
if (methodNames.contains(methodName))
continue;
methodNames.add(methodName);
Method method = new Method(methodName, Type.VOID_TYPE, new Type[] { CLASS_TYPE });
GeneratorAdapter mv = new GeneratorAdapter(cv.visitMethod(ACC_PRIVATE + ACC_STATIC, methodName, method.getDescriptor(), null, null), ACC_PRIVATE + ACC_STATIC, methodName, method.getDescriptor());
//Load the strings, method parameter and target
mv.visitLdcInsn(wd.getClassName());
mv.visitLdcInsn(wd.getMethodName());
mv.loadArg(0);
mv.visitLdcInsn(targetClass);
//Change the class on the stack into a classloader
mv.invokeVirtual(CLASS_TYPE, new Method("getClassLoader", CLASSLOADER_TYPE, new Type[0]));
//Call our util method
mv.invokeStatic(UTIL_CLASS, new Method("fixContextClassloader", Type.VOID_TYPE, new Type[] { String_TYPE, String_TYPE, CLASS_TYPE, CLASSLOADER_TYPE }));
mv.returnValue();
mv.endMethod();
}
super.visitEnd();
}
use of org.objectweb.asm.Type in project aries by apache.
the class ProxySubclassAdapter method processMethod.
private void processMethod(int access, String name, String desc, String signature, String[] exceptions) {
LOGGER.debug(Constants.LOG_ENTRY, "processMethod", new Object[] { access, name, desc, signature, exceptions });
LOGGER.debug("Processing method: {} with descriptor {}", name, desc);
// identify the target method parameters and return type
Method currentTransformMethod = new Method(name, desc);
Type[] targetMethodParameters = currentTransformMethod.getArgumentTypes();
Type returnType = currentTransformMethod.getReturnType();
// we create a static field for each method we encounter with a name
// like method_parm1_parm2...
StringBuilder methodStaticFieldNameBuilder = new StringBuilder(name);
// the dots first
for (Type t : targetMethodParameters) {
methodStaticFieldNameBuilder.append("_");
methodStaticFieldNameBuilder.append(t.getClassName().replaceAll("\\[\\]", "Array").replaceAll("\\.", ""));
}
String methodStaticFieldName = methodStaticFieldNameBuilder.toString();
// add a private static field for the method
cv.visitField(ACC_PRIVATE | ACC_STATIC, methodStaticFieldName, METHOD_TYPE.getDescriptor(), null, null);
// visit the method using the class writer, delegated through the method
// visitor and generator
// modify the method access so that any native methods aren't
// described as native
// since they won't be native in proxy form
// also stop methods being marked synchronized on the proxy as they will
// be sync
// on the real object
int newAccess = access & (~ACC_NATIVE) & (~ACC_SYNCHRONIZED);
MethodVisitor mv = cv.visitMethod(newAccess, name, desc, signature, exceptions);
// use a GeneratorAdapter to build the invoke call directly in byte code
GeneratorAdapter methodAdapter = new GeneratorAdapter(mv, newAccess, name, desc);
/*
* Stage 1 creates the bytecode for adding the reflected method of the
* superclass to a static field in the subclass: private static Method
* methodName_parm1_parm2... = null; static{ methodName_parm1_parm2... =
* superClass.getDeclaredMethod(methodName,new Class[]{method args}; }
*
* Stage 2 is to call the ih.invoke(this,methodName_parm1_parm2,args) in
* the new subclass methods Stage 3 is to cast the return value to the
* correct type
*/
/*
* Stage 1 use superClass.getMethod(methodName,new Class[]{method args}
* from the Class object on the stack
*/
// load the static superclass Class onto the stack
staticAdapter.getStatic(newClassType, currentClassFieldName, CLASS_TYPE);
// push the method name string arg onto the stack
staticAdapter.push(name);
// create an array of the method parm class[] arg
staticAdapter.push(targetMethodParameters.length);
staticAdapter.newArray(CLASS_TYPE);
int index = 0;
for (Type t : targetMethodParameters) {
staticAdapter.dup();
staticAdapter.push(index);
switch(t.getSort()) {
case Type.BOOLEAN:
staticAdapter.getStatic(Type.getType(java.lang.Boolean.class), "TYPE", CLASS_TYPE);
break;
case Type.BYTE:
staticAdapter.getStatic(Type.getType(java.lang.Byte.class), "TYPE", CLASS_TYPE);
break;
case Type.CHAR:
staticAdapter.getStatic(Type.getType(java.lang.Character.class), "TYPE", CLASS_TYPE);
break;
case Type.DOUBLE:
staticAdapter.getStatic(Type.getType(java.lang.Double.class), "TYPE", CLASS_TYPE);
break;
case Type.FLOAT:
staticAdapter.getStatic(Type.getType(java.lang.Float.class), "TYPE", CLASS_TYPE);
break;
case Type.INT:
staticAdapter.getStatic(Type.getType(java.lang.Integer.class), "TYPE", CLASS_TYPE);
break;
case Type.LONG:
staticAdapter.getStatic(Type.getType(java.lang.Long.class), "TYPE", CLASS_TYPE);
break;
case Type.SHORT:
staticAdapter.getStatic(Type.getType(java.lang.Short.class), "TYPE", CLASS_TYPE);
break;
default:
case Type.OBJECT:
staticAdapter.push(t);
break;
}
staticAdapter.arrayStore(CLASS_TYPE);
index++;
}
// invoke the getMethod
staticAdapter.invokeVirtual(CLASS_TYPE, new Method("getDeclaredMethod", METHOD_TYPE, new Type[] { STRING_TYPE, Type.getType(java.lang.Class[].class) }));
// store the reflected method in the static field
staticAdapter.putStatic(newClassType, methodStaticFieldName, METHOD_TYPE);
/*
* Stage 2 call the ih.invoke(this,supermethod,parms)
*/
// load this to get the ih field
methodAdapter.loadThis();
// load the invocation handler from the field (the location of the
// InvocationHandler.invoke)
methodAdapter.getField(newClassType, IH_FIELD, IH_TYPE);
// loadThis (the first arg of the InvocationHandler.invoke)
methodAdapter.loadThis();
// load the method to invoke (the second arg of the
// InvocationHandler.invoke)
methodAdapter.getStatic(newClassType, methodStaticFieldName, METHOD_TYPE);
// load all the method arguments onto the stack as an object array (the
// third arg of the InvocationHandler.invoke)
methodAdapter.loadArgArray();
// generate the invoke method
Method invocationHandlerInvokeMethod = new Method("invoke", OBJECT_TYPE, new Type[] { OBJECT_TYPE, METHOD_TYPE, Type.getType(java.lang.Object[].class) });
// call the invoke method of the invocation handler
methodAdapter.invokeInterface(IH_TYPE, invocationHandlerInvokeMethod);
/*
* Stage 3 the returned object is now on the top of the stack We need to
* check the type and cast as necessary
*/
switch(returnType.getSort()) {
case Type.BOOLEAN:
methodAdapter.cast(OBJECT_TYPE, Type.getType(Boolean.class));
methodAdapter.unbox(Type.BOOLEAN_TYPE);
break;
case Type.BYTE:
methodAdapter.cast(OBJECT_TYPE, Type.getType(Byte.class));
methodAdapter.unbox(Type.BYTE_TYPE);
break;
case Type.CHAR:
methodAdapter.cast(OBJECT_TYPE, Type.getType(Character.class));
methodAdapter.unbox(Type.CHAR_TYPE);
break;
case Type.DOUBLE:
methodAdapter.cast(OBJECT_TYPE, Type.getType(Double.class));
methodAdapter.unbox(Type.DOUBLE_TYPE);
break;
case Type.FLOAT:
methodAdapter.cast(OBJECT_TYPE, Type.getType(Float.class));
methodAdapter.unbox(Type.FLOAT_TYPE);
break;
case Type.INT:
methodAdapter.cast(OBJECT_TYPE, Type.getType(Integer.class));
methodAdapter.unbox(Type.INT_TYPE);
break;
case Type.LONG:
methodAdapter.cast(OBJECT_TYPE, Type.getType(Long.class));
methodAdapter.unbox(Type.LONG_TYPE);
break;
case Type.SHORT:
methodAdapter.cast(OBJECT_TYPE, Type.getType(Short.class));
methodAdapter.unbox(Type.SHORT_TYPE);
break;
case Type.VOID:
methodAdapter.cast(OBJECT_TYPE, Type.getType(Void.class));
methodAdapter.unbox(Type.VOID_TYPE);
break;
default:
case Type.OBJECT:
// in this case check the cast and cast the object to the return
// type
methodAdapter.checkCast(returnType);
methodAdapter.cast(OBJECT_TYPE, returnType);
break;
}
// return the (appropriately cast) result of the invocation from the
// stack
methodAdapter.returnValue();
// end the method
methodAdapter.endMethod();
LOGGER.debug(Constants.LOG_EXIT, "processMethod");
}
use of org.objectweb.asm.Type in project aries by apache.
the class ProxySubclassAdapter method addClassStaticField.
private void addClassStaticField(String classBinaryName) {
LOGGER.debug(Constants.LOG_ENTRY, "addClassStaticField", new Object[] { classBinaryName });
currentClassFieldName = classBinaryName.replaceAll("\\.", "_");
/*
* use Class.forName on the superclass so we can reflectively find
* methods later
*
* produces bytecode for retrieving the superclass and storing in a
* private static field: private static Class superClass = null; static{
* superClass = Class.forName(superclass, true, TYPE_BEING_PROXIED.class.getClassLoader()); }
*/
// add a private static field for the superclass Class
cv.visitField(ACC_PRIVATE | ACC_STATIC, currentClassFieldName, CLASS_TYPE.getDescriptor(), null, null);
// push the String arg for the Class.forName onto the stack
staticAdapter.push(classBinaryName);
//push the boolean arg for the Class.forName onto the stack
staticAdapter.push(true);
//get the classloader
staticAdapter.push(newClassType);
staticAdapter.invokeVirtual(CLASS_TYPE, new Method("getClassLoader", CLASSLOADER_TYPE, NO_ARGS));
// invoke the Class forName putting the Class on the stack
staticAdapter.invokeStatic(CLASS_TYPE, new Method("forName", CLASS_TYPE, new Type[] { STRING_TYPE, Type.BOOLEAN_TYPE, CLASSLOADER_TYPE }));
// put the Class in the static field
staticAdapter.putStatic(newClassType, currentClassFieldName, CLASS_TYPE);
LOGGER.debug(Constants.LOG_ENTRY, "addClassStaticField");
}
Aggregations