bytecodealliance / wizer

The WebAssembly Pre-Initializer
Apache License 2.0
934 stars 55 forks source link

Add support for snapshotting tables #29

Open fitzgen opened 3 years ago

fitzgen commented 3 years ago

Right now there are two potential kinds of tables:

The latter are easy to support, since Wasm can't construct an externref, only receive it from the outside world. As long as we don't allow any externrefs into the Wasm during initialization, then all we have to do is record the initialized size of these tables.

funcref tables are a little harder. Wasm can create funcrefs via the ref.func instruction. So we need a way to figure out which function each wasmtime::FuncRef in a table we are snapshotting is (i.e. what is the local function index of the ith table element?). wasmtime doesn't expose anything like that. I have an idea, however:

The one problem is that local function index isn't quite enough in the face of module linking. Instead we will need both the instance "id" (whatever that this; DFS index?) as well as the local function index in that instance. More to think about w.r.t. module linking here...

fitzgen commented 3 years ago

The one problem is that local function index isn't quite enough in the face of module linking. Instead we will need both the instance "id" (whatever that this; DFS index?) as well as the local function index in that instance. More to think about w.r.t. module linking here...

We can flip our view of this problem to make it a lot easier: we don't need to know, for a given table, where all of its functions came from and how to get them in there. Because of the constraints that Wizer imposes on imports, we know that all the functions came from somewhere inside this module graph / instantiation tree. So each instance needs to ask for a given table that it has access to, which of these functions are from me? Then we save this info in the snapshot and emit them as element segments.

We can make this a little more efficient by associating a bitmap with each table of which functions we've already resolved, so we don't have to check every single function in the table for every instance that has access to that table. This would also let us catch errors where some future WASI proposal stuffed things into the function table, or if we supported initializing with arbitrary linkers: just assert that we checked off all bits in that bit map, meaning we've accounted for every function in the table.