Merge pp_index and pp_rindex - we have another mathom.
Nicholas Clark [Tue, 7 Feb 2006 13:13:44 +0000 (13:13 +0000)]
p4raw-id: //depot/perl@27118

mathoms.c
opcode.h
opcode.pl
pp.c

index 61c2dc9..261abe3 100644 (file)
--- a/mathoms.c
+++ b/mathoms.c
@@ -1039,6 +1039,11 @@ PP(pp_sge)
     return pp_sle();
 }
 
+PP(pp_rindex)
+{
+    return pp_index();
+}
+
 U8 *
 Perl_uvuni_to_utf8(pTHX_ U8 *d, UV uv)
 {
index ac3c01e..5b73eb6 100644 (file)
--- a/opcode.h
+++ b/opcode.h
@@ -899,7 +899,7 @@ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */
        MEMBER_TO_FPTR(Perl_pp_substr),
        MEMBER_TO_FPTR(Perl_pp_vec),
        MEMBER_TO_FPTR(Perl_pp_index),
-       MEMBER_TO_FPTR(Perl_pp_rindex),
+       MEMBER_TO_FPTR(Perl_pp_index),  /* Perl_pp_rindex */
        MEMBER_TO_FPTR(Perl_pp_sprintf),
        MEMBER_TO_FPTR(Perl_pp_formline),
        MEMBER_TO_FPTR(Perl_pp_ord),
index b2bcf90..c548f7b 100755 (executable)
--- a/opcode.pl
+++ b/opcode.pl
@@ -79,6 +79,7 @@ my @raw_alias = (
                 Perl_pp_ucfirst => ['lcfirst'],
                 Perl_pp_sle => [qw(slt sgt sge)],
                 Perl_pp_print => ['say'],
+                Perl_pp_index => ['rindex'],
                );
 
 while (my ($func, $names) = splice @raw_alias, 0, 2) {
diff --git a/pp.c b/pp.c
index 29c845d..01dac5c 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -3112,6 +3112,7 @@ PP(pp_index)
     SV *little;
     SV *temp = NULL;
     STRLEN biglen;
+    STRLEN llen = 0;
     I32 offset;
     I32 retval;
     const char *tmps;
@@ -3119,9 +3120,13 @@ PP(pp_index)
     const I32 arybase = PL_curcop->cop_arybase;
     bool big_utf8;
     bool little_utf8;
+    const bool is_index = PL_op->op_type == OP_INDEX;
 
-    if (MAXARG >= 3)
+    if (MAXARG >= 3) {
+       /* arybase is in characters, like offset, so combine prior to the
+          UTF-8 to bytes calculation.  */
        offset = POPi - arybase;
+    }
     little = POPs;
     big = POPs;
     big_utf8 = DO_UTF8(big);
@@ -3167,95 +3172,27 @@ PP(pp_index)
            }
        }
     }
-    tmps = SvPV_const(big, biglen);
-
-    if (MAXARG < 3)
-       offset = 0;
-    else {
-       if (big_utf8 && offset > 0)
-           sv_pos_u2b(big, &offset, 0);
+    if (!is_index) {
+       tmps2 = SvPV_const(little, llen);
     }
-    if (offset < 0)
-       offset = 0;
-    else if (offset > (I32)biglen)
-       offset = biglen;
-    if (!(tmps2 = fbm_instr((unsigned char*)tmps + offset,
-      (unsigned char*)tmps + biglen, little, 0)))
-       retval = -1;
-    else {
-       retval = tmps2 - tmps;
-       if (retval > 0 && big_utf8)
-           sv_pos_b2u(big, &retval);
-    }
-    if (temp)
-       SvREFCNT_dec(temp);
- fail:
-    PUSHi(retval + arybase);
-    RETURN;
-}
-
-PP(pp_rindex)
-{
-    dVAR; dSP; dTARGET;
-    SV *big;
-    SV *little;
-    SV *temp = NULL;
-    STRLEN biglen;
-    STRLEN llen;
-    I32 offset;
-    I32 retval;
-    const char *tmps;
-    const char *tmps2;
-    const I32 arybase = PL_curcop->cop_arybase;
-    int big_utf8;
-    int little_utf8;
-
-    if (MAXARG >= 3) {
-       /* arybase is in characters, like offset, so combine prior to the
-          UTF-8 to bytes calculation.  */
-       offset = POPi - arybase;
-    }
-    little = POPs;
-    big = POPs;
-    big_utf8 = DO_UTF8(big);
-    little_utf8 = DO_UTF8(little);
-    if (big_utf8 ^ little_utf8) {
-       /* One needs to be upgraded.  */
-       SV * const bytes = little_utf8 ? big : little;
-       STRLEN len;
-       const char *p = SvPV_const(bytes, len);
-
-       temp = newSVpvn(p, len);
-
-       if (PL_encoding) {
-           sv_recode_to_utf8(temp, PL_encoding);
-       } else {
-           sv_utf8_upgrade(temp);
-       }
-       if (little_utf8) {
-           big = temp;
-           big_utf8 = TRUE;
-       } else {
-           little = temp;
-       }
-    }
-    tmps2 = SvPV_const(little, llen);
     tmps = SvPV_const(big, biglen);
 
     if (MAXARG < 3)
-       offset = biglen;
+       offset = is_index ? 0 : biglen;
     else {
        if (big_utf8 && offset > 0)
            sv_pos_u2b(big, &offset, 0);
-       /* llen is in bytes.  */
        offset += llen;
     }
     if (offset < 0)
        offset = 0;
     else if (offset > (I32)biglen)
        offset = biglen;
-    if (!(tmps2 = rninstr(tmps,  tmps  + offset,
-                         tmps2, tmps2 + llen)))
+    if (!(tmps2 = is_index
+         ? fbm_instr((unsigned char*)tmps + offset,
+                     (unsigned char*)tmps + biglen, little, 0)
+         : rninstr(tmps,  tmps  + offset,
+                   tmps2, tmps2 + llen)))
        retval = -1;
     else {
        retval = tmps2 - tmps;
@@ -3264,6 +3201,7 @@ PP(pp_rindex)
     }
     if (temp)
        SvREFCNT_dec(temp);
+ fail:
     PUSHi(retval + arybase);
     RETURN;
 }