File tree Expand file tree Collapse file tree 3 files changed +49
-3
lines changed Expand file tree Collapse file tree 3 files changed +49
-3
lines changed Original file line number Diff line number Diff line change @@ -1084,6 +1084,7 @@ namespace Js
10841084 newInstance->m_flags = InterpreterStackFrameFlags_None;
10851085 newInstance->closureInitDone = false ;
10861086 newInstance->isParamScopeDone = false ;
1087+ newInstance->shouldCacheSP = true ;
10871088#if ENABLE_PROFILE_INFO
10881089 newInstance->switchProfileMode = false ;
10891090 newInstance->isAutoProfiling = false ;
@@ -6744,7 +6745,10 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
67446745 // mark the stackFrame as 'in try block'
67456746 this ->m_flags |= InterpreterStackFrameFlags_WithinTryBlock;
67466747
6747- CacheSp ();
6748+ if (shouldCacheSP)
6749+ {
6750+ CacheSp ();
6751+ }
67486752
67496753 if (this ->IsInDebugMode ())
67506754 {
@@ -6772,10 +6776,10 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
67726776 this ->m_flags &= ~InterpreterStackFrameFlags_WithinTryBlock;
67736777 }
67746778
6779+ shouldCacheSP = !skipFinallyBlock;
6780+
67756781 if (skipFinallyBlock)
67766782 {
6777- RestoreSp ();
6778-
67796783 // A leave occurred due to a yield
67806784 return ;
67816785 }
Original file line number Diff line number Diff line change @@ -112,6 +112,7 @@ namespace Js
112112
113113 bool closureInitDone : 1 ;
114114 bool isParamScopeDone : 1 ;
115+ bool shouldCacheSP : 1 ; // Helps in determining if we need to cache the sp in ProcessTryFinally
115116#if ENABLE_PROFILE_INFO
116117 bool switchProfileMode : 1 ;
117118 bool isAutoProfiling : 1 ;
Original file line number Diff line number Diff line change @@ -1069,6 +1069,47 @@ var tests = [
10691069 } ) ;
10701070 }
10711071 } ,
1072+ {
1073+ name : "BugFix : yielding in the call expression under generator function" ,
1074+ body : function ( ) {
1075+ var val = 0 ;
1076+ function bar ( a , b , c ) { val = b ; }
1077+ function * foo ( d ) {
1078+ for ( var k of [ 2 , 3 ] ) {
1079+ bar ( 1 , d ? yield : d , k ) ;
1080+ }
1081+ }
1082+ var iter = foo ( true ) ;
1083+ iter . next ( ) ;
1084+ iter . next ( ) ;
1085+ iter . next ( 10 ) ;
1086+ assert . areEqual ( val , 10 , "yielding in the call expression under for..of is working correctly" ) ;
1087+ }
1088+ } ,
1089+ {
1090+ name : "BugFix : yielding in the call expression under try catch" ,
1091+ body : function ( ) {
1092+ var val = 0 ;
1093+ var counter = 0 ;
1094+ function bar ( a , b , c ) { val = b ; }
1095+ function * foo ( d ) {
1096+ try {
1097+ try {
1098+ bar ( 1 , d ? yield : d , 11 ) ;
1099+ } finally {
1100+ counter ++ ;
1101+ }
1102+ } finally {
1103+ counter ++ ;
1104+ }
1105+ }
1106+ var iter = foo ( true ) ;
1107+ iter . next ( ) ;
1108+ iter . next ( 10 ) ;
1109+ assert . areEqual ( val , 10 , "yielding in the call expression under try/catch is working correctly" ) ;
1110+ assert . areEqual ( counter , 2 , "both finally called after yielding" ) ;
1111+ }
1112+ } ,
10721113] ;
10731114
10741115testRunner . runTests ( tests , {
You can’t perform that action at this time.
0 commit comments