use of org.objectweb.asm.commons.Method in project aries by apache.
the class AbstractWovenProxyMethodAdapter method unwrapEqualsArgument.
/**
* This method unwraps woven proxy instances for use in the right-hand side
* of equals methods
*/
protected final void unwrapEqualsArgument() {
// Create and initialize a local for our work
int unwrapLocal = newLocal(OBJECT_TYPE);
visitInsn(ACONST_NULL);
storeLocal(unwrapLocal);
Label startUnwrap = newLabel();
mark(startUnwrap);
// Load arg and check if it is a WovenProxy instances
loadArg(0);
instanceOf(WOVEN_PROXY_IFACE_TYPE);
Label unwrapFinished = newLabel();
// Jump if zero (false)
visitJumpInsn(Opcodes.IFEQ, unwrapFinished);
// Arg is a wovenProxy, if it is the same as last time then we're done
loadLocal(unwrapLocal);
loadArg(0);
ifCmp(OBJECT_TYPE, EQ, unwrapFinished);
// Not the same, store current arg in unwrapLocal for next loop
loadArg(0);
storeLocal(unwrapLocal);
// So arg is a WovenProxy, but not the same as last time, cast it and store
// the result of unwrap.call in the arg
loadArg(0);
checkCast(WOVEN_PROXY_IFACE_TYPE);
// Now unwrap
invokeInterface(WOVEN_PROXY_IFACE_TYPE, new Method("org_apache_aries_proxy_weaving_WovenProxy_unwrap", DISPATCHER_TYPE, NO_ARGS));
// Now we may have a Callable to invoke
int callable = newLocal(DISPATCHER_TYPE);
storeLocal(callable);
loadLocal(callable);
ifNull(unwrapFinished);
loadLocal(callable);
invokeInterface(DISPATCHER_TYPE, new Method("call", OBJECT_TYPE, NO_ARGS));
// Store the result and we're done (for this iteration)
storeArg(0);
goTo(startUnwrap);
mark(unwrapFinished);
}
use of org.objectweb.asm.commons.Method in project aries by apache.
the class MethodCopyingClassAdapter method visitMethod.
@Override
public final MethodVisitor visitMethod(final int access, String name, String desc, String sig, String[] exceptions) {
MethodVisitor mv = null;
// abstract ones!.
if (!!!name.equals("<init>") && !!!name.equals("<clinit>") && (access & (ACC_STATIC | ACC_PRIVATE | ACC_SYNTHETIC | ACC_ABSTRACT | ACC_NATIVE | ACC_BRIDGE)) == 0) {
// identify the target method parameters and return type
Method currentTransformMethod = new Method(name, desc);
// We don't want to duplicate a method we already overrode!
if (!!!knownMethods.add(currentTransformMethod))
return null;
// We can't override a final method
if ((access & ACC_FINAL) != 0)
throw new RuntimeException(new FinalModifierException(superToCopy, name));
// package
if ((access & (ACC_PUBLIC | ACC_PROTECTED | ACC_PRIVATE)) == 0) {
if (!!!samePackage) {
methodHiddenException(name);
}
}
// Safe to copy a call to this method!
Type superType = Type.getType(superToCopy);
// identify the target method parameters and return type
String methodStaticFieldName = "methodField" + AbstractWovenProxyAdapter.getSanitizedUUIDString();
transformedMethods.put(methodStaticFieldName, new TypeMethod(superType, currentTransformMethod));
// Remember we need to copy the fake method *and* weave it, use a
// WovenProxyMethodAdapter as well as a CopyingMethodAdapter
MethodVisitor weaver = wovenProxyAdapter.getWeavingMethodVisitor(access, name, desc, sig, exceptions, currentTransformMethod, methodStaticFieldName, superType, false);
if (weaver instanceof AbstractWovenProxyMethodAdapter) {
// gets around the problem, but if not the class will fail verification.
if (!samePackage && (access & ACC_PROTECTED) != 0) {
methodHiddenException(name);
}
mv = new CopyingMethodAdapter((GeneratorAdapter) weaver, superType, currentTransformMethod);
} else {
// For whatever reason we aren't weaving this method. The call to super.xxx() will always work
mv = new CopyingMethodAdapter(new GeneratorAdapter(access, currentTransformMethod, mv), superType, currentTransformMethod);
}
}
return mv;
}
use of org.objectweb.asm.commons.Method 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) {
String methodName = getGeneratedMethodName(wd);
if (methodNames.contains(methodName))
continue;
methodNames.add(methodName);
if (ServiceLoader.class.getName().equals(wd.getClassName())) {
continue;
}
/* Equivalent to:
* private static void $$FCCL$$<className>$<methodName>(Class<?> cls) {
* Util.fixContextClassLoader("java.util.ServiceLoader", "load", cls, WovenClass.class.getClassLoader());
* }
*/
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.commons.Method in project Payara by payara.
the class ProviderImplGenerator method generateClassData.
public byte[] generateClassData(FlashlightProbeProvider provider, Class providerClazz, String generatedClassName) {
Type classType = Type.getType(providerClazz);
if (logger.isLoggable(Level.FINE)) {
logger.fine("** classType: " + classType);
logger.fine("** classDesc: " + Type.getDescriptor(providerClazz));
logger.fine("Generating for: " + generatedClassName);
}
generatedClassName = generatedClassName.replace('.', '/');
int cwFlags = ClassWriter.COMPUTE_FRAMES + ClassWriter.COMPUTE_MAXS;
ClassWriter cw = new ClassWriter(cwFlags);
int access = Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL;
String[] interfaces = new String[] { providerClazz.getName().replace('.', '/') };
cw.visit(Opcodes.V1_5, access, generatedClassName, null, "java/lang/Object", interfaces);
for (FlashlightProbe probe : provider.getProbes()) {
Type probeType = Type.getType(FlashlightProbe.class);
int fieldAccess = Opcodes.ACC_PUBLIC;
String fieldName = "_flashlight_" + probe.getProbeName();
cw.visitField(fieldAccess, fieldName, probeType.getDescriptor(), null, null);
}
Type probeType = Type.getType(FlashlightProbe.class);
for (FlashlightProbe probe : provider.getProbes()) {
StringBuilder methodDesc = new StringBuilder();
methodDesc.append("void ").append(probe.getProviderJavaMethodName());
methodDesc.append("(");
String delim = "";
for (Class paramType : probe.getParamTypes()) {
methodDesc.append(delim).append(paramType.getName());
delim = ", ";
}
methodDesc.append(")");
Method m = Method.getMethod(methodDesc.toString());
GeneratorAdapter gen = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null, null, cw);
String fieldName = "_flashlight_" + probe.getProbeName();
gen.loadThis();
gen.visitFieldInsn(Opcodes.GETFIELD, generatedClassName, fieldName, probeType.getDescriptor());
int index = gen.newLocal(probeType);
gen.storeLocal(index);
gen.loadLocal(index);
gen.invokeVirtual(probeType, Method.getMethod("boolean isEnabled()"));
gen.push(true);
Label enabledLabel = new Label();
Label notEnabledLabel = new Label();
gen.ifCmp(Type.getType(boolean.class), GeneratorAdapter.EQ, enabledLabel);
gen.goTo(notEnabledLabel);
gen.visitLabel(enabledLabel);
gen.loadLocal(index);
gen.loadArgArray();
gen.invokeVirtual(probeType, Method.getMethod("void fireProbe(Object[])"));
gen.visitLabel(notEnabledLabel);
gen.returnValue();
gen.endMethod();
}
generateConstructor(cw, generatedClassName, provider);
cw.visitEnd();
byte[] classData = cw.toByteArray();
int index = generatedClassName.lastIndexOf('.');
String clsName = generatedClassName.substring(index + 1);
if (Boolean.parseBoolean(System.getenv("AS_DEBUG"))) {
if (logger.isLoggable(Level.FINE))
logger.fine("Generated ClassDATA " + clsName);
// the path is horribly long. Let's just write t directly into the
// lib dir. It is not for loading as a class but just for us humans
// to decompile to figure out what is going on. No need to make it even harder!
clsName = clsName.replace('.', '/');
// just in case Windows? unlikely...
clsName = clsName.replace('\\', '/');
index = clsName.lastIndexOf('/');
if (index >= 0)
clsName = clsName.substring(index + 1);
FileOutputStream fos = null;
try {
String rootPath = System.getProperty(SystemPropertyConstants.INSTALL_ROOT_PROPERTY) + File.separator + "lib" + File.separator;
String fileName = rootPath + clsName + ".class";
if (logger.isLoggable(Level.FINE))
logger.fine("ClassFile: " + fileName);
File file = new File(fileName);
if (FileUtils.mkdirsMaybe(file.getParentFile())) {
fos = new FileOutputStream(file);
fos.write(classData);
fos.flush();
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (fos != null)
fos.close();
} catch (Exception e) {
// nothing can be done...
}
}
}
return classData;
}
use of org.objectweb.asm.commons.Method in project Payara by payara.
the class BtraceClientGenerator method generateBtraceClientClassData.
public static byte[] generateBtraceClientClassData(int clientID, Collection<FlashlightProbe> probes) {
// create a unique name. It does not matter what the name is.
String generatedClassName = "com/sun/btrace/flashlight/BTrace_Flashlight_" + clientID;
// Start of writing a class using ASM, which will be our BTrace Client
int cwFlags = ClassWriter.COMPUTE_FRAMES + ClassWriter.COMPUTE_MAXS;
ClassWriter cw = new ClassWriter(cwFlags);
// Define the access identifiers for the BTrace Client class
int access = Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL;
cw.visit(Opcodes.V1_5, access, generatedClassName, null, "java/lang/Object", null);
// Need a @OnMethod annotation, so prepare your Annotation Visitor for that
cw.visitAnnotation("Lcom/sun/btrace/annotations/BTrace;", true);
// Iterate through the probes, so you will create one method for each probe
int methodCounter = 0;
for (FlashlightProbe probe : probes) {
// Preparing the class method header and params (type) for @OnMethod annotation
StringBuilder typeDesc = new StringBuilder("void ");
StringBuilder methodDesc = new StringBuilder("void __");
methodDesc.append(probe.getProviderJavaMethodName()).append("__");
methodDesc.append(clientID).append("_").append(methodCounter).append("_");
methodDesc.append("(");
typeDesc.append("(");
String delim = "";
String typeDelim = "";
Class[] paramTypes = probe.getParamTypes();
for (int index = 0; index < paramTypes.length; index++) {
Class paramType = paramTypes[index];
methodDesc.append(delim).append(paramType.getName());
// Dont add the param type for type desc, if self is the first index
if (!(probe.hasSelf() && (index == 0))) {
typeDesc.append(typeDelim).append(paramType.getName());
typeDelim = ",";
}
delim = ", ";
}
methodDesc.append(")");
typeDesc.append(")");
// Creating the class method
Method m = Method.getMethod(methodDesc.toString());
GeneratorAdapter gen = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, m, null, null, cw);
// Add the @Self annotation
if (probe.hasSelf()) {
String[] paramNames = probe.getProbeParamNames();
for (int index = 0; index < paramNames.length; index++) {
if (paramNames[index].equalsIgnoreCase(FlashlightProbe.SELF)) {
AnnotationVisitor paramVisitor = gen.visitParameterAnnotation(index, "Lcom/sun/btrace/annotations/Self;", true);
paramVisitor.visitEnd();
}
}
}
// Add the @OnMethod annotation to this method
AnnotationVisitor av = gen.visitAnnotation("Lcom/sun/btrace/annotations/OnMethod;", true);
av.visit("clazz", "" + probe.getProviderClazz().getName());
av.visit("method", probe.getProviderJavaMethodName());
av.visit("type", typeDesc.toString());
av.visitEnd();
// Add the body
gen.push(probe.getId());
gen.loadArgArray();
gen.invokeStatic(Type.getType(ProbeRegistry.class), Method.getMethod("void invokeProbe(int, Object[])"));
gen.returnValue();
gen.endMethod();
methodCounter++;
}
BtraceClientGenerator.generateConstructor(cw);
cw.visitEnd();
byte[] classData = cw.toByteArray();
writeClass(classData, generatedClassName);
return classData;
}
Aggregations