-
Notifications
You must be signed in to change notification settings - Fork 289
Support componentizing modules that have duplicate imports. #2145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support componentizing modules that have duplicate imports. #2145
Conversation
0e0b765
to
4feaa10
Compare
To confirm on this: is it ok to lose all debuginfo for these modules? The downside of rewriting the module is that it changes all the binary offsets of instructions in a module which causes debuginfo to become invalidated. Does TinyGo have DWARF debugging information that would be lost? If debuginfo would be lost, that's where in #2063 I was thinking that the imports would all be preserved (as to not tamper with the function index space) and then the instantiation would provide the same function multiple times to the module. If debuginfo is not lost, then this strategy is probably ok too. I'd prefer if it were off-by-default though due to the consequences of losing debuginfo and rewriting the binary, so mind adding a CLI flag along the lines of |
In an ideal world, I too would prefer that the import-preserving strategy had worked, but it gradually became a real rat's nest. I had the imports renaming and was getting close to having the requisite aliases created and reimported into a go-between module that would handle the field-level renamings. But at that point I looked ahead and saw that not only would the types of imports need to be changed ( So, feeling discouraged, I took a day to spike out the rewriting approach to weigh its complexity, and, what-do-you-know, it turned out simple, short, and centralized. I had avoided this tack at first for fear of a maintenance burden as constructs get added to wasm, but it turns out The casualty, as you point out, is custom sections that refer to byte offsets. @sunfishcode's thinking was to be extremely conservative, stripping any custom sections except ones known not to contain byte offsets: specifically, producers and target features. That way, we at least don't start spitting out (potentially non-obvious) garbage during a debug session. I think it's totally reasonable to add a flag to avoid surprise, however. (To answer your question, it looks like TinyGo does emit debug info.) |
I agree yeah the I'm a bit surprised that the implementation became pretty complicated, but I also didn't read the first few commits in fine detail so I could very well be missing things too. My hope would be that Then the |
You're not alone! :-) You're welcome to peruse my abandoned branch, though it's messy and has a few course reversals. The commit messages are a decent read, but the code is best read all at once. As you can see, I tried to do most of my intervention in Since you point to |
Ah yeah I think the main difference is that the structure of ``wasm
which would then do "duplicate work" for each import to determine that they both get wired up to the adapter's |
Tracing through this now. So far, what I've (re-)learned is that |
2d5c417
to
1b89d9b
Compare
@alexcrichton Okay, I think we're ready to rock here! I gave the non-rewriting approach another Ideal Engineering Day and kicked over several obstacles but ultimately ran out the clock. (Here's where I got, in case you're curious.) This version, however, works great and is ready for your review. Thanks so much for all your help getting this far! |
When the `--deduplicate-imports` option is passed to `wasm-tools component new`, we rewrite the input module to compact out the duplicates. This allows tinyGo's output to be wrapped in a component. Closes bytecodealliance#2063. Using `Reencode` takes the maintenance pressure I feared off the deduplication engine; it won't have to chase future changes to the wasm format. Instead, `Reencode` should adapt to them and continue calling `function_index()` in all the right places.
1b89d9b
to
549e0f3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks reasonable to me, just some minor comments below.
FWIW I think one thing missing on your other branch is we'll still want to rewrite the module, but instead only the import section instead of the entire module. This PR drops imports, where what I was thinking was that we'd rename imports in-place. That I think would integrate much well with the rest of the system, basically "pretend the user specified some other module". Again though I'm ok if you prefer this approach, but wanted to leave this thought nonetheless.
;; RUN: component new % -o component.wasm --adapt tests/cli/wasi_snapshot_preview1.wasm --deduplicate-imports | ||
(module | ||
;; The second of these imports gets stripped out, letting `component new` succeed. | ||
(func $i (import "wasi_snapshot_preview1" "proc_exit") (param i32)) | ||
(func $j (import "wasi_snapshot_preview1" "proc_exit") (param i32)) | ||
(func (export "exported_func") | ||
i32.const 42 | ||
call $i | ||
i32.const 42 | ||
call $j | ||
) | ||
(memory (;0;) 1) | ||
(export "memory" (memory 0)) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this test might be better suited for crates/wit-component/tests/components/*
due to the multi-file nature of this test. That'll also avoid the need to check in a wasi_snapshot_preview1.wasm
binary since there are already other tests with textual forms of adapters in that directory too. Additionally that'll avoid the need to have -o component.wasm
which isn't a checked-in test expectation either, the test expectation will show up as text.
The main thing is you'll have to add new plumbing for --deduplicate-imports
in that test suite since right now all the component tests are run with default settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, it's fun and funny that adapt-wasi-snapshot-preview1.wat
, over in wit-component, chose proc_exit
as a "hello world" routine, just as I did.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alrighty, how does that look? I did pretty much the simplest thing that could possibly work to signal that the harness should deduplicate. (Since we got this far without needing these sorts of options, I don't expect a mad gallop of more. And if there is a need that exceeds this syntax, it's easy to change the spelling of this one test.)
Thanks, Alex! |
This commit is a refinement to the support added in bytecodealliance#2145 to support duplicate imports by default in wasm-tools, namely by avoiding changing any binary offsets in a module except for the import section. This implements a strategy of renaming imports in the module that goes into a component to be unique. Classification of what an import maps to is then ensured to use the original names, not the current names, in the module.
…2187) * Support duplicate imports by default in `wasm-tools component new` This commit is a refinement to the support added in #2145 to support duplicate imports by default in wasm-tools, namely by avoiding changing any binary offsets in a module except for the import section. This implements a strategy of renaming imports in the module that goes into a component to be unique. Classification of what an import maps to is then ensured to use the original names, not the current names, in the module. * Fix clippy lints * Review comments
When the
--deduplicate-imports
option is passed towasm-tools component new
, we rewrite the input module to compact out the duplicates. This allows tinyGo's output to be wrapped in a component. Closes #2063.Using
Reencode
takes the maintenance pressure I feared off the deduplication engine; it won't have to chase future changes to the wasm format. Instead,Reencode
should adapt to them and continue callingfunction_index()
in all the right places.Suggestions on a better place to put wasi_snapshot_preview1.wasm adapter are welcome.