Sfoglia il codice sorgente

OS 18333466 : Recursion in the generator next call.

Moving exception throw out from the catch handler. Otherwise we will throw hard stack overflow.
Fixed that in the DoIteratorStepAndValue as well
Akrosh Gandhi 7 anni fa
parent
commit
cc098c42d8

+ 7 - 2
lib/Runtime/Language/JavascriptOperators.inl

@@ -62,6 +62,7 @@ namespace Js
     {
         Var nextItem = nullptr;
         bool shouldCallReturn = false;
+        JavascriptExceptionObject *exception = nullptr;
         try
         {
             while (JavascriptOperators::IteratorStepAndValue(iterator, scriptContext, &nextItem))
@@ -73,13 +74,17 @@ namespace Js
         }
         catch (const JavascriptException& err)
         {
-            JavascriptExceptionObject * exceptionObj = err.GetAndClear();
+            exception = err.GetAndClear();
+        }
+
+        if (exception != nullptr)
+        {
             if (shouldCallReturn)
             {
                 // Closing the iterator
                 JavascriptOperators::IteratorClose(iterator, scriptContext);
             }
-            JavascriptExceptionOperators::DoThrow(exceptionObj, scriptContext);
+            JavascriptExceptionOperators::DoThrowCheckClone(exception, scriptContext);
         }
     }
 

+ 10 - 4
lib/Runtime/Library/JavascriptGenerator.cpp

@@ -126,6 +126,8 @@ namespace Js
             Var thunkArgs[] = { this, yieldData };
             Arguments arguments(_countof(thunkArgs), thunkArgs);
 
+            JavascriptExceptionObject *exception = nullptr;
+
             try
             {
                 BEGIN_SAFE_REENTRANT_CALL(scriptContext->GetThreadContext())
@@ -137,12 +139,16 @@ namespace Js
             }
             catch (const JavascriptException& err)
             {
-                Js::JavascriptExceptionObject* exceptionObj = err.GetAndClear();
-                if (!exceptionObj->IsGeneratorReturnException())
+                exception = err.GetAndClear();
+            }
+
+            if (exception != nullptr)
+            {
+                if (!exception->IsGeneratorReturnException())
                 {
-                    JavascriptExceptionOperators::DoThrow(exceptionObj, scriptContext);
+                    JavascriptExceptionOperators::DoThrowCheckClone(exception, scriptContext);
                 }
-                result = exceptionObj->GetThrownObject(nullptr);
+                result = exception->GetThrownObject(nullptr);
             }
         }
 

+ 16 - 1
test/Bugs/misc_bugs.js

@@ -174,7 +174,22 @@ var tests = [
         assert.throws(() => {"use strict"; let p1 = new Proxy({}, { deleteProperty() {return false;}}); delete p1.foo;}, TypeError, "deleteProperty handler is returning false which will throw type error",  "Proxy deleteProperty handler returned false");
       }
   },
-  
+  {
+    name: "Generator : testing recursion",
+    body: function () {
+        // This will throw out of stack error
+        assert.throws(() => {
+            function foo() {
+                function *f() {
+                    yield foo();
+                }
+                f().next();
+            }
+            foo();
+        });
+      }
+  },
+
 ];
 
 testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });