*/
protected static void buildHashCode(final ClassWriter cw,
final String className,
final Class clazz,
final Map fieldTypes) {
MethodVisitor mv;
// Building hashcode method
{
mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
"hashCode",
Type.getMethodDescriptor( Type.INT_TYPE,
new Type[]{} ),
null,
null );
mv.visitCode();
// if( this.__hashCache == 0 ) {
Label l0 = new Label();
mv.visitLabel( l0 );
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
className,
HASHCACHE_FIELD_NAME,
Type.INT_TYPE.getDescriptor() );
Label l1 = new Label();
mv.visitJumpInsn( Opcodes.IFNE,
l1 );
Label l2 = new Label();
// this.__hashCache = this.delegate.hashCode();
mv.visitLabel( l2 );
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
className,
DELEGATE_FIELD_NAME,
Type.getDescriptor( clazz ) );
if ( clazz.isInterface() ) {
mv.visitMethodInsn( Opcodes.INVOKEINTERFACE,
Type.getInternalName( clazz ),
"hashCode",
Type.getMethodDescriptor( Type.INT_TYPE,
new Type[0] ) );
} else {
mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
Type.getInternalName( clazz ),
"hashCode",
Type.getMethodDescriptor( Type.INT_TYPE,
new Type[0] ) );
}
mv.visitFieldInsn( Opcodes.PUTFIELD,
className,
HASHCACHE_FIELD_NAME,
Type.INT_TYPE.getDescriptor() );
// }
mv.visitLabel( l1 );
// return this.__hashCache;
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
className,
HASHCACHE_FIELD_NAME,
Type.INT_TYPE.getDescriptor() );
mv.visitInsn( Opcodes.IRETURN );
Label l3 = new Label();
mv.visitLabel( l3 );
mv.visitLocalVariable( "this",
"L" + className + ";",
null,
l0,
l3,
0 );
mv.visitMaxs( 0,
0 );
mv.visitEnd();
}
}