@@ -26,7 +26,7 @@ use crate::{
2626 vm:: { CompletionRecord , GeneratorResumeKind } ,
2727} ;
2828use boa_gc:: { Finalize , Trace } ;
29- use std:: collections:: VecDeque ;
29+ use std:: { collections:: VecDeque , slice } ;
3030
3131use super :: { BuiltInBuilder , IntrinsicObject } ;
3232
@@ -143,6 +143,21 @@ impl AsyncGenerator {
143143 } ) ;
144144 let generator = if_abrupt_reject_promise ! ( result, promise_capability, context) ;
145145
146+ Self :: inner_next (
147+ & generator,
148+ promise_capability,
149+ args. get_or_undefined ( 0 ) . clone ( ) ,
150+ context,
151+ )
152+ . map ( JsValue :: from)
153+ }
154+
155+ pub ( crate ) fn inner_next (
156+ generator : & JsObject < AsyncGenerator > ,
157+ cap : PromiseCapability ,
158+ value : JsValue ,
159+ context : & mut Context ,
160+ ) -> JsResult < JsObject > {
146161 // 5. Let state be generator.[[AsyncGeneratorState]].
147162 let state = generator. borrow ( ) . data ( ) . state ;
148163
@@ -152,21 +167,18 @@ impl AsyncGenerator {
152167 let iterator_result = create_iter_result_object ( JsValue :: undefined ( ) , true , context) ;
153168
154169 // b. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »).
155- promise_capability. resolve ( ) . call (
156- & JsValue :: undefined ( ) ,
157- & [ iterator_result] ,
158- context,
159- ) ?;
170+ cap. resolve ( )
171+ . call ( & JsValue :: undefined ( ) , & [ iterator_result] , context) ?;
160172
161173 // c. Return promiseCapability.[[Promise]].
162- return Ok ( promise_capability . promise ( ) . clone ( ) . into ( ) ) ;
174+ return Ok ( cap . promise ) ;
163175 }
164176
165177 // 7. Let completion be NormalCompletion(value).
166- let completion = CompletionRecord :: Normal ( args . get_or_undefined ( 0 ) . clone ( ) ) ;
178+ let completion = CompletionRecord :: Normal ( value ) ;
167179
168180 // 8. Perform AsyncGeneratorEnqueue(generator, completion, promiseCapability).
169- Self :: enqueue ( & generator, completion. clone ( ) , promise_capability . clone ( ) ) ;
181+ Self :: enqueue ( & generator, completion. clone ( ) , cap . clone ( ) ) ;
170182
171183 // 9. If state is either suspendedStart or suspendedYield, then
172184 if state == AsyncGeneratorState :: SuspendedStart
@@ -177,7 +189,7 @@ impl AsyncGenerator {
177189 }
178190
179191 // 11. Return promiseCapability.[[Promise]].
180- Ok ( promise_capability . promise ( ) . clone ( ) . into ( ) )
192+ Ok ( cap . promise )
181193 }
182194
183195 /// `AsyncGenerator.prototype.return ( value )`
@@ -216,12 +228,26 @@ impl AsyncGenerator {
216228 } ) ;
217229 let generator = if_abrupt_reject_promise ! ( result, promise_capability, context) ;
218230
231+ Self :: inner_return (
232+ & generator,
233+ promise_capability,
234+ args. get_or_undefined ( 0 ) . clone ( ) ,
235+ context,
236+ )
237+ . map ( JsValue :: from)
238+ }
239+
240+ pub ( crate ) fn inner_return (
241+ generator : & JsObject < AsyncGenerator > ,
242+ cap : PromiseCapability ,
243+ return_value : JsValue ,
244+ context : & mut Context ,
245+ ) -> JsResult < JsObject > {
219246 // 5. Let completion be Completion Record { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
220- let return_value = args. get_or_undefined ( 0 ) . clone ( ) ;
221247 let completion = CompletionRecord :: Return ( return_value. clone ( ) ) ;
222248
223249 // 6. Perform AsyncGeneratorEnqueue(generator, completion, promiseCapability).
224- Self :: enqueue ( & generator, completion. clone ( ) , promise_capability . clone ( ) ) ;
250+ Self :: enqueue ( & generator, completion. clone ( ) , cap . clone ( ) ) ;
225251
226252 // 7. Let state be generator.[[AsyncGeneratorState]].
227253 let state = generator. borrow ( ) . data ( ) . state ;
@@ -243,7 +269,7 @@ impl AsyncGenerator {
243269 // a. Assert: state is either executing or draining-queue.
244270
245271 // 11. Return promiseCapability.[[Promise]].
246- Ok ( promise_capability . promise ( ) . clone ( ) . into ( ) )
272+ Ok ( cap . promise )
247273 }
248274
249275 /// `AsyncGenerator.prototype.throw ( exception )`
@@ -281,6 +307,21 @@ impl AsyncGenerator {
281307 . into ( )
282308 } ) ;
283309 let generator = if_abrupt_reject_promise ! ( result, promise_capability, context) ;
310+ Self :: inner_throw (
311+ & generator,
312+ promise_capability,
313+ args. get_or_undefined ( 0 ) . clone ( ) ,
314+ context,
315+ )
316+ . map ( JsValue :: from)
317+ }
318+
319+ pub ( crate ) fn inner_throw (
320+ generator : & JsObject < AsyncGenerator > ,
321+ cap : PromiseCapability ,
322+ error_value : JsValue ,
323+ context : & mut Context ,
324+ ) -> JsResult < JsObject > {
284325 let mut r#gen = generator. borrow_mut ( ) ;
285326
286327 // 5. Let state be generator.[[AsyncGeneratorState]].
@@ -301,22 +342,21 @@ impl AsyncGenerator {
301342 // 7. If state is completed, then
302343 if state == AsyncGeneratorState :: Completed {
303344 // a. Perform ! Call(promiseCapability.[[Reject]], undefined, « exception »).
304- promise_capability . reject ( ) . call (
345+ cap . reject ( ) . call (
305346 & JsValue :: undefined ( ) ,
306- & [ args . get_or_undefined ( 0 ) . clone ( ) ] ,
347+ slice :: from_ref ( & error_value ) ,
307348 context,
308349 ) ?;
309350
310351 // b. Return promiseCapability.[[Promise]].
311- return Ok ( promise_capability . promise ( ) . clone ( ) . into ( ) ) ;
352+ return Ok ( cap . promise ( ) . clone ( ) . into ( ) ) ;
312353 }
313354
314355 // 8. Let completion be ThrowCompletion(exception).
315- let completion =
316- CompletionRecord :: Throw ( JsError :: from_opaque ( args. get_or_undefined ( 0 ) . clone ( ) ) ) ;
356+ let completion = CompletionRecord :: Throw ( JsError :: from_opaque ( error_value) ) ;
317357
318358 // 9. Perform AsyncGeneratorEnqueue(generator, completion, promiseCapability).
319- Self :: enqueue ( & generator, completion. clone ( ) , promise_capability . clone ( ) ) ;
359+ Self :: enqueue ( & generator, completion. clone ( ) , cap . clone ( ) ) ;
320360
321361 // 10. If state is suspended-yield, then
322362 if state == AsyncGeneratorState :: SuspendedYield {
@@ -328,7 +368,7 @@ impl AsyncGenerator {
328368 // a. Assert: state is either executing or draining-queue.
329369
330370 // 12. Return promiseCapability.[[Promise]].
331- Ok ( promise_capability . promise ( ) . clone ( ) . into ( ) )
371+ Ok ( cap . promise ( ) . clone ( ) . into ( ) )
332372 }
333373
334374 /// `AsyncGeneratorEnqueue ( generator, completion, promiseCapability )`
0 commit comments