use of org.objectweb.asm.Type in project groovy by apache.
the class ProxyGeneratorAdapter method visitMethod.
@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
Object key = Arrays.asList(name, desc);
if (visitedMethods.contains(key))
return null;
if (Modifier.isPrivate(access) || Modifier.isNative(access) || ((access & ACC_SYNTHETIC) != 0)) {
// do not generate bytecode for private methods
return null;
}
int accessFlags = access;
visitedMethods.add(key);
if ((objectDelegateMethods.contains(name + desc) || delegatedClosures.containsKey(name) || (!"<init>".equals(name) && hasWildcard)) && !Modifier.isStatic(access) && !Modifier.isFinal(access)) {
if (!GROOVYOBJECT_METHOD_NAMESS.contains(name)) {
if (Modifier.isAbstract(access)) {
// prevents the proxy from being abstract
accessFlags -= ACC_ABSTRACT;
}
if (delegatedClosures.containsKey(name) || (!"<init>".equals(name) && hasWildcard)) {
delegatedClosures.put(name, Boolean.TRUE);
return makeDelegateToClosureCall(name, desc, signature, exceptions, accessFlags);
}
if (generateDelegateField && objectDelegateMethods.contains(name + desc)) {
return makeDelegateCall(name, desc, signature, exceptions, accessFlags);
}
delegatedClosures.put(name, Boolean.TRUE);
return makeDelegateToClosureCall(name, desc, signature, exceptions, accessFlags);
}
} else if ("getProxyTarget".equals(name) && "()Ljava/lang/Object;".equals(desc)) {
return createGetProxyTargetMethod(access, name, desc, signature, exceptions);
} else if ("<init>".equals(name) && (Modifier.isPublic(access) || Modifier.isProtected(access))) {
return createConstructor(access, name, desc, signature, exceptions);
} else if (Modifier.isAbstract(access) && !GROOVYOBJECT_METHOD_NAMESS.contains(name)) {
if (isImplemented(superClass, name, desc)) {
return null;
}
accessFlags -= ACC_ABSTRACT;
MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions);
mv.visitCode();
Type[] args = Type.getArgumentTypes(desc);
if (emptyBody) {
Type returnType = Type.getReturnType(desc);
if (returnType == Type.VOID_TYPE) {
mv.visitInsn(RETURN);
} else {
int loadIns = getLoadInsn(returnType);
switch(loadIns) {
case ILOAD:
mv.visitInsn(ICONST_0);
break;
case LLOAD:
mv.visitInsn(LCONST_0);
break;
case FLOAD:
mv.visitInsn(FCONST_0);
break;
case DLOAD:
mv.visitInsn(DCONST_0);
break;
default:
mv.visitInsn(ACONST_NULL);
}
mv.visitInsn(getReturnInsn(returnType));
mv.visitMaxs(2, registerLen(args) + 1);
}
} else {
// for compatibility with the legacy proxy generator, we should throw an UnsupportedOperationException
// instead of an AbtractMethodException
mv.visitTypeInsn(NEW, "java/lang/UnsupportedOperationException");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/UnsupportedOperationException", "<init>", "()V", false);
mv.visitInsn(ATHROW);
mv.visitMaxs(2, registerLen(args) + 1);
}
mv.visitEnd();
}
return null;
}
use of org.objectweb.asm.Type in project groovy by apache.
the class ProxyGeneratorAdapter method makeDelegateToClosureCall.
protected MethodVisitor makeDelegateToClosureCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags) {
MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions);
// TraceMethodVisitor tmv = new TraceMethodVisitor(mv);
// mv = tmv;
mv.visitCode();
int stackSize = 0;
// method body should be:
// this.$delegate$closure$methodName.call(new Object[] { method arguments })
Type[] args = Type.getArgumentTypes(desc);
int arrayStore = args.length + 1;
BytecodeHelper.pushConstant(mv, args.length);
// stack size = 1
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
stackSize = 1;
int idx = 1;
for (int i = 0; i < args.length; i++) {
Type arg = args[i];
// stack size = 2
mv.visitInsn(DUP);
// array index, stack size = 3
BytecodeHelper.pushConstant(mv, i);
stackSize = 3;
// primitive types must be boxed
if (isPrimitive(arg)) {
mv.visitIntInsn(getLoadInsn(arg), idx);
String wrappedType = getWrappedClassDescriptor(arg);
mv.visitMethodInsn(INVOKESTATIC, wrappedType, "valueOf", "(" + arg.getDescriptor() + ")L" + wrappedType + ";", false);
} else {
// load argument i
mv.visitVarInsn(ALOAD, idx);
}
idx += registerLen(arg);
stackSize = Math.max(4, 3 + registerLen(arg));
// store value into array
mv.visitInsn(AASTORE);
}
// store array
mv.visitVarInsn(ASTORE, arrayStore);
int arrayIndex = arrayStore;
// load this
mv.visitVarInsn(ALOAD, 0);
// load closure map
mv.visitFieldInsn(GETFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;");
// load method name
mv.visitLdcInsn(name);
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
arrayStore++;
mv.visitVarInsn(ASTORE, arrayStore);
// if null, test if wildcard exists
Label notNull = new Label();
mv.visitIntInsn(ALOAD, arrayStore);
mv.visitJumpInsn(IFNONNULL, notNull);
// load this
mv.visitVarInsn(ALOAD, 0);
// load closure map
mv.visitFieldInsn(GETFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;");
// load wildcard
mv.visitLdcInsn("*");
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitVarInsn(ASTORE, arrayStore);
mv.visitLabel(notNull);
mv.visitVarInsn(ALOAD, arrayStore);
mv.visitMethodInsn(INVOKESTATIC, BytecodeHelper.getClassInternalName(this.getClass()), "ensureClosure", "(Ljava/lang/Object;)Lgroovy/lang/Closure;", false);
// load argument array
mv.visitVarInsn(ALOAD, arrayIndex);
stackSize++;
// call closure
mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Closure", "call", "([Ljava/lang/Object;)Ljava/lang/Object;", false);
unwrapResult(mv, desc);
mv.visitMaxs(stackSize, arrayStore + 1);
mv.visitEnd();
// System.out.println("tmv.getText() = " + tmv.getText());
return null;
}
use of org.objectweb.asm.Type in project groovy by apache.
the class ProxyGeneratorAdapter method makeDelegateCall.
/**
* Generate a call to the delegate object.
*/
protected MethodVisitor makeDelegateCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags) {
MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions);
// load this
mv.visitVarInsn(ALOAD, 0);
// load delegate
mv.visitFieldInsn(GETFIELD, proxyName, DELEGATE_OBJECT_FIELD, BytecodeHelper.getTypeDescription(delegateClass));
// using InvokerHelper to allow potential intercepted calls
int size;
// method name
mv.visitLdcInsn(name);
Type[] args = Type.getArgumentTypes(desc);
BytecodeHelper.pushConstant(mv, args.length);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
size = 6;
int idx = 1;
for (int i = 0; i < args.length; i++) {
Type arg = args[i];
mv.visitInsn(DUP);
BytecodeHelper.pushConstant(mv, i);
// primitive types must be boxed
if (isPrimitive(arg)) {
mv.visitIntInsn(getLoadInsn(arg), idx);
String wrappedType = getWrappedClassDescriptor(arg);
mv.visitMethodInsn(INVOKESTATIC, wrappedType, "valueOf", "(" + arg.getDescriptor() + ")L" + wrappedType + ";", false);
} else {
// load argument i
mv.visitVarInsn(ALOAD, idx);
}
size = Math.max(size, 5 + registerLen(arg));
idx += registerLen(arg);
// store value into array
mv.visitInsn(AASTORE);
}
mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/InvokerHelper", "invokeMethod", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", false);
unwrapResult(mv, desc);
mv.visitMaxs(size, registerLen(args) + 1);
return mv;
}
use of org.objectweb.asm.Type in project cglib by cglib.
the class EmitUtils method process_arrays.
/**
* Process two arrays on the stack in parallel. Assumes the top two items on the stack
* are arrays of the specified class. The arrays must be the same length. For each pair
* of elements in the arrays, puts the pair on the stack and triggers the callback.
* @param type the type of the arrays (type.isArray() must be true)
* @param callback the callback triggered for each pair of elements
*/
public static void process_arrays(CodeEmitter e, Type type, ProcessArrayCallback callback) {
Type componentType = TypeUtils.getComponentType(type);
Local array1 = e.make_local();
Local array2 = e.make_local();
Local loopvar = e.make_local(Type.INT_TYPE);
Label loopbody = e.make_label();
Label checkloop = e.make_label();
e.store_local(array1);
e.store_local(array2);
e.push(0);
e.store_local(loopvar);
e.goTo(checkloop);
e.mark(loopbody);
e.load_local(array1);
e.load_local(loopvar);
e.array_load(componentType);
e.load_local(array2);
e.load_local(loopvar);
e.array_load(componentType);
callback.processElement(componentType);
e.iinc(loopvar, 1);
e.mark(checkloop);
e.load_local(loopvar);
e.load_local(array1);
e.arraylength();
e.if_icmp(e.LT, loopbody);
}
use of org.objectweb.asm.Type in project cglib by cglib.
the class ReflectUtils method getClassInfo.
public static ClassInfo getClassInfo(final Class clazz) {
final Type type = Type.getType(clazz);
final Type sc = (clazz.getSuperclass() == null) ? null : Type.getType(clazz.getSuperclass());
return new ClassInfo() {
public Type getType() {
return type;
}
public Type getSuperType() {
return sc;
}
public Type[] getInterfaces() {
return TypeUtils.getTypes(clazz.getInterfaces());
}
public int getModifiers() {
return clazz.getModifiers();
}
};
}
Aggregations