Skip to content

Commit d28ff47

Browse files
committed
[1.10>master] [MERGE #5519 @akroshg] OS 18333466 : Recursion in the generator next call.
Merge pull request #5519 from akroshg:generator Moving exception throw out from the catch handler. Otherwise we will throw hard stack overflow.
2 parents 6906f95 + 55c9960 commit d28ff47

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

lib/Runtime/Language/JavascriptOperators.inl

+7-2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ namespace Js
6262
{
6363
Var nextItem = nullptr;
6464
bool shouldCallReturn = false;
65+
JavascriptExceptionObject *exception = nullptr;
6566
try
6667
{
6768
while (JavascriptOperators::IteratorStepAndValue(iterator, scriptContext, &nextItem))
@@ -73,13 +74,17 @@ namespace Js
7374
}
7475
catch (const JavascriptException& err)
7576
{
76-
JavascriptExceptionObject * exceptionObj = err.GetAndClear();
77+
exception = err.GetAndClear();
78+
}
79+
80+
if (exception != nullptr)
81+
{
7782
if (shouldCallReturn)
7883
{
7984
// Closing the iterator
8085
JavascriptOperators::IteratorClose(iterator, scriptContext);
8186
}
82-
JavascriptExceptionOperators::DoThrow(exceptionObj, scriptContext);
87+
JavascriptExceptionOperators::DoThrowCheckClone(exception, scriptContext);
8388
}
8489
}
8590

lib/Runtime/Library/JavascriptGenerator.cpp

+10-4
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ namespace Js
126126
Var thunkArgs[] = { this, yieldData };
127127
Arguments arguments(_countof(thunkArgs), thunkArgs);
128128

129+
JavascriptExceptionObject *exception = nullptr;
130+
129131
try
130132
{
131133
BEGIN_SAFE_REENTRANT_CALL(scriptContext->GetThreadContext())
@@ -137,12 +139,16 @@ namespace Js
137139
}
138140
catch (const JavascriptException& err)
139141
{
140-
Js::JavascriptExceptionObject* exceptionObj = err.GetAndClear();
141-
if (!exceptionObj->IsGeneratorReturnException())
142+
exception = err.GetAndClear();
143+
}
144+
145+
if (exception != nullptr)
146+
{
147+
if (!exception->IsGeneratorReturnException())
142148
{
143-
JavascriptExceptionOperators::DoThrow(exceptionObj, scriptContext);
149+
JavascriptExceptionOperators::DoThrowCheckClone(exception, scriptContext);
144150
}
145-
result = exceptionObj->GetThrownObject(nullptr);
151+
result = exception->GetThrownObject(nullptr);
146152
}
147153
}
148154

test/Bugs/misc_bugs.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,22 @@ var tests = [
174174
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");
175175
}
176176
},
177-
177+
{
178+
name: "Generator : testing recursion",
179+
body: function () {
180+
// This will throw out of stack error
181+
assert.throws(() => {
182+
function foo() {
183+
function *f() {
184+
yield foo();
185+
}
186+
f().next();
187+
}
188+
foo();
189+
});
190+
}
191+
},
192+
178193
];
179194

180195
testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });

0 commit comments

Comments
 (0)