bytecodealliance / wasm-micro-runtime

WebAssembly Micro Runtime (WAMR)
Apache License 2.0
4.93k stars 624 forks source link

[RFC] Support instantiation linking #3807

Open lum1n0us opened 1 month ago

lum1n0us commented 1 month ago

Instantiation linking is a necessary method for processing imports (such as functions, globals, tables, and memory) of a Wasm module with given external values. Please refer to Spec. for more details.

loading linking(MULTI_MODULE) instantiation linking
when to process during loading during instantiation
how to give what is needed by module(by runtime) by module,by host,(by runtime)
which objects are allowed function,global function,global,memory,table

It is different from the current method of loading linking, which is made possible by WAMR_BUILD_MULTI_MODULE.

Loading linking copies the way ld-linux works. It looks for a needed Wasm file in specified paths using a module name, and it looks for needed external values within the Wasm file using a field name. It then connects multiple Wasm files at the module level. As a result, every instance of one module will be linked in the exact same way. Later on, a Wasm module and its related modules will all be instantiated by the Runtime. The Runtime will select the needed items from the dependent module instances and then supply them as imports, sorted by type.

Instantiation linking, on the other hand, requires users to provide a list of external values. This list should match the types of imports a Wasm module needs. The advantage of instantiation linking is that it does not require actual Wasm modules like loading linking does. Users can gather the list of external values from Wasm modules, from instances(such as function instances, global instances, memory instances and table instances) created by the host, and from dummy Wasm instances.

Instantiation linking is more adaptable than loading linking. Because of this, it can be included within loading linking. In some ways, we could say that loading linking = dependencies loader + dependencies instantiation + instantiation linking. As a result, loading linking can be reworked using instantiation linking APIs.

necessary APIs

We must ensure that all the following functions are fully supported and align with the Spec. definitions in both wasm_c_api.h and wasm_export.h, whether through new or existing APIs.

To be continued...

may affected

default linking policy

Clearly, loading linking can at least make use of the new instantiation linking APIs. However, we will keep it as is and separate it within the WAMR_BUILD_MULTI_MODULE controlled blocks. The tasks to come include reworking loading linking and creating a new linking layer.

Since instantiation linking is defined by Spec., it should always be an active feature by default. We must acknowledge that users may supply their own versions for some of the Wasm module import requirements and rely on the Runtime's built-in versions for the rest.

Due to the above line, the original WAMR_BUILD_MULTI_MODULE will need to have its scope expanded to encompass all content related to loading linking. It may also be necessary to rename it to WAMR_BUILD_LOADING_LINKING.

an import list

The Runtime should connect built-in functions (registered native functions) and built-in globals (when WASM_ENABLE_LIBC_BUILTIN is on) with imports in the instantiation stage. If we strictly follow the Spec., appropriate registered native functions should be part of the list of external values given when a Wasm module is initiated. However, this could result in a very long list that may not be user-friendly for API users in certain situations, such as when WASM_ENABLE_LIBC_WASI is on. Therefore, we might not insist that the list of external values completely matches the content of a Wasm module's import section. For any missing parts, the Runtime could provide the registered native functions. Another approach is to offer APIs that assist the host in creating a complete list of imports, keeping the instantiation process as straightforward as possible. The new APIs would generate the required imports using the registered native functions and/or host functions provided by the user through arguments.

host creation

It requires to create WASMFunctionInstance, WASMGlobalInstance, WASMMemoryInstance, and WASMTableInstance directly instead of instantiating from related Wasm module section content.

The Runtime must be able to process and manage creations made by users. Typically, this means that all necessary fields for execution should be populated with appropriate values.

Reusing the current xxx_instantiate() in wasm_runtime.c to create a WASMXXXInstance appears to be feasible. Be sure that an XXXModuleInstance is not a required argument.

instances of a spawned thread

Both LIB_WASI_THREADS and THREAD_MGR share a memory model. Every spawned thread reuses its parent's WASMMemoryInstance(?WASMFunctionInstance, WASMGlobalInstance, WASMTableInstance). We can inherit WASMMemoryInstance from parents

To be continued...

### Tasks
- [ ] Identify the types of imports and exports of a Wasm module.
- [ ] Retrieve the export values from a Wasm instance.
- [ ] Use the given external values when instantiating a Wasm module.
- [ ] Create instances of functions, globals, tables, and memories from the host.
- [ ] During the loading phase, do not resolve import items.
- [ ] In the instantiation phase, resolve import items. Utilize wasm_native symbols and built-in libc symbols to resolve import items not provided by the user.
- [ ] reconsider #3790
- [ ] Create an external value list for *spectest* requirement.
- [ ] Create an external value list for *wasi-test* requirement
- [ ] Support to grow memory from host
- [ ] Support to grow table from host
- [ ] refactor `wasm_instance_new_xxx()` in wasm_c_api
lum1n0us commented 2 weeks ago

https://github.com/bytecodealliance/wasm-micro-runtime/pull/3845