@@ -219,6 +219,12 @@ void Visit(ParseNode *pnode, ByteCodeGenerator* byteCodeGenerator, PrefixFn pref
219219 prefix (pnode, byteCodeGenerator);
220220 switch (pnode->nop )
221221 {
222+ case knopYield:
223+ case knopYieldLeaf:
224+ case knopYieldStar:
225+ case knopAwait:
226+ byteCodeGenerator->SetHasYield ();
227+ // fall through to default
222228 default :
223229 {
224230 uint flags = ParseNode::Grfnop (pnode->nop );
@@ -245,6 +251,7 @@ void Visit(ParseNode *pnode, ByteCodeGenerator* byteCodeGenerator, PrefixFn pref
245251 break ;
246252
247253 case knopArrayPattern:
254+ byteCodeGenerator->PushTrackForYield (pnode);
248255 if (!byteCodeGenerator->InDestructuredPattern ())
249256 {
250257 byteCodeGenerator->SetInDestructuredPattern (true );
@@ -255,6 +262,7 @@ void Visit(ParseNode *pnode, ByteCodeGenerator* byteCodeGenerator, PrefixFn pref
255262 {
256263 Visit (pnode->AsParseNodeUni ()->pnode1 , byteCodeGenerator, prefix, postfix);
257264 }
265+ byteCodeGenerator->PopTrackForYield (pnode);
258266 break ;
259267
260268 case knopCall:
@@ -379,11 +387,13 @@ void Visit(ParseNode *pnode, ByteCodeGenerator* byteCodeGenerator, PrefixFn pref
379387 case knopForOf:
380388 case knopForAwaitOf:
381389 BeginVisitBlock (pnode->AsParseNodeForInOrForOf ()->pnodeBlock , byteCodeGenerator);
390+ byteCodeGenerator->PushTrackForYield (pnode);
382391 Visit (pnode->AsParseNodeForInOrForOf ()->pnodeLval , byteCodeGenerator, prefix, postfix);
383392 Visit (pnode->AsParseNodeForInOrForOf ()->pnodeObj , byteCodeGenerator, prefix, postfix);
384393 byteCodeGenerator->EnterLoop ();
385394 Visit (pnode->AsParseNodeForInOrForOf ()->pnodeBody , byteCodeGenerator, prefix, postfix, pnode);
386395 byteCodeGenerator->ExitLoop ();
396+ byteCodeGenerator->PopTrackForYield (pnode);
387397 EndVisitBlock (pnode->AsParseNodeForInOrForOf ()->pnodeBlock , byteCodeGenerator);
388398 break ;
389399 // PTNODE(knopReturn , "return" ,None ,Uni ,fnopNone)
@@ -441,8 +451,10 @@ void Visit(ParseNode *pnode, ByteCodeGenerator* byteCodeGenerator, PrefixFn pref
441451 break ;
442452 // PTNODE(knopTryCatchFinally,"try-catch-finally",None,TryCatchFinally,fnopCleanup)
443453 case knopTryFinally:
454+ byteCodeGenerator->PushTrackForYield (pnode);
444455 Visit (pnode->AsParseNodeTryFinally ()->pnodeTry , byteCodeGenerator, prefix, postfix, pnode);
445456 Visit (pnode->AsParseNodeTryFinally ()->pnodeFinally , byteCodeGenerator, prefix, postfix, pnode);
457+ byteCodeGenerator->PopTrackForYield (pnode);
446458 break ;
447459 // PTNODE(knopTryCatch , "try-catch" ,None ,TryCatch ,fnopCleanup)
448460 case knopTryCatch:
@@ -728,6 +740,8 @@ ByteCodeGenerator::ByteCodeGenerator(Js::ScriptContext* scriptContext, Js::Scope
728740 flags(0 ),
729741 funcInfoStack(nullptr ),
730742 jumpCleanupList(nullptr ),
743+ nodesToTrackForYield(nullptr ),
744+ nodesWithYield(nullptr ),
731745 pRootFunc(nullptr ),
732746 pCurrentFunction(nullptr ),
733747 globalScope(nullptr ),
@@ -769,6 +783,52 @@ void ByteCodeGenerator::AddFuncInfoToFinalizationSet(FuncInfo * funcInfo)
769783 this ->funcInfosToFinalize ->Prepend (funcInfo);
770784}
771785
786+ void ByteCodeGenerator::PushTrackForYield (ParseNode* node)
787+ {
788+ if (this ->nodesToTrackForYield == nullptr )
789+ {
790+ this ->nodesToTrackForYield = Anew (alloc, SList<ParseNode*>, alloc);
791+ }
792+ this ->nodesToTrackForYield ->Push (node);
793+ }
794+
795+ void ByteCodeGenerator::PopTrackForYield (ParseNode* node)
796+ {
797+ Assert (this ->nodesToTrackForYield != nullptr );
798+ Assert (this ->nodesToTrackForYield ->Top () == node);
799+ this ->nodesToTrackForYield ->Pop ();
800+ if (this ->nodesToTrackForYield ->Empty ())
801+ {
802+ this ->nodesToTrackForYield = nullptr ;
803+ }
804+ else if (this ->GetHasYield (node))
805+ {
806+ this ->SetHasYield ();
807+ }
808+ }
809+
810+ void ByteCodeGenerator::SetHasYield ()
811+ {
812+ if (this ->nodesToTrackForYield != nullptr )
813+ {
814+ Assert (!this ->nodesToTrackForYield ->Empty ());
815+ if (this ->nodesWithYield == nullptr )
816+ {
817+ this ->nodesWithYield = Anew (alloc, SList<ParseNode*>, alloc);
818+ }
819+ this ->nodesWithYield ->Push (this ->nodesToTrackForYield ->Top ());
820+ }
821+ }
822+
823+ bool ByteCodeGenerator::GetHasYield (ParseNode* pnode)
824+ {
825+ if (this ->nodesWithYield != nullptr && this ->nodesWithYield ->Has (pnode))
826+ {
827+ return true ;
828+ }
829+ return false ;
830+ }
831+
772832/* static */
773833bool ByteCodeGenerator::IsFalse (ParseNode* node)
774834{
@@ -2203,6 +2263,8 @@ void ByteCodeGenerator::Begin(
22032263 this ->envDepth = 0 ;
22042264 this ->trackEnvDepth = false ;
22052265 this ->funcInfosToFinalize = nullptr ;
2266+ this ->nodesToTrackForYield = nullptr ;
2267+ this ->nodesWithYield = nullptr ;
22062268
22072269 this ->funcInfoStack = Anew (alloc, SList<FuncInfo*>, alloc);
22082270 this ->jumpCleanupList = Anew (alloc, JumpCleanupList, alloc);
0 commit comments