Skip to content

fix: handle duplicate func names in Wasm's name section - #1357

Open
mooori wants to merge 2 commits into
nextfrom
mooori/duplicate-wasm-fn-name-2
Open

fix: handle duplicate func names in Wasm's name section#1357
mooori wants to merge 2 commits into
nextfrom
mooori/duplicate-wasm-fn-name-2

Conversation

@mooori

@mooori mooori commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Closes #1341
Closes #1360

Both are related to function names and fixes for each must work well in combination.

Summary

  • Creates unique linkage names for functions whose name is duplicated in the Wasm name section. The linkage names are tracked separately to not modify the Wasm name section.
  • Makes export name the linkage for exported functions. Previously the export name was not taken into account for linkage names.
  • Debug info: Functions whose name is not unique in Wasm's name section are left out of the name map. This forces them to be resolved via (unique) low_pc instead of (non-unique) source_name.

Related follow-up work

Note on testing

Duplicate name-section names are easy to reproduce with miden-field, see #1341. Without miden-field it's tricky. Since miden-field may change, I avoided it in the test and went for synthetic DWARF instead.

@mooori
mooori force-pushed the mooori/duplicate-wasm-fn-name-2 branch from b8f5d6a to f6fd84b Compare August 27, 2026 22:47
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Miden examples benchmark

Candidate 5f557c742c06 compared with next 7d0ec654687d. Lower is better.

example VM cycles (vs next) MAST size (vs next)
auth-component-no-auth n/a 6,823B (~0%)
auth-component-rpo-falcon512 n/a 13,177B (~0%)
basic-wallet n/a 8,505B (~0%)
basic-wallet-tx-script n/a 13,784B (~0%)
collatz 5,264 (~0%) 2,385B (~0%)
counter-contract n/a 13,562B (~0%)
counter-note n/a 3,685B (~0%)
fibonacci 870 (~0%) 3,203B (~0%)
is-prime 2,332,732 (~0%) 5,848B (~0%)
p2id-note n/a 21,763B (~0%)
p2id-tx-script n/a 12,468B (~0%)
p2ide-note n/a 16,402B (~0%)
storage-example n/a 15,677B (~0%)

SVG flamegraphs and compiled packages are attached to the workflow run.

@mooori
mooori force-pushed the mooori/duplicate-wasm-fn-name-2 branch from f6fd84b to e20b119 Compare August 28, 2026 10:53
@mooori
mooori marked this pull request as ready for review August 28, 2026 11:42
@mooori
mooori requested review from bitwalker and greenhat August 28, 2026 11:42
@mooori

mooori commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

The new plan is to address #1360 in this PR here as well, to ensure handling of export names and name-section names works well together. So reverting to draft.

@mooori
mooori force-pushed the mooori/duplicate-wasm-fn-name-2 branch from e20b119 to 25c7d78 Compare September 4, 2026 20:08
@mooori

mooori commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

This has been reworked to address both #1341 and #1360, as discussed, so it's ready for review. A fix of #1341 is required to make projects using miden-field compile with panic=abort.

cc @bitwalker, @greenhat

@mooori
mooori marked this pull request as ready for review September 4, 2026 22:48

@bitwalker bitwalker left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but there are two relatively significant issues that need to be addressed before this can be merged, see comments for details

};
let export_sym = Symbol::intern(export_name.as_str());

if exported_as.insert(*func_idx, export_sym).is_some() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please preserve multiple export aliases for a function instead of rejecting them. This occurs in ordinary optimized Rust: compiling two exported functions foo and bar that both return 42 with rustc -C opt-level=3 --target wasm32-unknown-unknown produces two exports referring to function index 0. This check rejects that output. It also regresses component startup targets with multiple export aliases: I verified that a component whose startup target is exported as both aliased-start and other-start translates on the base commit but fails here. Choose a primary linkage name and preserve the additional exports through aliases or forwarding functions, with a regression test for this case.

let mut global_names: FxHashSet<Symbol> = FxHashSet::default();
for global_idx in self.globals.keys() {
let name = self.global_name(global_idx);
if export_names.contains(&name) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please disambiguate the internal global linkage name instead of rejecting the public function export. For example, this valid module translates on the base commit but fails here:

(module $counter_module
  (global $counter (mut i32) (i32.const 0))
  (func $read_counter (export "counter") (result i32)
    global.get $counter))

The global's name-section name and the function's export name are allowed to coincide; the private global's source name should not constrain the public interface. Extend the source/linkage distinction to globals so the public export keeps its name and references to the renamed global remain consistent, and cover this with a regression test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following our sync on Monday, my understanding is that for now we don't expect Wasm producers to generate collisions between global and export names. The code in this PR already emits a diagnostic in that case and as discussed I've opened #1390 if we need this later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wasm frontend ignores function export names Frontend assumes names from Wasm's name section are unique

2 participants