e.push(PRIMES[(int)(seed % PRIMES.length)]); e.push(PRIMES[(int)((seed * 13) % PRIMES.length)]);
int hc = (constant != 0) ? constant : PRIMES[(int)(seed % PRIMES.length)]; int hm = (multiplier != 0) ? multiplier : PRIMES[(int)((seed * 13) % PRIMES.length)]; e.push(hc);
        public void generateClass(ClassVisitor v) {            ClassEmitter ce = new ClassEmitter(v);                        Method newInstance = ReflectUtils.findNewInstance(keyInterface);            if (!newInstance.getReturnType().equals(Object.class)) {                throw new IllegalArgumentException("newInstance method must return Object");            }            Type[] parameterTypes = TypeUtils.getTypes(newInstance.getParameterTypes());            ce.begin_class(Constants.ACC_PUBLIC,                           getClassName(),                           KEY_FACTORY,                           new Type[]{ Type.getType(keyInterface) },                           Constants.SOURCE_FILE);            ComplexOps.null_constructor(ce);            ComplexOps.factory_method(ce, ReflectUtils.getSignature(newInstance));            // TODO: change to exactly follow Effective Java recommendations            // constructor            int seed = 0;            CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC,                                            TypeUtils.parseConstructor(parameterTypes),                                            null);            e.load_this();            e.super_invoke_constructor();            e.load_this();            for (int i = 0; i < parameterTypes.length; i++) {                seed += parameterTypes[i].hashCode();                ce.declare_field(Constants.ACC_PRIVATE | Constants.ACC_FINAL,                                 getFieldName(i),                                 parameterTypes[i],                                 null);                e.dup();                e.load_arg(i);                e.putfield(getFieldName(i));            }            e.return_value();            e.end_method();                        // hash code            e = ce.begin_method(Constants.ACC_PUBLIC, HASH_CODE, null);            e.push(PRIMES[(int)(seed % PRIMES.length)]);            e.push(PRIMES[(int)((seed * 13) % PRIMES.length)]);            for (int i = 0; i < parameterTypes.length; i++) {                e.load_this();                e.getfield(getFieldName(i));                ComplexOps.hash_code(e, parameterTypes[i], customizer);            }            e.swap();            e.pop();            e.return_value();            e.end_method();            // equals            e = ce.begin_method(Constants.ACC_PUBLIC, EQUALS, null);            Label fail = e.make_label();            e.load_arg(0);            e.instance_of_this();            e.if_jump(e.EQ, fail);            for (int i = 0; i < parameterTypes.length; i++) {                e.load_this();                e.getfield(getFieldName(i));                e.load_arg(0);                e.checkcast_this();                e.getfield(getFieldName(i));                ComplexOps.not_equals(e, parameterTypes[i], fail, customizer);            }            e.push(1);            e.return_value();            e.mark(fail);            e.push(0);            e.return_value();            e.end_method();            // toString            e = ce.begin_method(Constants.ACC_PUBLIC, TO_STRING, null);            e.new_instance(Constants.TYPE_STRING_BUFFER);            e.dup();            e.invoke_constructor(Constants.TYPE_STRING_BUFFER);            for (int i = 0; i < parameterTypes.length; i++) {                e.load_this();                e.getfield(getFieldName(i));                ComplexOps.append_string(e, parameterTypes[i], ComplexOps.DEFAULT_DELIMITERS, customizer);            }            e.invoke_virtual(Constants.TYPE_STRING_BUFFER, TO_STRING);            e.return_value();            e.end_method();            ce.end_class();        }