Create newSVpv_hek to reduce code duplication where HEKs need to be
Nicholas Clark [Fri, 3 Jun 2005 09:37:21 +0000 (09:37 +0000)]
turned into SVs

p4raw-id: //depot/perl@24692

embed.fnc
embed.h
global.sym
hv.c
sv.c

index 5c6c8e8..edffcf8 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -533,6 +533,7 @@ Apda        |SV*    |newSVuv        |UV u
 Apda   |SV*    |newSVnv        |NV n
 Apda   |SV*    |newSVpv        |const char* s|STRLEN len
 Apda   |SV*    |newSVpvn       |const char* s|STRLEN len
+Apda   |SV*    |newSVpv_hek    |const HEK *hek
 Apda   |SV*    |newSVpvn_share |const char* s|I32 len|U32 hash
 Afpda  |SV*    |newSVpvf       |const char* pat|...
 Ap     |SV*    |vnewSVpvf      |const char* pat|va_list* args
diff --git a/embed.h b/embed.h
index 53e90b5..15cbbb6 100644 (file)
--- a/embed.h
+++ b/embed.h
 #define newSVnv                        Perl_newSVnv
 #define newSVpv                        Perl_newSVpv
 #define newSVpvn               Perl_newSVpvn
+#define newSVpv_hek            Perl_newSVpv_hek
 #define newSVpvn_share         Perl_newSVpvn_share
 #define newSVpvf               Perl_newSVpvf
 #define vnewSVpvf              Perl_vnewSVpvf
 #define newSVnv(a)             Perl_newSVnv(aTHX_ a)
 #define newSVpv(a,b)           Perl_newSVpv(aTHX_ a,b)
 #define newSVpvn(a,b)          Perl_newSVpvn(aTHX_ a,b)
+#define newSVpv_hek(a)         Perl_newSVpv_hek(aTHX_ a)
 #define newSVpvn_share(a,b,c)  Perl_newSVpvn_share(aTHX_ a,b,c)
 #define vnewSVpvf(a,b)         Perl_vnewSVpvf(aTHX_ a,b)
 #define newSVrv(a,b)           Perl_newSVrv(aTHX_ a,b)
index f8c26bb..8a1e9ca 100644 (file)
@@ -315,6 +315,7 @@ Perl_newSVuv
 Perl_newSVnv
 Perl_newSVpv
 Perl_newSVpvn
+Perl_newSVpv_hek
 Perl_newSVpvn_share
 Perl_newSVpvf
 Perl_vnewSVpvf
diff --git a/hv.c b/hv.c
index 68ef67e..1562976 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -2059,39 +2059,7 @@ see C<hv_iterinit>.
 SV *
 Perl_hv_iterkeysv(pTHX_ register HE *entry)
 {
-    if (HeKLEN(entry) != HEf_SVKEY) {
-        HEK *hek = HeKEY_hek(entry);
-        const int flags = HEK_FLAGS(hek);
-        SV *sv;
-
-        if (flags & HVhek_WASUTF8) {
-            /* Trouble :-)
-               Andreas would like keys he put in as utf8 to come back as utf8
-            */
-            STRLEN utf8_len = HEK_LEN(hek);
-            U8 *as_utf8 = bytes_to_utf8 ((U8*)HEK_KEY(hek), &utf8_len);
-
-            sv = newSVpvn ((char*)as_utf8, utf8_len);
-            SvUTF8_on (sv);
-           Safefree (as_utf8); /* bytes_to_utf8() allocates a new string */
-       } else if (flags & HVhek_REHASH) {
-           /* We don't have a pointer to the hv, so we have to replicate the
-              flag into every HEK. This hv is using custom a hasing
-              algorithm. Hence we can't return a shared string scalar, as
-              that would contain the (wrong) hash value, and might get passed
-              into an hv routine with a regular hash  */
-
-            sv = newSVpvn (HEK_KEY(hek), HEK_LEN(hek));
-           if (HEK_UTF8(hek))
-               SvUTF8_on (sv);
-       } else {
-            sv = newSVpvn_share(HEK_KEY(hek),
-                                (HEK_UTF8(hek) ? -HEK_LEN(hek) : HEK_LEN(hek)),
-                                HEK_HASH(hek));
-        }
-        return sv_2mortal(sv);
-    }
-    return sv_mortalcopy(HeKEY_sv(entry));
+    return sv_2mortal(newSVpv_hek(HeKEY_hek(entry)));
 }
 
 /*
diff --git a/sv.c b/sv.c
index aa07053..69a8908 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -7601,6 +7601,53 @@ Perl_newSVpvn(pTHX_ const char *s, STRLEN len)
     return sv;
 }
 
+
+/*
+=for apidoc newSVpv_hek
+
+Creates a new SV from the hash key structure.  It will generate scalars that
+point to the shared string table where possible.
+
+=cut
+*/
+
+SV *
+Perl_newSVpv_hek(pTHX_ const HEK *hek)
+{
+    if (HEK_LEN(hek) == HEf_SVKEY) {
+       return newSVsv(*(SV**)HEK_KEY(hek));
+    } else {
+       const int flags = HEK_FLAGS(hek);
+       if (flags & HVhek_WASUTF8) {
+           /* Trouble :-)
+              Andreas would like keys he put in as utf8 to come back as utf8
+           */
+           STRLEN utf8_len = HEK_LEN(hek);
+           U8 *as_utf8 = bytes_to_utf8 ((U8*)HEK_KEY(hek), &utf8_len);
+           SV *sv = newSVpvn ((char*)as_utf8, utf8_len);
+
+           SvUTF8_on (sv);
+           Safefree (as_utf8); /* bytes_to_utf8() allocates a new string */
+           return sv;
+       } else if (flags & HVhek_REHASH) {
+           /* We don't have a pointer to the hv, so we have to replicate the
+              flag into every HEK. This hv is using custom a hasing
+              algorithm. Hence we can't return a shared string scalar, as
+              that would contain the (wrong) hash value, and might get passed
+              into an hv routine with a regular hash  */
+
+           SV *sv = newSVpvn (HEK_KEY(hek), HEK_LEN(hek));
+           if (HEK_UTF8(hek))
+               SvUTF8_on (sv);
+           return sv;
+       }
+       /* This will be overwhelminly the most common case.  */
+       return newSVpvn_share(HEK_KEY(hek),
+                             (HEK_UTF8(hek) ? -HEK_LEN(hek) : HEK_LEN(hek)),
+                             HEK_HASH(hek));
+    }
+}
+
 /*
 =for apidoc newSVpvn_share