@@ -86,15 +86,50 @@ module.exports = function (t, year, GeneratorResumeAbrupt, extras) {
8686 'generator with return completion -> done iter result'
8787 ) ;
8888
89+ // test re-entrant return() throws TypeError
90+ var reentrantGenerator = { } ;
91+ SLOT . set ( reentrantGenerator , '[[GeneratorState]]' , 'SUSPENDED-YIELD' ) ;
92+ SLOT . set ( reentrantGenerator , '[[GeneratorBrand]]' , brand ) ;
93+ SLOT . set ( reentrantGenerator , '[[GeneratorContext]]' , null ) ;
94+
95+ var enterCount = 0 ;
96+ var reentrantCloseIfAbrupt = function ( ) {
97+ enterCount += 1 ;
98+ if ( enterCount > 1 ) {
99+ // guard against infinite recursion in case the fix is not applied
100+ throw new RangeError ( 're-entrant call was not prevented' ) ;
101+ }
102+ // re-entrant call while generator is executing
103+ GeneratorResumeAbrupt ( reentrantGenerator , ReturnCompletion ( undefined ) , brand ) ;
104+ return { sentinel : true } ;
105+ } ;
106+ SLOT . set ( reentrantGenerator , '[[CloseIfAbrupt]]' , reentrantCloseIfAbrupt ) ;
107+
108+ t . equal ( enterCount , 0 , 'closeIfAbrupt not called yet' ) ;
109+
110+ t [ 'throws' ] (
111+ function ( ) { GeneratorResumeAbrupt ( reentrantGenerator , ReturnCompletion ( 42 ) , brand ) ; } ,
112+ TypeError ,
113+ 'throws TypeError when return() is called re-entrantly during [[CloseIfAbrupt]]'
114+ ) ;
115+
116+ t . equal ( enterCount , 1 , 'closeIfAbrupt was entered exactly once before throwing' ) ;
117+
89118 SLOT . set ( generator , '[[GeneratorState]]' , 'SUSPENDED-START' ) ;
119+ t [ 'throws' ] (
120+ function ( ) { GeneratorResumeAbrupt ( generator , completion , brand ) ; } ,
121+ 42 ,
122+ 'SUSPENDED-START with throw completion transitions to COMPLETED then throws'
123+ ) ;
124+ t . equal ( SLOT . get ( generator , '[[GeneratorState]]' ) , 'COMPLETED' , 'state is completed' ) ;
125+ t . equal ( SLOT . get ( generator , '[[GeneratorContext]]' ) , null , 'context is unset' ) ;
126+
90127 t . deepEqual (
91- GeneratorResumeAbrupt ( generator , completion , brand ) ,
128+ GeneratorResumeAbrupt ( generator , ReturnCompletion ( 42 ) , brand ) ,
92129 {
93130 value : 42 ,
94131 done : true
95132 } ,
96- 'completed state -> done iter result'
133+ 'COMPLETED state with return completion -> done iter result'
97134 ) ;
98- t . equal ( SLOT . get ( generator , '[[GeneratorState]]' ) , 'COMPLETED' , 'state is completed' ) ;
99- t . equal ( SLOT . get ( generator , '[[GeneratorContext]]' ) , null , 'context is unset' ) ;
100135} ;
0 commit comments