Add no_resolve to LoadArgs and wasm_runtime_resolve_symbols so one can
delay resolving of symbols.
This is useful for inspecting the module between loading and instantiating.
Now that WAMR supports multiple memory instances, this PR adds some APIs
to access them in a standard way.
This involves moving some existing utility functions out from the
`WASM_ENABLE_MULTI_MODULE` blocks they were nested in, but multi-memory
and multi-module seem independent as far as I can tell so I assume that's okay.
APIs added:
```C
wasm_runtime_lookup_memory
wasm_runtime_get_default_memory
wasm_runtime_get_memory
wasm_memory_get_cur_page_count
wasm_memory_get_max_page_count
wasm_memory_get_bytes_per_page
wasm_memory_get_shared
wasm_memory_get_base_address
wasm_memory_enlarge
```
Implement multi-memory for classic-interpreter. Support core spec (and bulk memory) opcodes now,
and will support atomic opcodes, and add multi-memory export APIs in the future.
PS: Multi-memory spec test patched a lot for linking test to adapt for multi-module implementation.
When AOT isn't enabled and the input is a wasm file, wasm_runtime_load doesn't
report error. Same when interpreter isn't enabled and the input is AOT file.
This PR makes wasm_runtime_load report error "magic header not detected" for
such situations.
There's probably a number of other places where the bh_leb_read could be used (e.g. aot loader)
but I'm making the change as small as possible. Further refactoring can be done later.
Check whether the indices overflow UINT32_MAX or not for:
- import function count + function count
- import global count + global count
- import tag count + tag count
This PR fixes the issue reported by Oss-fuzz test (#69920).
- Split the `aot_loader_resolve_function` into two functions to prevent
redundant module lookups and loads
- Access pre-associated module instances from `import_func_module_insts`,
avoiding unnecessary instance lookups and improving performance
The wasm loader is failing when multi-module support is on and the dependent
modules are not found; this enforces the AOT compiler integrations to prepare
dependent modules while it isn't necessary.
This PR allows allows missing imports in wasm loader and report error in wasm
instantiation instead, which enables the integrated AOT compiler to work as if
the multi-module support isn't turned on.
Consider the following wasm module:
```wast
(module
(func (export "foo")
i32.const 0x104
i32.const 0x12345678
i32.store
)
(memory 1 1)
)
```
While the address (0x104) is perfectly aligned for i32.store,
as our aot compiler uses 1-byte alignment for load/store LLVM
IR instructions, it often produces inefficient machine code,
especially for alignment-sensitive targets.
For example, the above "foo" function is compiled into the
following xtensa machine code.
```
0000002c <aot_func_internal#0>:
2c: 004136 entry a1, 32
2f: 07a182 movi a8, 0x107
32: 828a add.n a8, a2, a8
34: 291c movi.n a9, 18
36: 004892 s8i a9, a8, 0
39: 06a182 movi a8, 0x106
3c: 828a add.n a8, a2, a8
3e: ffff91 l32r a9, 3c <aot_func_internal#0+0x10> (ff91828a <aot_func_internal#0+0xff91825e>)
3e: R_XTENSA_SLOT0_OP .literal+0x8
41: 004892 s8i a9, a8, 0
44: 05a182 movi a8, 0x105
47: 828a add.n a8, a2, a8
49: ffff91 l32r a9, 48 <aot_func_internal#0+0x1c> (ffff9182 <aot_func_internal#0+0xffff9156>)
49: R_XTENSA_SLOT0_OP .literal+0xc
4c: 41a890 srli a10, a9, 8
4f: 0048a2 s8i a10, a8, 0
52: 04a182 movi a8, 0x104
55: 828a add.n a8, a2, a8
57: 004892 s8i a9, a8, 0
5a: f01d retw.n
```
Note that the each four bytes are stored separately using
one-byte-store instruction, s8i.
This commit tries to use larger alignments for load/store LLVM IR
instructions when possible. with this commit, the above example is
compiled into the following machine code, which seems more reasonable.
```
0000002c <aot_func_internal#0>:
2c: 004136 entry a1, 32
2f: ffff81 l32r a8, 2c <aot_func_internal#0> (81004136 <aot_func_internal#0+0x8100410a>)
2f: R_XTENSA_SLOT0_OP .literal+0x8
32: 416282 s32i a8, a2, 0x104
35: f01d retw.n
```
Note: this doesn't work well for --xip because aot_load_const_from_table()
hides the constness of the value. Maybe we need our own mechanism to
propagate the constness and the value.
- All files under *core/iwasm/libraries/wasi-nn* are compiled as shared libraries
- *wasi-nn.c* is shared between backends
- Every backend has a separated shared library
- If wasi-nn feature is enabled, iwasm will depend on shared library libiwasm.so
instead of linking static library libvmlib.a
- possible integer overflow in adjust_table_max_size:
unsigned integer overflow: 2684354559 * 2 cannot be represented in type 'uint32'
- limit max memory size in wasm_runtime_malloc
- add more checks in aot loader
- adjust compilation options
Support to get `wasm_memory_type_t memory_type` from API
`wasm_runtime_get_import_type` and `wasm_runtime_get_export_type`,
and then get shared flag, initial page cout, maximum page count
from the memory_type:
```C
bool
wasm_memory_type_get_shared(const wasm_memory_type_t memory_type);
uint32_t
wasm_memory_type_get_init_page_count(const wasm_memory_type_t memory_type);
uint32_t
wasm_memory_type_get_max_page_count(const wasm_memory_type_t memory_type);
```
Add flag `LoadArgs.clone_wasm_binary` to control whether to clone the wasm/aot
binary in wasm-c-api module. If false, API `wasm_module_new_ex` won't clone the
binary, which may reduce the footprint.
Add flag `LoadArgs.wasm_binary_freeable` to control whether the wasm/aot binary
may be freed after instantiation for wamr API `wasm_runtime_load_ex`, if yes, then
for some running modes, the wasm/aot module doesn't refer to the input binary
again so developer can free it after instantiation to reduce the footprint.
And add API `wasm_module_is_underlying_binary_freeable` and
`wasm_runtime_is_underlying_binary_freeable` to check whether the input binary
can be freed after instantiation for wasm-c-api and wamr api.
And add sample to illustrate it.
Support getting global type from `wasm_runtime_get_import_type` and
`wasm_runtime_get_export_type`, and add two APIs:
```C
wasm_valkind_t
wasm_global_type_get_valkind(const wasm_global_type_t global_type);
bool
wasm_global_type_get_mutable(const wasm_global_type_t global_type);
```