@@ -387,28 +387,48 @@ impl dyn InstanceAllocator + '_ {
387387 self . increment_core_instance_count ( ) ?;
388388
389389 let num_defined_memories = module. num_defined_memories ( ) ;
390- let mut memories = PrimaryMap :: with_capacity ( num_defined_memories) ;
391-
392390 let num_defined_tables = module. num_defined_tables ( ) ;
393- let mut tables = PrimaryMap :: with_capacity ( num_defined_tables) ;
394-
395- match ( || {
396- self . allocate_memories ( & mut request, & mut memories) ?;
397- self . allocate_tables ( & mut request, & mut tables) ?;
398- Ok ( ( ) )
399- } ) ( ) {
400- // SAFETY: memories/tables were just allocated from the store within
401- // `request` and this function's own contract requires that the
402- // imports are valid.
403- Ok ( _) => unsafe { Ok ( Instance :: new ( request, memories, tables, & module. memories ) ) } ,
404- Err ( e) => {
391+
392+ let mut guard = DeallocateOnDrop {
393+ run_deallocate : true ,
394+ memories : PrimaryMap :: with_capacity ( num_defined_memories) ,
395+ tables : PrimaryMap :: with_capacity ( num_defined_tables) ,
396+ allocator : self ,
397+ } ;
398+
399+ self . allocate_memories ( & mut request, & mut guard. memories ) ?;
400+ self . allocate_tables ( & mut request, & mut guard. tables ) ?;
401+ guard. run_deallocate = false ;
402+ // SAFETY: memories/tables were just allocated from the store within
403+ // `request` and this function's own contract requires that the
404+ // imports are valid.
405+ return unsafe {
406+ Ok ( Instance :: new (
407+ request,
408+ mem:: take ( & mut guard. memories ) ,
409+ mem:: take ( & mut guard. tables ) ,
410+ & module. memories ,
411+ ) )
412+ } ;
413+
414+ struct DeallocateOnDrop < ' a > {
415+ run_deallocate : bool ,
416+ memories : PrimaryMap < DefinedMemoryIndex , ( MemoryAllocationIndex , Memory ) > ,
417+ tables : PrimaryMap < DefinedTableIndex , ( TableAllocationIndex , Table ) > ,
418+ allocator : & ' a ( dyn InstanceAllocator + ' a ) ,
419+ }
420+
421+ impl Drop for DeallocateOnDrop < ' _ > {
422+ fn drop ( & mut self ) {
423+ if !self . run_deallocate {
424+ return ;
425+ }
405426 // SAFETY: these were previously allocated by this allocator
406427 unsafe {
407- self . deallocate_memories ( & mut memories) ;
408- self . deallocate_tables ( & mut tables) ;
428+ self . allocator . deallocate_memories ( & mut self . memories ) ;
429+ self . allocator . deallocate_tables ( & mut self . tables ) ;
409430 }
410- self . decrement_core_instance_count ( ) ;
411- Err ( e)
431+ self . allocator . decrement_core_instance_count ( ) ;
412432 }
413433 }
414434 }
0 commit comments