Skip to content

Commit

Permalink
Preserve the function table during early gc passes
Browse files Browse the repository at this point in the history
Recent refactorings of wasm-bindgen have inserted multiple `gc` passes
executed by walrus. In these passes though the function table was being
removed a bit too aggressively because it's not exported by LLD and it's
only later that we realize we need to export it.

To handle this case we add synthetic and temporary exports of the
function table and these exports are removed just after the GC pass in
question.

Closes #1603
  • Loading branch information
alexcrichton committed Jun 18, 2019
1 parent 8d90655 commit c9ee88b
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions crates/cli-support/src/descriptors.rs
Expand Up @@ -40,7 +40,24 @@ pub fn execute(module: &mut Module) -> Result<WasmBindgenDescriptorsSectionId, E

// Delete all descriptor functions and imports from the module now that
// we've executed all of them.
//
// Note though that during this GC pass it's a bit aggressive in that it can
// delete the function table entirely. We don't actually know at this point
// whether we need the function table or not. The bindings generation may
// need to export the table so the JS glue can call functions in it, and
// that's only discovered during binding selection. For now we just add
// synthetic root exports for all tables in the module, and then we delete
// the exports just after GC. This should keep tables like the function
// table alive during GC all the way through to the bindings generation
// where we can either actually export it or gc it out since it's not used.
let mut exported_tables = Vec::new();
for table in module.tables.iter() {
exported_tables.push(module.exports.add("foo", table.id()));
}
walrus::passes::gc::run(module);
for export in exported_tables {
module.exports.delete(export);
}

Ok(module.customs.add(section))
}
Expand Down

0 comments on commit c9ee88b

Please sign in to comment.