use of org.objectweb.asm.commons.GeneratorAdapter in project eclipse.themes.darker by jinmingjian.
the class DarkerWeavingHook method transform.
public void transform(WovenClass wovenClass) {
byte[] bytes = wovenClass.getBytes();
ClassReader cr = new ClassReader(bytes);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
cr.accept(cw, 0);
Method md = Method.getMethod("org.eclipse.swt.graphics.Color getForeground ()");
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, md.getName(), md.getDescriptor(), null, null);
final GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, md, mv);
final Label LABEL_SKIP_CALL_TO_SUPER = new Label();
final Label LABEL_LOOP_CMP = new Label();
final Label LABEL_LOOP_START = new Label();
mg.newInstance(Type.getType(Exception.class));
mg.dup();
mg.invokeConstructor(Type.getType(Exception.class), Method.getMethod("void <init> ()"));
mg.invokeVirtual(Type.getType(Exception.class), Method.getMethod("StackTraceElement[] getStackTrace ()"));
mg.storeLocal(1, Type.getType(StackTraceElement[].class));
mg.push(10);
mg.storeLocal(2, Type.getType(int.class));
mg.goTo(LABEL_LOOP_CMP);
mg.mark(LABEL_LOOP_START);
mg.loadLocal(1);
mg.loadLocal(2);
mg.arrayLoad(Type.getType(StackTraceElement.class));
mg.invokeVirtual(Type.getType(StackTraceElement.class), Method.getMethod("String getClassName ()"));
mg.push("Dialog");
mg.invokeVirtual(Type.getType(String.class), Method.getMethod("int indexOf (String)"));
mg.push(-1);
mg.ifICmp(GeneratorAdapter.EQ, LABEL_SKIP_CALL_TO_SUPER);
// //XXX: DEBUG
// mg.getStatic(Type.getType(System.class), "out", Type.getType(java.io.PrintStream.class));
// mg.push("2");
// mg.invokeVirtual(Type.getType(java.io.PrintStream.class), Method.getMethod("void println (String)"));
// //XXX: DEBUG
mg.loadThis();
mg.invokeConstructor(Type.getType("Lorg/eclipse/swt/widgets/Control;"), Method.getMethod("org.eclipse.swt.graphics.Color getForeground ()"));
mg.returnValue();
mg.mark(LABEL_SKIP_CALL_TO_SUPER);
mg.iinc(2, 1);
mg.mark(LABEL_LOOP_CMP);
mg.loadLocal(2);
mg.loadLocal(1);
mg.arrayLength();
mg.ifICmp(GeneratorAdapter.LT, LABEL_LOOP_START);
mg.loadThis();
mg.invokeVirtual(Type.getType("Lorg/eclipse/swt/custom/CLabel;"), Method.getMethod("org.eclipse.swt.widgets.Display getDisplay ()"));
mg.push(1);
mg.invokeVirtual(Type.getType("Lorg/eclipse/swt/widgets/Display;"), Method.getMethod("org.eclipse.swt.graphics.Color getSystemColor (int)"));
mg.returnValue();
mg.endMethod();
cw.visitEnd();
wovenClass.setBytes(cw.toByteArray());
}
use of org.objectweb.asm.commons.GeneratorAdapter in project MinecraftForge by MinecraftForge.
the class ASMTransformerWrapper method makeWrapper.
private static byte[] makeWrapper(String fileName) {
if (!wrapperModMap.containsKey(fileName) || !wrapperParentMap.containsKey(fileName) || !fileName.endsWith(".class")) {
throw new IllegalArgumentException("makeWrapper called with strange argument: " + fileName);
}
String name = fileName.substring(0, fileName.length() - ".class".length());
try {
Type wrapper = Type.getType(TransformerWrapper.class);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
writer.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, name, null, wrapper.getInternalName(), null);
Method m = Method.getMethod("void <init> ()");
GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null, null, writer);
mg.loadThis();
mg.invokeConstructor(wrapper, m);
mg.returnValue();
mg.endMethod();
m = Method.getMethod("java.lang.String getParentClass ()");
mg = new GeneratorAdapter(Opcodes.ACC_PROTECTED, m, null, null, writer);
mg.push(wrapperParentMap.get(fileName));
mg.returnValue();
mg.endMethod();
m = Method.getMethod("java.lang.String getCoreMod ()");
mg = new GeneratorAdapter(Opcodes.ACC_PROTECTED, m, null, null, writer);
mg.push(wrapperModMap.get(fileName));
mg.returnValue();
mg.endMethod();
writer.visitEnd();
return writer.toByteArray();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of org.objectweb.asm.commons.GeneratorAdapter in project robolectric by robolectric.
the class ProxyMaker method createProxyFactory.
<T> Factory createProxyFactory(Class<T> targetClass) {
Type targetType = Type.getType(targetClass);
String targetName = targetType.getInternalName();
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
writer.visit(V1_7, ACC_PUBLIC | ACC_SUPER | ACC_FINAL, PROXY_NAME, null, targetName, null);
writer.visitField(ACC_PUBLIC, TARGET_FIELD, targetType.getDescriptor(), null, null);
for (java.lang.reflect.Method method : targetClass.getMethods()) {
if (!shouldProxy(method))
continue;
Method proxyMethod = Method.getMethod(method);
GeneratorAdapter m = new GeneratorAdapter(ACC_PUBLIC, Method.getMethod(method), null, null, writer);
m.loadThis();
m.getField(PROXY_TYPE, TARGET_FIELD, targetType);
m.loadArgs();
String targetMethod = methodMapper.getName(targetClass.getName(), method.getName());
// In Java 8 we could use invokespecial here but not in 7, from jvm spec:
// If an invokespecial instruction names a method which is not an instance
// initialization method, then the type of the target reference on the operand
// stack must be assignment compatible with the current class (JLS ยง5.2).
m.visitMethodInsn(INVOKEVIRTUAL, targetName, targetMethod, proxyMethod.getDescriptor(), false);
m.returnValue();
m.endMethod();
}
writer.visitEnd();
final Class<?> proxyClass = UNSAFE.defineAnonymousClass(targetClass, writer.toByteArray(), null);
try {
final MethodHandle setter = LOOKUP.findSetter(proxyClass, TARGET_FIELD, targetClass);
return new Factory() {
@Override
public <E> E createProxy(Class<E> targetClass, E target) {
try {
Object proxy = UNSAFE.allocateInstance(proxyClass);
setter.invoke(proxy, target);
return targetClass.cast(proxy);
} catch (Throwable t) {
throw new AssertionError(t);
}
}
};
} catch (IllegalAccessException | NoSuchFieldException e) {
throw new AssertionError(e);
}
}
use of org.objectweb.asm.commons.GeneratorAdapter in project robovm by robovm.
the class LambdaClassGenerator method createForwardingMethod.
private void createForwardingMethod(SootClass caller, String lambdaClassName, ClassWriter cw, String name, List<Type> parameters, Type returnType, List<Type> invokedParameters, SootMethodType samMethodType, SootMethodHandle implMethod, SootMethodType instantiatedMethodType, boolean isBridgeMethod) {
String descriptor = Types.getDescriptor(parameters, returnType);
String implClassName = implMethod.getMethodRef().declaringClass().getName().replace('.', '/');
int accessFlags = ACC_PUBLIC | (isBridgeMethod ? ACC_BRIDGE : 0);
MethodVisitor mv = cw.visitMethod(accessFlags, name, descriptor, null, null);
mv.visitCode();
// figure out the invoke op code for the lambda implementation
// as well as if it's an instance method.
int invokeOpCode = INVOKESTATIC;
boolean isInstanceMethod = false;
switch(implMethod.getReferenceKind()) {
case SootMethodHandle.REF_invokeInterface:
invokeOpCode = INVOKEINTERFACE;
isInstanceMethod = true;
break;
case SootMethodHandle.REF_invokeSpecial:
invokeOpCode = INVOKESPECIAL;
isInstanceMethod = true;
break;
case SootMethodHandle.REF_newInvokeSpecial:
invokeOpCode = INVOKESPECIAL;
break;
case SootMethodHandle.REF_invokeStatic:
invokeOpCode = INVOKESTATIC;
break;
case SootMethodHandle.REF_invokeVirtual:
invokeOpCode = INVOKEVIRTUAL;
isInstanceMethod = true;
break;
default:
throw new CompilerException("Unknown invoke type: " + implMethod.getReferenceKind());
}
GeneratorAdapter caster = new GeneratorAdapter(mv, accessFlags, name, descriptor);
// push the arguments
pushArguments(caller, lambdaClassName, mv, caster, parameters, invokedParameters, implMethod, instantiatedMethodType, isInstanceMethod);
// generate a descriptor for the lambda implementation
// to invoke based on the parameters. If the lambda
// is an instance method, we need to remove the first
// parameter for the descriptor generation as it's
// not part of the method signature.
String implDescriptor = null;
List<Type> paramTypes = new ArrayList<Type>(implMethod.getMethodType().getParameterTypes());
if (isInstanceMethod)
paramTypes.remove(0);
implDescriptor = Types.getDescriptor(paramTypes, implMethod.getMethodType().getReturnType());
// call the lambda implementation
mv.visitMethodInsn(invokeOpCode, implClassName, implMethod.getMethodRef().name(), implDescriptor, invokeOpCode == INVOKEINTERFACE);
// emit the return instruction based on the return type
createForwardingMethodReturn(mv, caster, returnType, samMethodType, implMethod, instantiatedMethodType);
mv.visitMaxs(-1, -1);
mv.visitEnd();
}
use of org.objectweb.asm.commons.GeneratorAdapter in project aries by apache.
the class AbstractWovenProxyAdapter method writeStaticInitMethod.
/**
* Create fields and an initialiser for {@link java.lang.reflect.Method}
* objects in our class
*/
private final void writeStaticInitMethod() {
for (String methodStaticFieldName : transformedMethods.keySet()) {
// add a private static field for the method
cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, methodStaticFieldName, METHOD_TYPE.getDescriptor(), null, null).visitEnd();
}
GeneratorAdapter staticAdapter = new GeneratorAdapter(staticInitMethodFlags, staticInitMethod, null, null, cv);
for (Entry<String, TypeMethod> entry : transformedMethods.entrySet()) {
// Add some more code to the static initializer
TypeMethod m = entry.getValue();
Type[] targetMethodParameters = m.method.getArgumentTypes();
String methodStaticFieldName = entry.getKey();
Label beginPopulate = staticAdapter.newLabel();
Label endPopulate = staticAdapter.newLabel();
Label catchHandler = staticAdapter.newLabel();
staticAdapter.visitTryCatchBlock(beginPopulate, endPopulate, catchHandler, THROWABLE_INAME);
staticAdapter.mark(beginPopulate);
staticAdapter.push(m.declaringClass);
// push the method name string arg onto the stack
staticAdapter.push(m.method.getName());
// 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);
staticAdapter.push(t);
staticAdapter.arrayStore(CLASS_TYPE);
index++;
}
// invoke the getMethod
staticAdapter.invokeVirtual(CLASS_TYPE, new Method("getDeclaredMethod", METHOD_TYPE, new Type[] { STRING_TYPE, CLASS_ARRAY_TYPE }));
// store the reflected method in the static field
staticAdapter.putStatic(typeBeingWoven, methodStaticFieldName, METHOD_TYPE);
Label afterCatch = staticAdapter.newLabel();
staticAdapter.mark(endPopulate);
staticAdapter.goTo(afterCatch);
staticAdapter.mark(catchHandler);
// We don't care about the exception, so pop it off
staticAdapter.pop();
// store the reflected method in the static field
staticAdapter.visitInsn(ACONST_NULL);
staticAdapter.putStatic(typeBeingWoven, methodStaticFieldName, METHOD_TYPE);
staticAdapter.mark(afterCatch);
}
staticAdapter.returnValue();
staticAdapter.endMethod();
}
Aggregations