fn remove_excess_segments(merged_data_segments: &mut Vec<DataSegment>) {
    if merged_data_segments.len() < MAX_DATA_SEGMENTS {
        return;
    }

    // We need to remove `excess` number of data segments.
    let excess = merged_data_segments.len() - MAX_DATA_SEGMENTS;

    #[derive(Clone, Copy, PartialEq, Eq)]
    struct GapIndex {
        gap: u32,
        // Use a `u32` instead of `usize` to fit `GapIndex` within a word on
        // 64-bit systems, using less memory.
        index: u32,
    }

    // Find the gaps between the start of one segment and the next (if they are
    // both in the same memory). We will merge the `excess` segments with the
    // smallest gaps together. Because they are the smallest gaps, this will
    // bloat the size of our data segment the least.
    let mut smallest_gaps = Vec::with_capacity(merged_data_segments.len() - 1);
    for (index, w) in merged_data_segments.windows(2).enumerate() {
        if w[0].memory_index != w[1].memory_index {
            continue;
        }
        let gap = w[0].gap(&w[1]);
        let index = u32::try_from(index).unwrap();
        smallest_gaps.push(GapIndex { gap, index });
    }
    smallest_gaps.sort_unstable_by_key(|g| g.gap);
    smallest_gaps.truncate(excess);

    // Now merge the chosen segments together in reverse index order so that
    // merging two segments doesn't mess up the index of the next segments we
    // will to merge.
    smallest_gaps.sort_unstable_by(|a, b| a.index.cmp(&b.index).reverse());
    for GapIndex { index, .. } in smallest_gaps {
        let index = usize::try_from(index).unwrap();
        let merged = merged_data_segments[index].merge(&merged_data_segments[index + 1]);
        merged_data_segments[index] = merged;

        // Okay to use `swap_remove` here because, even though it makes
        // `merged_data_segments` unsorted, the segments are still sorted within
        // the range `0..index` and future iterations will only operate within
        // that subregion because we are iterating over largest to smallest
        // indices.
        merged_data_segments.swap_remove(index + 1);
    }

    // Finally, sort the data segments again so that our output is
    // deterministic.
    merged_data_segments.sort_by_key(|s| (s.memory_index, s.offset));
}
/// Engines apply a limit on how many segments a module may contain, and Wizer
/// can run afoul of it. When that happens, we need to merge data segments
/// together until our number of data segments fits within the limit.
Engines apply a limit on how many segments a module may contain, and Wizer
can run afoul of it. When that happens, we need to merge data segments
together until our number of data segments fits within the limit.
Engines apply a limit on how many segments a module may contain and Wizer can run afoul of it . When that happens we need to merge data segments together until our number of data segments fits within the limit .
fn remove_excess_segments(merged_data_segments: &mut Vec<DataSegment>) {
    if merged_data_segments.len() < MAX_DATA_SEGMENTS {
        return;
    }
    // We need to remove `excess` number of data segments.
    let excess = merged_data_segments.len() - MAX_DATA_SEGMENTS;
    #[derive(Clone, Copy, PartialEq, Eq)]
    struct GapIndex {
        gap: u32,
        // Use a `u32` instead of `usize` to fit `GapIndex` within a word on
        // 64-bit systems, using less memory.
        index: u32,
    }
    // Find the gaps between the start of one segment and the next (if they are
    // both in the same memory). We will merge the `excess` segments with the
    // smallest gaps together. Because they are the smallest gaps, this will
    // bloat the size of our data segment the least.
    let mut smallest_gaps = Vec::with_capacity(merged_data_segments.len() - 1);
    for (index, w) in merged_data_segments.windows(2).enumerate() {
        if w[0].memory_index != w[1].memory_index {
            continue;
        }
        let gap = w[0].gap(&w[1]);
        let index = u32::try_from(index).unwrap();
        smallest_gaps.push(GapIndex { gap, index });
    }
    smallest_gaps.sort_unstable_by_key(|g| g.gap);
    smallest_gaps.truncate(excess);
    // Now merge the chosen segments together in reverse index order so that
    // merging two segments doesn't mess up the index of the next segments we
    // will to merge.
    smallest_gaps.sort_unstable_by(|a, b| a.index.cmp(&b.index).reverse());
    for GapIndex { index, .. } in smallest_gaps {
        let index = usize::try_from(index).unwrap();
        let merged = merged_data_segments[index].merge(&merged_data_segments[index + 1]);
        merged_data_segments[index] = merged;
        // Okay to use `swap_remove` here because, even though it makes
        // `merged_data_segments` unsorted, the segments are still sorted within
        // the range `0..index` and future iterations will only operate within
        // that subregion because we are iterating over largest to smallest
        // indices.
        merged_data_segments.swap_remove(index + 1);
    }
    // Finally, sort the data segments again so that our output is
    // deterministic.
    merged_data_segments.sort_by_key(|s| (s.memory_index, s.offset));
}
fn remove_excess_segments ( merged_data_segments : & mut Vec < DataSegment > ) { if merged_data_segments . len ( ) < MAX_DATA_SEGMENTS { return ; } // We need to remove `excess` number of data segments. let excess = merged_data_segments . len ( ) - MAX_DATA_SEGMENTS ; # [ derive ( Clone Copy PartialEq Eq ) ] struct GapIndex { gap : u32 , // Use a `u32` instead of `usize` to fit `GapIndex` within a word on // 64-bit systems, using less memory. index : u32 , } // Find the gaps between the start of one segment and the next (if they are // both in the same memory). We will merge the `excess` segments with the // smallest gaps together. Because they are the smallest gaps, this will // bloat the size of our data segment the least. let mut smallest_gaps = Vec :: with_capacity ( merged_data_segments . len ( ) - 1 ) ; for ( index , w ) in merged_data_segments . windows ( 2 ) . enumerate ( ) { if w [ 0 ] . memory_index != w [ 1 ] . memory_index { continue ; } let gap = w [ 0 ] . gap ( & w [ 1 ] ) ; let index = u32 :: try_from ( index ) . unwrap ( ) ; smallest_gaps . push ( GapIndex { gap , index } ) ; } smallest_gaps . sort_unstable_by_key ( | g | g . gap ) ; smallest_gaps . truncate ( excess ) ; // Now merge the chosen segments together in reverse index order so that // merging two segments doesn't mess up the index of the next segments we // will to merge. smallest_gaps . sort_unstable_by ( | a , b | a . index . cmp ( & b . index ) . reverse ( ) ) ; for GapIndex { index , .. } in smallest_gaps { let index = usize :: try_from ( index ) . unwrap ( ) ; let merged = merged_data_segments [ index ] . merge ( & merged_data_segments [ index + 1 ] ) ; merged_data_segments [ index ] = merged ; // Okay to use `swap_remove` here because, even though it makes // `merged_data_segments` unsorted, the segments are still sorted within // the range `0..index` and future iterations will only operate within // that subregion because we are iterating over largest to smallest // indices. merged_data_segments . swap_remove ( index + 1 ) ; } // Finally, sort the data segments again so that our output is // deterministic. merged_data_segments . sort_by_key ( | s | ( s . memory_index , s . offset ) ) ; }
Engines apply a limit on how many segments a module may contain, and Wizer
can run afoul of it.
Engines apply a limit on how many segments a module may contain and Wizer can run afoul of it .
merged_data_segments
&mut Vec<DataSegment>
merged_data_segments
&mut Vec<DataSegment>