/* * call-seq: * obj.hash => fixnum * * Generates a <code>Fixnum</code> hash value for this object. This * function must have the property that <code>a.eql?(b)</code> implies * <code>a.hash == b.hash</code>. The hash value is used by class * <code>Hash</code>. Any hash value that exceeds the capacity of a * <code>Fixnum</code> will be truncated before being used. */ VALUE rb_obj_id(VALUE obj) { /* * 32-bit VALUE space * MSB ------------------------ LSB * false 00000000000000000000000000000000 * true 00000000000000000000000000000010 * nil 00000000000000000000000000000100 * undef 00000000000000000000000000000110 * symbol ssssssssssssssssssssssss00001110 * object oooooooooooooooooooooooooooooo00 = 0 (mod sizeof(RVALUE)) * fixnum fffffffffffffffffffffffffffffff1 * * object_id space * LSB * false 00000000000000000000000000000000 * true 00000000000000000000000000000010 * nil 00000000000000000000000000000100 * undef 00000000000000000000000000000110 * symbol 000SSSSSSSSSSSSSSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4) * object oooooooooooooooooooooooooooooo0 o...o % A = 0 * fixnum fffffffffffffffffffffffffffffff1 bignum if required * * where A = sizeof(RVALUE)/4 * * sizeof(RVALUE) is * 20 if 32-bit, double is 4-byte aligned * 24 if 32-bit, double is 8-byte aligned * 40 if 64-bit */ if (TYPE(obj) == T_SYMBOL) { return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG; } if (SPECIAL_CONST_P(obj)) { return LONG2NUM((long)obj); } return (VALUE)((long)obj|FIXNUM_FLAG); }