@@ -306,11 +306,6 @@ impl ArrayRef {
306306 elem : & Val ,
307307 len : u32 ,
308308 ) -> Result < Rooted < ArrayRef > > {
309- assert_eq ! (
310- store. id( ) ,
311- allocator. store_id,
312- "attempted to use a `ArrayRefPre` with the wrong store"
313- ) ;
314309 assert ! (
315310 !store. async_support( ) ,
316311 " use `ArrayRef::new_async` with asynchronous stores"
@@ -374,11 +369,6 @@ impl ArrayRef {
374369 elem : & Val ,
375370 len : u32 ,
376371 ) -> Result < Rooted < ArrayRef > > {
377- assert_eq ! (
378- store. id( ) ,
379- allocator. store_id,
380- "attempted to use a `ArrayRefPre` with the wrong store"
381- ) ;
382372 assert ! (
383373 store. async_support( ) ,
384374 "use `ArrayRef::new` with synchronous stores"
@@ -395,13 +385,38 @@ impl ArrayRef {
395385 . await
396386 }
397387
388+ /// Like `ArrayRef::new` but when async is configured must only ever be
389+ /// called from on a fiber stack.
390+ pub ( crate ) unsafe fn new_maybe_async (
391+ store : & mut StoreOpaque ,
392+ allocator : & ArrayRefPre ,
393+ elem : & Val ,
394+ len : u32 ,
395+ ) -> Result < Rooted < ArrayRef > > {
396+ // Type check the initial element value against the element type.
397+ elem. ensure_matches_ty ( store, allocator. ty . element_type ( ) . unpack ( ) )
398+ . context ( "element type mismatch" ) ?;
399+
400+ unsafe {
401+ store. retry_after_gc_maybe_async ( ( ) , |store, ( ) | {
402+ Self :: _new_unchecked ( store, allocator, RepeatN ( elem, len) )
403+ } )
404+ }
405+ }
406+
398407 /// Allocate a new array of the given elements, without checking that the
399408 /// elements' types match the array's element type.
400409 fn _new_unchecked < ' a > (
401410 store : & mut StoreOpaque ,
402411 allocator : & ArrayRefPre ,
403412 elems : impl ExactSizeIterator < Item = & ' a Val > ,
404413 ) -> Result < Rooted < ArrayRef > > {
414+ assert_eq ! (
415+ store. id( ) ,
416+ allocator. store_id,
417+ "attempted to use a `ArrayRefPre` with the wrong store"
418+ ) ;
419+
405420 let len = u32:: try_from ( elems. len ( ) ) . unwrap ( ) ;
406421
407422 // Allocate the array and write each field value into the appropriate
@@ -572,6 +587,34 @@ impl ArrayRef {
572587 . await
573588 }
574589
590+ /// Like `ArrayRef::new_fixed[_async]` but it is the caller's responsibility
591+ /// to ensure that when async is enabled, this is only called from on a
592+ /// fiber stack.
593+ #[ cfg( feature = "async" ) ]
594+ pub ( crate ) unsafe fn _new_fixed_maybe_async (
595+ store : & mut StoreOpaque ,
596+ allocator : & ArrayRefPre ,
597+ elems : & [ Val ] ,
598+ ) -> Result < Rooted < ArrayRef > > {
599+ assert_eq ! (
600+ store. id( ) ,
601+ allocator. store_id,
602+ "attempted to use a `ArrayRefPre` with the wrong store"
603+ ) ;
604+
605+ // Type check the elements against the element type.
606+ for elem in elems {
607+ elem. ensure_matches_ty ( store, allocator. ty . element_type ( ) . unpack ( ) )
608+ . context ( "element type mismatch" ) ?;
609+ }
610+
611+ unsafe {
612+ store. retry_after_gc_maybe_async ( ( ) , |store, ( ) | {
613+ Self :: _new_unchecked ( store, allocator, elems. iter ( ) )
614+ } )
615+ }
616+ }
617+
575618 #[ inline]
576619 pub ( crate ) fn comes_from_same_store ( & self , store : & StoreOpaque ) -> bool {
577620 self . inner . comes_from_same_store ( store)
0 commit comments