Stream: general

Topic: Polyfilling a core wasm using `walrus`


view this post on Zulip James Mart (Jan 11 2024 at 17:08):

I see in walrus I can use replace_imported_func to polyfill some imports.

So my question is, is it possible for the InstrSeqBuilder to use an existing set of instructions from a loaded function? Feels like it should be possible but I'm not seeing any way to copy existing instructions from a compiled polyfill function :thinking:

view this post on Zulip James Mart (Jan 11 2024 at 19:54):

Looks like there was some discussion about this topic. CC @Victor Adossi - I guess there's still no straightforward way to do that then?

After trialing replace_(imported|exported)_func in WASI-Virt, it's clear that the ergonomics around the builder function need to be improved. FunctionBuilder (particularly FunctionBuilder::new()) i...

view this post on Zulip Victor Adossi (Jan 12 2024 at 08:32):

Sorry I'm not sure exactly how you'd do that, but what about dealing with the function object itself? You might be able to manipulate/replace at the function rather than the instruction level?

view this post on Zulip Victor Adossi (Jan 12 2024 at 08:35):

Also what about using instrs to copy and extract all the instructions for the function?

view this post on Zulip James Mart (Jan 15 2024 at 19:24):

what about dealing with the function object itself

I'm thinking I'd need to work at the instruction level so I can detect if there's a call or indirect call in the copied function that the function index gets corrected when the instruction is copied into the new module.

what about using instrs to copy and extract all the instructions for the function?

Oh, okay this looks promising. So if I'm understanding correctly I should be able to extract the instrs from a compiled function and check the type with something like if let walrus::ir::Instr::Call(call) = &instr { ... }... I'll give this a try!

view this post on Zulip Victor Adossi (Jan 16 2024 at 04:37):

You're right about the instructions -- if you need to inspect them to figure out the direct/indirect calls -- I thought you might have been just trying to stub stuff out/duplicate a function without peering inside it!

Excited to see where you land on the instrs usage! Not sure if it will work but :fingers_crossed:

view this post on Zulip akesling (Jan 16 2024 at 20:19):

@James Mart

What's your ultimate goal? I found myself needing to polyfill a bunch of WASI Snapshot Preview 1 imports (convoluted story) and the least painful solution I found was to write some tooling to swap in a home-rolled VFS implementation, etc.

My process is to include all of the polyfill functions as exports in the module (this lets, e.g., the module-internal memory allocator be dealt with at compile time instead of having to somehow be patched at rewrite or only allow non-allocating replacements) and then do a Walrus-based rewrite that replaces the imports with my exports.

Would it be helpful to you if I open sourced my rewriting tool? It's fairly general already, taking a mapping between function symbols to rewrite.

view this post on Zulip James Mart (Jan 16 2024 at 21:26):

@akesling I'm writing a cargo extension that can be used to build wasm modules that are deployed in a certain environment, and in order to run in this environment all the wasi imports must be polyfilled with some custom implementations.

If I'm understanding your design right, it sounds like you may have done something pretty close to what I'm doing. I'm currently compiling a polyfill wasm from rust, and then extracting the exports from that polyfill module (various wasi functions) and using them to replace all the wasi imports in the target module using walrus.

Would it be helpful to you if I open sourced my rewriting tool?

I mean, if you wouldn't mind, I'd happily take a look at your prior work and see if it suits my needs or helps expedite my efforts!


Last updated: Dec 23 2024 at 12:05 UTC