Additional regexp DoReplace diagnostics. (r=dmandelin, a=blocker, b=605754)
authorChris Leary <cdleary@mozilla.com>
Wed, 01 Dec 2010 16:34:42 -0800
changeset 58511 be1f9b4e522e94d7db7488d52d8394b0dc883c56
parent 58510 a93d62654d2d43b5176d431768dde5212772db46
child 58512 5ae1f2fa0d9f2b9560d5aecc28d4b945a78db941
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersdmandelin, blocker
bugs605754
milestone2.0b8pre
Additional regexp DoReplace diagnostics. (r=dmandelin, a=blocker, b=605754)
js/src/jscntxt.h
js/src/jsstr.cpp
js/src/yarr/yarr/RegexJIT.cpp
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -2364,20 +2364,34 @@ struct JSContext
     void assertValidStackDepth(uintN /*depth*/) {}
 #endif
 
     enum DollarPath {
         DOLLAR_LITERAL = 1,
         DOLLAR_AMP,
         DOLLAR_PLUS,
         DOLLAR_TICK,
-        DOLLAR_QUOT
+        DOLLAR_QUOT,
+        DOLLAR_EMPTY,
+        DOLLAR_1,
+        DOLLAR_2,
+        DOLLAR_3,
+        DOLLAR_4,
+        DOLLAR_5,
+        DOLLAR_OTHER
     };
+#ifdef XP_WIN
     volatile DollarPath *dollarPath;
+    volatile JSSubString *sub;
     volatile jschar *blackBox;
+    volatile jschar **repstrChars;
+    volatile jschar **repstrDollar;
+    volatile jschar **repstrDollarEnd;
+    volatile size_t *peekLen;
+#endif
 
 private:
 
     /*
      * The allocation code calls the function to indicate either OOM failure
      * when p is null or that a memory pressure counter has reached some
      * threshold when p is not null. The function takes the pointer and not
      * a boolean flag to minimize the amount of code in its inlined callers.
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -2015,16 +2015,26 @@ InterpretDollar(JSContext *cx, RegExpSta
             }
         }
         if (num == 0)
             return false;
 
         *skip = cp - dp;
 
         JS_CRASH_UNLESS(num <= res->parenCount());
+
+        switch (num) {
+          case 1: *path = JSContext::DOLLAR_1; break;
+          case 2: *path = JSContext::DOLLAR_2; break;
+          case 3: *path = JSContext::DOLLAR_3; break;
+          case 4: *path = JSContext::DOLLAR_4; break;
+          case 5: *path = JSContext::DOLLAR_5; break;
+          default: *path = JSContext::DOLLAR_OTHER;
+        }
+
         /* 
          * Note: we index to get the paren with the (1-indexed) pair
          * number, as opposed to a (0-indexed) paren number.
          */
         res->getParen(num, out);
         return true;
     }
 
@@ -2180,34 +2190,49 @@ FindReplaceLength(JSContext *cx, RegExpS
 
 static void
 DoReplace(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, jschar *chars)
 {
     JSString *repstr = rdata.repstr;
     jschar *cp;
     jschar *bp = cp = repstr->chars();
     volatile JSContext::DollarPath path;
+#ifdef XP_WIN
     cx->dollarPath = &path;
     jschar sourceBuf[128];
     cx->blackBox = sourceBuf;
+#endif
 
     for (jschar *dp = rdata.dollar, *ep = rdata.dollarEnd; dp; dp = js_strchr_limit(dp, '$', ep)) {
         size_t len = dp - cp;
         js_strncpy(chars, cp, len);
         chars += len;
         cp = dp;
 
         JSSubString sub;
         size_t skip;
         if (InterpretDollar(cx, res, dp, ep, rdata, &sub, &skip, &path)) {
+#ifdef XP_WIN
             if (((size_t(sub.chars) & 0xfffffU) + sub.length) > 0x100000U) {
                 /* Going to cross a 0xffffe address, so take a gander at the replace value. */
-                size_t peekLen = JS_MIN(rdata.dollarEnd - rdata.dollar, 128);
-                js_strncpy(sourceBuf, rdata.dollar, peekLen);
+                volatile JSSubString vsub = sub;
+                volatile jschar *repstrChars = rdata.repstr->chars();
+                volatile jschar *repstrDollar = rdata.dollar;
+                volatile jschar *repstrDollarEnd = rdata.dollarEnd;
+                cx->sub = &vsub;
+                cx->repstrChars = &repstrChars;
+                cx->repstrDollar = &repstrDollar;
+                cx->repstrDollarEnd = &repstrDollarEnd;
+                ptrdiff_t dollarDistance = rdata.dollarEnd - rdata.dollar;
+                JS_CRASH_UNLESS(dollarDistance >= 0);
+                volatile size_t peekLen = JS_MIN(rdata.repstr->length(), 128);
+                cx->peekLen = &peekLen;
+                js_strncpy(sourceBuf, rdata.repstr->chars(), peekLen);
             }
+#endif
 
             len = sub.length;
             js_strncpy(chars, sub.chars, len);
             chars += len;
             cp += skip;
             dp += skip;
         } else {
             dp++;
--- a/js/src/yarr/yarr/RegexJIT.cpp
+++ b/js/src/yarr/yarr/RegexJIT.cpp
@@ -989,17 +989,17 @@ class RegexGenerator : private MacroAsse
                 branchTest32(Zero, indexTemporary).linkTo(nonGreedyTryParentheses, this);
             }
 
             parenthesesState.plantJumpToBacktrackIfExists(this);
             // A failure WITHIN the parens jumps here
             parenthesesState.linkAlternativeBacktracks(this);
             if (term.invertOrCapture) {
                 store32(Imm32(-1), Address(output, (term.parentheses.subpatternId << 1) * sizeof(int)));
-#if DEBUG
+#if 0
                 store32(Imm32(-1), Address(output, ((term.parentheses.subpatternId << 1) + 1) * sizeof(int)));
 #endif
             }
 
             if (term.quantityType == QuantifierGreedy)
                 storeToFrame(Imm32(0), parenthesesFrameLocation);
             else
                 state.jumpToBacktrack(jump(), this);