value = &PL_sv_placeholder;
break;
case HVrhek_IV:
- value = (he->refcounted_he_data[0] & HVrhek_UV)
- ? newSVuv(he->refcounted_he_val.refcounted_he_u_iv)
- : newSViv(he->refcounted_he_val.refcounted_he_u_uv);
+ value = newSViv(he->refcounted_he_val.refcounted_he_u_iv);
+ break;
+ case HVrhek_UV:
+ value = newSVuv(he->refcounted_he_val.refcounted_he_u_uv);
break;
case HVrhek_PV:
+ case HVrhek_PV_UTF8:
/* Create a string SV that directly points to the bytes in our
structure. */
value = newSV_type(SVt_PV);
SvLEN_set(value, 0);
SvPOK_on(value);
SvREADONLY_on(value);
- if (he->refcounted_he_data[0] & HVrhek_UTF8)
+ if ((he->refcounted_he_data[0] & HVrhek_typemask) == HVrhek_PV_UTF8)
SvUTF8_on(value);
break;
default:
return value;
}
-#ifdef USE_ITHREADS
-/* A big expression to find the key offset */
-#define REF_HE_KEY(chain) \
- ((((chain->refcounted_he_data[0] & HVrhek_typemask) == HVrhek_PV) \
- ? chain->refcounted_he_val.refcounted_he_u_len + 1 : 0) \
- + 1 + chain->refcounted_he_data)
-#endif
-
/*
=for apidoc refcounted_he_chain_2hv
value_len = 0;
key_offset = 1;
}
- flags = value_type;
#ifdef USE_ITHREADS
he = (struct refcounted_he*)
if (value_type == HVrhek_PV) {
Copy(value_p, he->refcounted_he_data + 1, value_len + 1, char);
he->refcounted_he_val.refcounted_he_u_len = value_len;
- if (SvUTF8(value)) {
- flags |= HVrhek_UTF8;
- }
+ /* Do it this way so that the SvUTF8() test is after the SvPV, in case
+ the value is overloaded, and doesn't yet have the UTF-8flag set. */
+ if (SvUTF8(value))
+ value_type = HVrhek_PV_UTF8;
} else if (value_type == HVrhek_IV) {
if (SvUOK(value)) {
he->refcounted_he_val.refcounted_he_u_uv = SvUVX(value);
- flags |= HVrhek_UV;
+ value_type = HVrhek_UV;
} else {
he->refcounted_he_val.refcounted_he_u_iv = SvIVX(value);
}
}
+ flags = value_type;
if (is_utf8) {
/* Hash keys are always stored normalised to (yes) ISO-8859-1.
between threads (because it hangs from OPs, which are shared), hence the
alternate definition and mutex. */
+struct refcounted_he;
+
#ifdef PERL_CORE
/* Gosh. This really isn't a good name any longer. */
IV refcounted_he_u_iv;
UV refcounted_he_u_uv;
STRLEN refcounted_he_u_len;
+ void *refcounted_he_u_ptr; /* Might be useful in future */
} refcounted_he_val;
/* First byte is flags. Then NUL-terminated value. Then for ithreads,
non-NUL terminated key. */
/* Flag bits are HVhek_UTF8, HVhek_WASUTF8, then */
#define HVrhek_undef 0x00 /* Value is undef. */
-#define HVrhek_PV 0x10 /* Value is a string. */
-#define HVrhek_IV 0x20 /* Value is IV/UV. */
-#define HVrhek_delete 0x30 /* Value is placeholder - signifies delete. */
-#define HVrhek_typemask 0x30
-#define HVrhek_UTF8 0x40 /* string value is utf8. */
-#define HVrhek_UV 0x40 /* integer value is UV. */
+#define HVrhek_delete 0x10 /* Value is placeholder - signifies delete. */
+#define HVrhek_IV 0x20 /* Value is IV. */
+#define HVrhek_UV 0x30 /* Value is UV. */
+#define HVrhek_PV 0x40 /* Value is a (byte) string. */
+#define HVrhek_PV_UTF8 0x50 /* Value is a (utf8) string. */
+/* Two spare. As these have to live in the optree, you can't store anything
+ interpreter specific, such as SVs. :-( */
+#define HVrhek_typemask 0x70
+
+#ifdef USE_ITHREADS
+/* A big expression to find the key offset */
+#define REF_HE_KEY(chain) \
+ ((((chain->refcounted_he_data[0] & 0x60) == 0x40) \
+ ? chain->refcounted_he_val.refcounted_he_u_len + 1 : 0) \
+ + 1 + chain->refcounted_he_data)
+#endif
# ifdef USE_ITHREADS
# define HINTS_REFCNT_LOCK MUTEX_LOCK(&PL_hints_mutex)