Open amesgen opened 7 months ago
We do this sort of thing for bulk memory already. We do an extra validation pass over the Wasm and fail if we statically see any table.set
instruction or anything like that. We could extend this for reference types as well.
Adding support for doing these checks dynamically is a little more involved. I think we could do this by inserting calls to a new dynamic_fail_wizer_init
imported function, or something like that, before each forbidden instruction during the instrumentation phase. That function would always trap, making initialization fail if it was dynamically executed.
Could we perhaps check if there are any live references at the end of wizening? It seems like everything else wouldn't really matter, right?
If we limit this to extenrerf
s, I think that works, so long as we also record the initialized sizes of externref
tables (which would all be full of null elements if we enforce the proposed property). In fact, I don't think we need to even track the live externref
s since there won't be any: wasm can't create an externref
, only the host can, and we simply won't.
So basically, I think allowing support for extenref
s is fine because there will only ever be null externref
s. And we can avoid the table-size issue for now by keeping the existing bulk-memory validation that forbids table.grow
(or turn it into a dynamic check as described earlier (or just add support for growing externref
tables with null references)).
But funcref
s present more problems:
externref
s since we don't have hooks and they are also live for the entire store's lifetime.funcref
we don't have a way to inspect which function it isSee https://github.com/bytecodealliance/wizer/issues/29 for more ideas about full table support.
I have a WASM module that uses reference types, but the initialization function (some pure precomputation) doesn't use them. Currently, wizer categorically fails with
However, when I apply this patch
everything works fine, both initialization and later usage of the WASM module (including reference types).
Would it make sense to allow reference types a priori, and instead error when instructions related to reference types are encountered during initialization? I could take a stab at a PR if this makes sense.