Bug 1343363 - Check RegExp wasn't modified in RegExp.p.@@replace global elem-base optimized path. r=till
authorAndré Bargull <andre.bargull@gmail.com>
Mon, 05 Jun 2017 13:23:01 +0200
changeset 410696 7fe1ee54c97bcb6cf7a96b3ee05c1d6f5e23e766
parent 410695 43d1e5140752e9b49ea18efe371065dc37e44270
child 410697 2240d6e36324d77bff5260084243f863b74dfcdd
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1343363
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1343363 - Check RegExp wasn't modified in RegExp.p.@@replace global elem-base optimized path. r=till
js/src/builtin/RegExpGlobalReplaceOpt.h.js
js/src/tests/ecma_6/RegExp/replace-compile-elembase.js
--- a/js/src/builtin/RegExpGlobalReplaceOpt.h.js
+++ b/js/src/builtin/RegExpGlobalReplaceOpt.h.js
@@ -26,17 +26,17 @@ function FUNC_NAME(rx, S, lengthS, repla
                    , elemBase
 #endif
                   )
 {
     // Step 8.b.
     var lastIndex = 0;
     rx.lastIndex = 0;
 
-#if defined(FUNCTIONAL)
+#if defined(FUNCTIONAL) || defined(ELEMBASE)
     // Save the original source and flags, so we can check if the replacer
     // function recompiled the regexp.
     var originalSource = UnsafeGetStringFromReservedSlot(rx, REGEXP_SOURCE_SLOT);
     var originalFlags = UnsafeGetInt32FromReservedSlot(rx, REGEXP_FLAGS_SLOT);
 #endif
 
     // Step 12 (reordered).
     var accumulatedResult = "";
@@ -104,17 +104,17 @@ function FUNC_NAME(rx, S, lengthS, repla
 
         // Step 11.c.iii.2.
         if (matchLength === 0) {
             lastIndex = fullUnicode ? AdvanceStringIndex(S, lastIndex) : lastIndex + 1;
             if (lastIndex > lengthS)
                 break;
         }
 
-#if defined(FUNCTIONAL)
+#if defined(FUNCTIONAL) || defined(ELEMBASE)
         // Ensure the current source and flags match the original regexp, the
         // replaceValue function may have called RegExp#compile.
         if (UnsafeGetStringFromReservedSlot(rx, REGEXP_SOURCE_SLOT) !== originalSource ||
             UnsafeGetInt32FromReservedSlot(rx, REGEXP_FLAGS_SLOT) !== originalFlags)
         {
             rx = regexp_construct_raw_flags(originalSource, originalFlags);
         }
 #endif
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/replace-compile-elembase.js
@@ -0,0 +1,22 @@
+(function() {
+    var rx = /a/g;
+    var b = {
+        get a() {
+            rx.compile("b");
+            return "A";
+        }
+    };
+
+    // Replacer function which is applicable for the elem-base optimization in
+    // RegExp.prototype.@@replace.
+    function replacer(a) {
+        return b[a];
+    }
+
+    var result = rx[Symbol.replace]("aaa", replacer);
+
+    assertEq(result, "AAA");
+})();
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);