@@ -6529,6 +6529,20 @@ PP(pp_unshift)
6529
6529
return NORMAL ;
6530
6530
}
6531
6531
6532
+ #ifdef _MSC_VER
6533
+ # pragma intrinsic(_byteswap_ushort, _byteswap_ulong, _byteswap_uint64)
6534
+ # define S_bswap16 (_x ) _byteswap_ushort(_x)
6535
+ # define S_bswap32 (_x ) _byteswap_ulong(_x)
6536
+ # define S_bswap64 (_x ) _byteswap_uint64(_x)
6537
+ PERL_STATIC_FORCE_INLINE void *
6538
+ S_memcpy (void * dest , const void * src ,size_t count );
6539
+ #else
6540
+ # define S_bswap16 (_x ) _swab_16_(_x)
6541
+ # define S_bswap32 (_x ) _swab_32_(_x)
6542
+ # define S_bswap64 (_x ) _swab_64_(_x)
6543
+ # define S_memcpy (_d ,_s ,_n ) memcpy((_d),(_s),(_n))
6544
+ #endif
6545
+
6532
6546
PP_wrapped (pp_reverse , 0 , 1 )
6533
6547
{
6534
6548
dSP ; dMARK ;
@@ -6554,15 +6568,17 @@ PP_wrapped(pp_reverse, 0, 1)
6554
6568
SV * begin , * end ;
6555
6569
6556
6570
if (can_preserve ) {
6557
- if (!av_exists (av , i )) {
6558
- if (av_exists (av , j )) {
6571
+ bool exi = av_exists (av , i );
6572
+ bool exj = av_exists (av , j );
6573
+ if (!exi ) {
6574
+ if (exj ) {
6559
6575
SV * sv = av_delete (av , j , 0 );
6560
6576
begin = * av_fetch (av , i , TRUE);
6561
6577
sv_setsv_mg (begin , sv );
6562
6578
}
6563
6579
continue ;
6564
6580
}
6565
- else if (!av_exists ( av , j ) ) {
6581
+ else if (!exj ) {
6566
6582
SV * sv = av_delete (av , i , 0 );
6567
6583
end = * av_fetch (av , j , TRUE);
6568
6584
sv_setsv_mg (end , sv );
@@ -6643,18 +6659,19 @@ PP_wrapped(pp_reverse, 0, 1)
6643
6659
* in a single pass, rather than 2-3 passes. */
6644
6660
6645
6661
const char * src = SvPV_const (src_sv , len );
6662
+ U8 * dd ;
6646
6663
6647
6664
/* Prepare the TARG. */
6648
- if (SvTYPE (TARG ) < SVt_PV ) {
6665
+ if (SvTHINKFIRST (TARG ))
6666
+ SV_CHECK_THINKFIRST_COW_DROP (TARG ); /* Drops any buffer or RV */
6667
+ if (SvTYPE (TARG ) < SVt_PV )
6649
6668
SvUPGRADE (TARG , SvTYPE (src_sv )); /* No buffer allocation here */
6650
- } else if (SvTHINKFIRST (TARG )) {
6651
- SV_CHECK_THINKFIRST_COW_DROP (TARG ); /* Drops any buffer */
6652
- }
6653
- SvSETMAGIC (TARG );
6654
- SvGROW (TARG , len + 1 );
6669
+ else /* can't have SMG if < PVMG, SvROK/SvAMAGIC doesn't apply */
6670
+ SvSETMAGIC (TARG );
6671
+ dd = (U8 * )SvGROW (TARG , len + 1 );
6655
6672
SvCUR_set (TARG , len );
6656
6673
SvPOK_only (TARG );
6657
- * SvEND ( TARG ) = '\0' ;
6674
+ dd [ len ] = '\0' ;
6658
6675
if (SvTAINTED (src_sv ))
6659
6676
SvTAINT (TARG );
6660
6677
@@ -6663,9 +6680,9 @@ PP_wrapped(pp_reverse, 0, 1)
6663
6680
SvUTF8_on (TARG );
6664
6681
6665
6682
const U8 * s = (const U8 * )src ;
6666
- U8 * dd = (U8 * )(SvPVX (TARG ) + len );
6667
6683
const U8 * send = (const U8 * )(s + len );
6668
6684
int bytes = 0 ;
6685
+ dd = dd + len ;
6669
6686
while (s < send ) {
6670
6687
bytes = UTF8SKIP (s );
6671
6688
if (bytes == 1 ) {
@@ -6680,57 +6697,57 @@ PP_wrapped(pp_reverse, 0, 1)
6680
6697
} else {
6681
6698
STRLEN i = 0 ;
6682
6699
STRLEN j = len ;
6683
- uint32_t u32_1 , u32_2 ;
6684
- uint16_t u16_1 , u16_2 ;
6685
- char * outp = SvPVX ( TARG ) ;
6700
+ U32 u32_1 , u32_2 ;
6701
+ U16 u16_1 , u16_2 ;
6702
+ char * outp = dd ;
6686
6703
/* Take a chunk of bytes from the front and from the
6687
6704
* back, reverse the bytes in each and and swap the
6688
6705
* chunks over. This should have generally good
6689
6706
* performance but also is likely to be optimised
6690
6707
* into bswap instructions by the compiler.
6691
6708
*/
6692
6709
#ifdef HAS_QUAD
6693
- uint64_t u64_1 , u64_2 ;
6710
+ U64 u64_1 , u64_2 ;
6694
6711
while (j - i >= 16 ) {
6695
- memcpy (& u64_1 , src + j - 8 , 8 );
6696
- memcpy (& u64_2 , src + i , 8 );
6697
- u64_1 = _swab_64_ (u64_1 );
6698
- u64_2 = _swab_64_ (u64_2 );
6699
- memcpy (outp + j - 8 , & u64_2 , 8 );
6700
- memcpy (outp + i , & u64_1 , 8 );
6712
+ S_memcpy (& u64_1 , src + j - 8 , 8 );
6713
+ S_memcpy (& u64_2 , src + i , 8 );
6714
+ u64_1 = S_bswap64 (u64_1 );
6715
+ u64_2 = S_bswap64 (u64_2 );
6716
+ S_memcpy (outp + j - 8 , & u64_2 , 8 );
6717
+ S_memcpy (outp + i , & u64_1 , 8 );
6701
6718
i += 8 ;
6702
6719
j -= 8 ;
6703
6720
}
6704
6721
6705
6722
if (j - i >= 8 ) {
6706
- memcpy (& u32_1 , src + j - 4 , 4 );
6707
- memcpy (& u32_2 , src + i , 4 );
6708
- u32_1 = _swab_32_ (u32_1 );
6709
- u32_2 = _swab_32_ (u32_2 );
6710
- memcpy (outp + j - 4 , & u32_2 , 4 );
6711
- memcpy (outp + i , & u32_1 , 4 );
6723
+ S_memcpy (& u32_1 , src + j - 4 , 4 );
6724
+ S_memcpy (& u32_2 , src + i , 4 );
6725
+ u32_1 = S_bswap32 (u32_1 );
6726
+ u32_2 = S_bswap32 (u32_2 );
6727
+ S_memcpy (outp + j - 4 , & u32_2 , 4 );
6728
+ S_memcpy (outp + i , & u32_1 , 4 );
6712
6729
i += 4 ;
6713
6730
j -= 4 ;
6714
6731
}
6715
6732
#else
6716
6733
while (j - i >= 8 ) {
6717
- memcpy (& u32_1 , src + j - 4 , 4 );
6718
- memcpy (& u32_2 , src + i , 4 );
6719
- u32_1 = _swab_32_ (u32_1 );
6720
- u32_2 = _swab_32_ (u32_2 );
6721
- memcpy (outp + j - 4 , & u32_2 , 4 );
6722
- memcpy (outp + i , & u32_1 , 4 );
6734
+ S_memcpy (& u32_1 , src + j - 4 , 4 );
6735
+ S_memcpy (& u32_2 , src + i , 4 );
6736
+ u32_1 = S_bswap32 (u32_1 );
6737
+ u32_2 = S_bswap32 (u32_2 );
6738
+ S_memcpy (outp + j - 4 , & u32_2 , 4 );
6739
+ S_memcpy (outp + i , & u32_1 , 4 );
6723
6740
i += 4 ;
6724
6741
j -= 4 ;
6725
6742
}
6726
6743
#endif
6727
6744
if (j - i >= 4 ) {
6728
- memcpy (& u16_1 , src + j - 2 , 2 );
6729
- memcpy (& u16_2 , src + i , 2 );
6730
- u16_1 = _swab_16_ (u16_1 );
6731
- u16_2 = _swab_16_ (u16_2 );
6732
- memcpy (outp + j - 2 , & u16_2 , 2 );
6733
- memcpy (outp + i , & u16_1 , 2 );
6745
+ S_memcpy (& u16_1 , src + j - 2 , 2 );
6746
+ S_memcpy (& u16_2 , src + i , 2 );
6747
+ u16_1 = S_bswap16 (u16_1 );
6748
+ u16_2 = S_bswap16 (u16_2 );
6749
+ S_memcpy (outp + j - 2 , & u16_2 , 2 );
6750
+ S_memcpy (outp + i , & u16_1 , 2 );
6734
6751
i += 2 ;
6735
6752
j -= 2 ;
6736
6753
}
@@ -6755,7 +6772,8 @@ PP_wrapped(pp_reverse, 0, 1)
6755
6772
/* The traditional way, operate on the current byte buffer */
6756
6773
if (DO_UTF8 (TARG )) { /* first reverse each character */
6757
6774
char * down ;
6758
- U8 * s = (U8 * )SvPVX (TARG );
6775
+ assert (SvPVX (TARG ) == up );
6776
+ U8 * s = (U8 * )up ;
6759
6777
const U8 * send = (U8 * )(s + len );
6760
6778
while (s < send ) {
6761
6779
if (UTF8_IS_INVARIANT (* s )) {
@@ -6780,51 +6798,51 @@ PP_wrapped(pp_reverse, 0, 1)
6780
6798
}
6781
6799
STRLEN i = 0 ;
6782
6800
STRLEN j = len ;
6783
- uint32_t u32_1 , u32_2 ;
6784
- uint16_t u16_1 , u16_2 ;
6801
+ U32 u32_1 , u32_2 ;
6802
+ U16 u16_1 , u16_2 ;
6785
6803
/* Reverse the buffer in place, in chunks where possible */
6786
6804
#ifdef HAS_QUAD
6787
- uint64_t u64_1 , u64_2 ;
6805
+ U64 u64_1 , u64_2 ;
6788
6806
while (j - i >= 16 ) {
6789
- memcpy (& u64_1 , up + j - 8 , 8 );
6790
- memcpy (& u64_2 , up + i , 8 );
6791
- u64_1 = _swab_64_ (u64_1 );
6792
- u64_2 = _swab_64_ (u64_2 );
6793
- memcpy (up + j - 8 , & u64_2 , 8 );
6794
- memcpy (up + i , & u64_1 , 8 );
6807
+ S_memcpy (& u64_1 , up + j - 8 , 8 );
6808
+ S_memcpy (& u64_2 , up + i , 8 );
6809
+ u64_1 = S_bswap64 (u64_1 );
6810
+ u64_2 = S_bswap64 (u64_2 );
6811
+ S_memcpy (up + j - 8 , & u64_2 , 8 );
6812
+ S_memcpy (up + i , & u64_1 , 8 );
6795
6813
i += 8 ;
6796
6814
j -= 8 ;
6797
6815
}
6798
6816
6799
6817
if (j - i >= 8 ) {
6800
- memcpy (& u32_1 , up + j - 4 , 4 );
6801
- memcpy (& u32_2 , up + i , 4 );
6802
- u32_1 = _swab_32_ (u32_1 );
6803
- u32_2 = _swab_32_ (u32_2 );
6804
- memcpy (up + j - 4 , & u32_2 , 4 );
6805
- memcpy (up + i , & u32_1 , 4 );
6818
+ S_memcpy (& u32_1 , up + j - 4 , 4 );
6819
+ S_memcpy (& u32_2 , up + i , 4 );
6820
+ u32_1 = S_bswap32 (u32_1 );
6821
+ u32_2 = S_bswap32 (u32_2 );
6822
+ S_memcpy (up + j - 4 , & u32_2 , 4 );
6823
+ S_memcpy (up + i , & u32_1 , 4 );
6806
6824
i += 4 ;
6807
6825
j -= 4 ;
6808
6826
}
6809
6827
#else
6810
6828
while (j - i >= 8 ) {
6811
- memcpy (& u32_1 , up + j - 4 , 4 );
6812
- memcpy (& u32_2 , up + i , 4 );
6813
- u32_1 = _swab_32_ (u32_1 );
6814
- u32_2 = _swab_32_ (u32_2 );
6815
- memcpy (up + j - 4 , & u32_2 , 4 );
6816
- memcpy (up + i , & u32_1 , 4 );
6829
+ S_memcpy (& u32_1 , up + j - 4 , 4 );
6830
+ S_memcpy (& u32_2 , up + i , 4 );
6831
+ u32_1 = S_bswap32 (u32_1 );
6832
+ u32_2 = S_bswap32 (u32_2 );
6833
+ S_memcpy (up + j - 4 , & u32_2 , 4 );
6834
+ S_memcpy (up + i , & u32_1 , 4 );
6817
6835
i += 4 ;
6818
6836
j -= 4 ;
6819
6837
}
6820
6838
#endif
6821
6839
if (j - i >= 4 ) {
6822
- memcpy (& u16_1 , up + j - 2 , 2 );
6823
- memcpy (& u16_2 , up + i , 2 );
6824
- u16_1 = _swab_16_ (u16_1 );
6825
- u16_2 = _swab_16_ (u16_2 );
6826
- memcpy (up + j - 2 , & u16_2 , 2 );
6827
- memcpy (up + i , & u16_1 , 2 );
6840
+ S_memcpy (& u16_1 , up + j - 2 , 2 );
6841
+ S_memcpy (& u16_2 , up + i , 2 );
6842
+ u16_1 = S_bswap16 (u16_1 );
6843
+ u16_2 = S_bswap16 (u16_2 );
6844
+ S_memcpy (up + j - 2 , & u16_2 , 2 );
6845
+ S_memcpy (up + i , & u16_1 , 2 );
6828
6846
i += 2 ;
6829
6847
j -= 2 ;
6830
6848
}
@@ -6843,6 +6861,11 @@ PP_wrapped(pp_reverse, 0, 1)
6843
6861
RETURN ;
6844
6862
}
6845
6863
6864
+ #undef S_memcpy
6865
+ #undef S_bswap16
6866
+ #undef S_bswap32
6867
+ #undef S_bswap64
6868
+
6846
6869
PP_wrapped (pp_split ,
6847
6870
( (PL_op -> op_private & OPpSPLIT_ASSIGN )
6848
6871
&& (PL_op -> op_flags & OPf_STACKED ))
@@ -8179,6 +8202,18 @@ PP(pp_is_tainted)
8179
8202
return NORMAL ;
8180
8203
}
8181
8204
8205
+ #ifdef _MSC_VER
8206
+ /* this pragma can't be push/pop-ed vs whatever the cmd line to cl.exe was */
8207
+ # pragma intrinsic(memcpy)
8208
+
8209
+ void *
8210
+ S_memcpy (void * dest , const void * src , size_t count )
8211
+ {
8212
+ return memcpy (dest , src , count );
8213
+ }
8214
+
8215
+ #endif
8216
+
8182
8217
/*
8183
8218
* ex: set ts=8 sts=4 sw=4 et:
8184
8219
*/
0 commit comments