]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/StringRecursionChecker.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / StringRecursionChecker.h
index 07dc25ababc5c856afcbddda4e1f3385cf5933c1..0f1990e76f0f2482c9d9b034cb5131bf1bfb5b9e 100644 (file)
@@ -49,10 +49,18 @@ private:
 
 inline JSValue StringRecursionChecker::performCheck()
 {
-    const StackBounds& nativeStack = wtfThreadData().stack();
-    if (!nativeStack.isSafeToRecurse())
+    VM& vm = m_exec->vm();
+    if (!vm.isSafeToRecurse())
         return throwStackOverflowError();
-    bool alreadyVisited = !m_exec->vm().stringRecursionCheckVisitedObjects.add(m_thisObject).isNewEntry;
+
+    bool alreadyVisited = false;
+    if (!vm.stringRecursionCheckFirstObject)
+        vm.stringRecursionCheckFirstObject = m_thisObject;
+    else if (vm.stringRecursionCheckFirstObject == m_thisObject)
+        alreadyVisited = true;
+    else
+        alreadyVisited = !vm.stringRecursionCheckVisitedObjects.add(m_thisObject).isNewEntry;
+
     if (alreadyVisited)
         return emptyString(); // Return empty string to avoid infinite recursion.
     return JSValue(); // Indicate success.
@@ -74,8 +82,14 @@ inline StringRecursionChecker::~StringRecursionChecker()
 {
     if (m_earlyReturnValue)
         return;
-    ASSERT(m_exec->vm().stringRecursionCheckVisitedObjects.contains(m_thisObject));
-    m_exec->vm().stringRecursionCheckVisitedObjects.remove(m_thisObject);
+
+    VM& vm = m_exec->vm();
+    if (vm.stringRecursionCheckFirstObject == m_thisObject)
+        vm.stringRecursionCheckFirstObject = nullptr;
+    else {
+        ASSERT(vm.stringRecursionCheckVisitedObjects.contains(m_thisObject));
+        vm.stringRecursionCheckVisitedObjects.remove(m_thisObject);
+    }
 }
 
 }