Skip to content

Commit

Permalink
Add sorted_iter_mut for NonstandardWitSection.adapters for determinism
Browse files Browse the repository at this point in the history
In the `externref` code, we call `export_xform` while iterating
over `adapters` with `iter_mut`. Calling `export_xform` can result
in shims, with the id depending on the order in which we iterate
over the exports.

To make the final .wasm output deterministic, I've changed this to
use a new `sorted_iter_mut` method (based on `sorted_iter`).
  • Loading branch information
Aaron1011 committed Feb 22, 2024
1 parent 00ab174 commit 7078c80
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 3 deletions.
4 changes: 2 additions & 2 deletions crates/cli-support/src/externref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn process(module: &mut Module) -> Result<()> {

// Transform all exported functions in the module, using the bindings listed
// for each exported function.
for (id, adapter) in section.adapters.iter_mut() {
for (id, adapter) in crate::sorted_iter_mut(&mut section.adapters) {
let instructions = match &mut adapter.kind {
AdapterKind::Local { instructions } => instructions,
AdapterKind::Import { .. } => continue,
Expand Down Expand Up @@ -77,7 +77,7 @@ pub fn process(module: &mut Module) -> Result<()> {
// Additionally we may need to update some adapter instructions other than
// those found for the externref pass. These are some general "fringe support"
// things necessary to get absolutely everything working.
for (_, adapter) in section.adapters.iter_mut() {
for (_, adapter) in crate::sorted_iter_mut(&mut section.adapters) {
let instrs = match &mut adapter.kind {
AdapterKind::Local { instructions } => instructions,
AdapterKind::Import { .. } => continue,
Expand Down
10 changes: 10 additions & 0 deletions crates/cli-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,3 +785,13 @@ where
pairs.sort_by_key(|(k, _)| *k);
pairs.into_iter()
}

/// Like `sorted_iter`, but produces mutable references to the values
fn sorted_iter_mut<K, V>(map: &mut HashMap<K, V>) -> impl Iterator<Item = (&K, &mut V)>
where
K: Ord,
{
let mut pairs = map.iter_mut().collect::<Vec<_>>();
pairs.sort_by_key(|(k, _)| *k);
pairs.into_iter()
}
2 changes: 1 addition & 1 deletion crates/cli-support/src/multivalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn run(module: &mut Module) -> Result<(), Error> {
let mut to_xform = Vec::new();
let mut slots = Vec::new();

for (_, adapter) in adapters.adapters.iter_mut() {
for (_, adapter) in crate::sorted_iter_mut(&mut adapters.adapters) {
extract_xform(module, adapter, &mut to_xform, &mut slots);
}
if to_xform.is_empty() {
Expand Down

0 comments on commit 7078c80

Please sign in to comment.