Type.getMethodDescriptor( Type.BOOLEAN_TYPE,
new Type[]{Type.getType( Object.class )} ),
null,
null );
mv.visitCode();
final Label l0 = new Label();
mv.visitLabel( l0 );
// if ( this == object || this.delegate == object || this.delegate.equals( object ) ) {
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
final Label l1 = new Label();
mv.visitJumpInsn( Opcodes.IF_ACMPEQ,
l1 );
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
className,
DELEGATE_FIELD_NAME,
Type.getDescriptor( clazz ) );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
mv.visitJumpInsn( Opcodes.IF_ACMPEQ,
l1 );
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn( Opcodes.GETFIELD,
className,
DELEGATE_FIELD_NAME,
Type.getDescriptor( clazz ) );
mv.visitVarInsn(Opcodes.ALOAD, 1);
if ( clazz.isInterface() ) {
mv.visitMethodInsn( Opcodes.INVOKEINTERFACE,
Type.getInternalName( clazz ),
"equals",
Type.getMethodDescriptor( Type.BOOLEAN_TYPE,
new Type[]{Type.getType( Object.class )} ) );
} else {
mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
Type.getInternalName( clazz ),
"equals",
Type.getMethodDescriptor( Type.BOOLEAN_TYPE,
new Type[]{Type.getType( Object.class )} ) );
}
Label l2 = new Label();
mv.visitJumpInsn(Opcodes.IFEQ, l2);
// return true;
mv.visitLabel( l1 );
mv.visitInsn( Opcodes.ICONST_1 );
mv.visitInsn( Opcodes.IRETURN );
mv.visitLabel( l2 );
// if (( object == null ) || ( ! ( object instanceof <class> ) ) )
mv.visitVarInsn( Opcodes.ALOAD,
1 );
final Label l3 = new Label();
mv.visitJumpInsn( Opcodes.IFNULL,
l3 );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
mv.visitTypeInsn( Opcodes.INSTANCEOF,
Type.getInternalName( clazz ) );
final Label l4 = new Label();
mv.visitJumpInsn( Opcodes.IFNE,
l4 );
// return false;
mv.visitLabel( l3 );
mv.visitInsn( Opcodes.ICONST_0 );
mv.visitInsn( Opcodes.IRETURN );
mv.visitLabel( l4 );
// if( object instanceof ShadowProxy &&
// ( this.delegate == ((ShadowProxy)object).delegate ||
// this.delegate.equals( ((ShadowProxy)object).delegate ) ) ) {
Label c0 = new Label();
mv.visitLabel( c0 );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
mv.visitTypeInsn( Opcodes.INSTANCEOF,
className );
Label c1 = new Label();
mv.visitJumpInsn( Opcodes.IFEQ,
c1 );
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
className,
DELEGATE_FIELD_NAME,
Type.getDescriptor( clazz ) );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
mv.visitTypeInsn( Opcodes.CHECKCAST,
className );
mv.visitFieldInsn( Opcodes.GETFIELD,
className,
DELEGATE_FIELD_NAME,
Type.getDescriptor( clazz ) );
Label c2 = new Label();
mv.visitJumpInsn( Opcodes.IF_ACMPEQ,
c2 );
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
className,
DELEGATE_FIELD_NAME,
Type.getDescriptor( clazz ) );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
mv.visitTypeInsn( Opcodes.CHECKCAST,
className );
mv.visitFieldInsn( Opcodes.GETFIELD,
className,
DELEGATE_FIELD_NAME,
Type.getDescriptor( clazz ) );
if ( clazz.isInterface() ) {
mv.visitMethodInsn( Opcodes.INVOKEINTERFACE,
Type.getInternalName( clazz ),
"equals",
Type.getMethodDescriptor( Type.BOOLEAN_TYPE,
new Type[]{Type.getType( Object.class )} ) );
} else {
mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
Type.getInternalName( clazz ),
"equals",
Type.getMethodDescriptor( Type.BOOLEAN_TYPE,
new Type[]{Type.getType( Object.class )} ) );
}
mv.visitJumpInsn( Opcodes.IFEQ,
c1 );
mv.visitLabel( c2 );
// return true;
mv.visitInsn( Opcodes.ICONST_1 );
mv.visitInsn( Opcodes.IRETURN );
// }
mv.visitLabel( c1 );
// return false;
mv.visitInsn( Opcodes.ICONST_0 );
mv.visitInsn( Opcodes.IRETURN );
final Label lastLabel = new Label();
mv.visitLabel( lastLabel );
mv.visitLocalVariable( "this",
"L" + className + ";",
null,