mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-11 12:11:14 +00:00
Merge pull request #3511 from bytecodealliance/main
Merge branch main into dev/checkpoint_and_restore
This commit is contained in:
commit
ac308c4fa9
|
@ -19,6 +19,7 @@ on:
|
|||
- "samples/**"
|
||||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "tests/unit/**"
|
||||
- "wamr-compiler/**"
|
||||
- "test-tools/wamr-ide/**"
|
||||
# will be triggered on push events
|
||||
|
@ -36,6 +37,7 @@ on:
|
|||
- "samples/**"
|
||||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "tests/unit/**"
|
||||
- "wamr-compiler/**"
|
||||
- "test-tools/wamr-ide/**"
|
||||
# allow to be triggered manually
|
||||
|
@ -272,10 +274,73 @@ jobs:
|
|||
cmake --build . --config Release --parallel 4
|
||||
working-directory: product-mini/platforms/${{ matrix.platform }}
|
||||
|
||||
build_unit_tests:
|
||||
needs:
|
||||
[
|
||||
build_llvm_libraries_on_ubuntu_2204,
|
||||
build_wamrc
|
||||
]
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04]
|
||||
wasi_sdk_release:
|
||||
[
|
||||
"https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz",
|
||||
]
|
||||
wabt_release:
|
||||
[
|
||||
"https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz",
|
||||
]
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get LLVM libraries
|
||||
id: retrieve_llvm_libs
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
./core/deps/llvm/build/bin
|
||||
./core/deps/llvm/build/include
|
||||
./core/deps/llvm/build/lib
|
||||
./core/deps/llvm/build/libexec
|
||||
./core/deps/llvm/build/share
|
||||
key: ${{ matrix.llvm_cache_key }}
|
||||
|
||||
- name: Quit if cache miss
|
||||
if: (steps.retrieve_llvm_libs.outputs.cache-hit != 'true')
|
||||
run: echo "::error::can not get prebuilt llvm libraries" && exit 1
|
||||
|
||||
- name: download and install wasi-sdk
|
||||
run: |
|
||||
cd /opt
|
||||
sudo wget ${{ matrix.wasi_sdk_release }}
|
||||
sudo tar -xzf wasi-sdk-*.tar.gz
|
||||
sudo ln -sf wasi-sdk-20.0 wasi-sdk
|
||||
|
||||
- name: download and install wabt
|
||||
run: |
|
||||
cd /opt
|
||||
sudo wget ${{ matrix.wabt_release }}
|
||||
sudo tar -xzf wabt-1.0.31-*.tar.gz
|
||||
sudo mv wabt-1.0.31 wabt
|
||||
|
||||
- name: Build wamrc
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
cmake --build . --config Release --parallel 4
|
||||
working-directory: wamr-compiler
|
||||
|
||||
- name: Build and run unit tests
|
||||
run: |
|
||||
mkdir build-unittests && cd build-unittests
|
||||
cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }}
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
cmake --build . --config Release --parallel 4
|
||||
ctest
|
||||
working-directory: tests/unit
|
||||
|
|
4
.github/workflows/compilation_on_nuttx.yml
vendored
4
.github/workflows/compilation_on_nuttx.yml
vendored
|
@ -85,14 +85,14 @@ jobs:
|
|||
- name: Checkout NuttX
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: apache/incubator-nuttx
|
||||
repository: apache/nuttx
|
||||
ref: releases/12.4
|
||||
path: nuttx
|
||||
|
||||
- name: Checkout NuttX Apps
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: apache/incubator-nuttx-apps
|
||||
repository: apache/nuttx-apps
|
||||
ref: releases/12.4
|
||||
path: apps
|
||||
|
||||
|
|
4
.github/workflows/spec_test_on_nuttx.yml
vendored
4
.github/workflows/spec_test_on_nuttx.yml
vendored
|
@ -112,14 +112,14 @@ jobs:
|
|||
- name: Checkout NuttX
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: apache/incubator-nuttx
|
||||
repository: apache/nuttx
|
||||
ref: releases/12.4
|
||||
path: nuttx
|
||||
|
||||
- name: Checkout NuttX Apps
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: apache/incubator-nuttx-apps
|
||||
repository: apache/nuttx-apps
|
||||
ref: releases/12.4
|
||||
path: apps
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
|
|||
| uvwasi | unspecified | v0.0.12 | https://github.com/nodejs/uvwasi | |
|
||||
| asmjit | unspecified | unspecified | https://github.com/asmjit/asmjit | |
|
||||
| zydis | unspecified | e14a07895136182a5b53e181eec3b1c6e0b434de | https://github.com/zyantific/zydis | |
|
||||
| NuttX ELF headers | 72313301e23f9c2de969fb64b9a0f67bb4c284df | 10.3.0 | https://github.com/apache/incubator-nuttx | |
|
||||
| NuttX ELF headers | 72313301e23f9c2de969fb64b9a0f67bb4c284df | 10.3.0 | https://github.com/apache/nuttx | |
|
||||
| Dhrystone | 2.1 | 2.1 | https://fossies.org/linux/privat/old/ | |
|
||||
|
||||
## Licenses
|
||||
|
|
|
@ -1,3 +1,101 @@
|
|||
## WAMR-2.1.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
### New Features
|
||||
- Add wasm_export.h APIs to expose memory type (#3496)
|
||||
- Add api to get export global instance (#3452)
|
||||
- Add wasm-mutator-fuzz test (#3420)
|
||||
- Implement Memory64 support for AOT (#3362)
|
||||
- Add wasm module global type information APIs (#3406)
|
||||
- Add aot binary analysis tool aot-analyzer (#3379)
|
||||
- Expose API to get import/export function's param/result valkind (#3363)
|
||||
- Add WASI support for esp-idf platform (#3348)
|
||||
|
||||
### Bug Fixes
|
||||
- Fix posix build when libc wasi is disabled and debug interp is enabled (#3503)
|
||||
- Fix wasm_mini_loader.c build when jit or multi-module is enabled (#3502)
|
||||
- Fix wasm loader check data segment count (#3492)
|
||||
- Fix loader parse block type and calculate dynamic offset for loop args (#3482)
|
||||
- Fix memory64 handling find_block_addr and execute_main (#3480)
|
||||
- Fix two issues to make fuzzing test quit earlier (#3471)
|
||||
- Fix test-wamr-ide CI failure (#3485)
|
||||
- NuttX: Fix a dbus-related crash on esp32s3 (#3470)
|
||||
- Clone data segments when specified with load args (#3463)
|
||||
- Fix codeql compilation error (#3461)
|
||||
- Fix several typos and fix bh_log calculate mills (#3441)
|
||||
- ssp_config.h: Fix ifdef for android random api (#3444)
|
||||
- libc-wasi: Fix a locking botch (#3437)
|
||||
- Fix fast interp RECOVER_BR_INFO and local set/tee (#3434)
|
||||
- aot compiler: Fix a type mismatch in compile_op_float_min_max (#3423)
|
||||
- Correct Exception Handling tag type when GC is enabled (#3413)
|
||||
- wasm loader: Fix handling if block without op else (#3404)
|
||||
- ref-types: Correct default value for function local variables (#3397)
|
||||
- aot compiler: Fix the length type passed to aot_memmove/aot_memset (#3378)
|
||||
- Fix loader and mini-loader select potiential error (#3374)
|
||||
- Fix aot debugger compilation error on windows (#3370)
|
||||
- A few native stack detection fixes for macOS/arm64 (#3368)
|
||||
- Fix ESP32-S3 compiling error (#3359)
|
||||
- Fix a few native stack address calculations (#3351)
|
||||
|
||||
### Enhancements
|
||||
- Modify logging for windows exception handler and remove unused function (#3489)
|
||||
- posix iwasm: Make the timeout logic a bit more robust (#3478)
|
||||
- libc-builtin: Enhance buffered print for printf_wrapper (#3460)
|
||||
- Enhance GC const initializer expression to support nested struct/array new (#3447)
|
||||
- wasi: Tweak the configuration for nuttx and explain why (#3451)
|
||||
- NuttX: Replace esp32s3 bits with the OS-provided APIs (#3439)
|
||||
- Allow not copying the wasm binary in wasm-c-api and not referring to the binary in wasm/aot loader (#3389)
|
||||
- aot: Make precheck functions use short-call for xtensa (#3418)
|
||||
- Add wasm_runtime_detect_native_stack_overflow_size (#3355)
|
||||
- Enhance wasm loader checks for opcode br_table (#3352)
|
||||
|
||||
### Others
|
||||
- Bump requests from 2.32.2 to 2.32.3 in /build-scripts (#3494)
|
||||
- Enable building static library on Android platform (#3488)
|
||||
- wasm-mutator-fuzz: Generate more kinds of corpus (#3487)
|
||||
- Correct nuttx repo names (#3484)
|
||||
- Bump requests from 2.31.0 to 2.32.2 in /build-scripts (#3474)
|
||||
- wasm-mutator-fuzz: Adapt to oss-fuzz compilation (#3464)
|
||||
- Add regression tests of BA issue cases (#3462)
|
||||
- Add malformed test cases (#3459)
|
||||
- NuttX: Rename a few recently-added nuttx options (#3449)
|
||||
- wamr-test-suites: Enable AOT multi-module spec tests (#3450)
|
||||
- Remove install_wasi_sdk from workload preparation script (#3445)
|
||||
- Add cmake static/shared library build settings (#3443)
|
||||
- Update spec test to latest commit (#3293)
|
||||
- Fix typo of WAMR_CONFIGUABLE_BOUNDS_CHECKS (#3424)
|
||||
- ci/coding_guidelines_check.py: Allow some well-known file names to contain '-' (#3428)
|
||||
- product-mini/platforms/posix/main.c: Adapt to WASM_MEM_DUAL_BUS_MIRROR (#3427)
|
||||
- Add comments to global type function declarations (#3431)
|
||||
- nuttx/esp32s3: Apply ibus/dbus adjustment to internal ram 1 as well (#3421)
|
||||
- Change WASM_ANYREF to WASM_EXTERNREF (#3426)
|
||||
- Remove unused macros which were moved to wamr-app-framework (#3425)
|
||||
- Add WASM_V128 in wasm_valkind_enum (#3412)
|
||||
- Fix basic example, parameter missmatch between host and wasm (#3415)
|
||||
- Fix workspaces path in build_wamr.sh (#3414)
|
||||
- core/iwasm/compilation: Remove stale function prototypes (#3408)
|
||||
- Add test cases for the requirements of "gc-aot" feature (#3399)
|
||||
- append_aot_to_wasm.py: Add --ver-str option to emit more info in custom section name (#3398)
|
||||
- Fix clang compile warnings (#3396)
|
||||
- Fix some more spelling issues (#3393)
|
||||
- Fix some spelling issues (#3385)
|
||||
- samples/native-stack-overflow: Examine native functions with signature (#3382)
|
||||
- Add some more comments on WASM_STACK_GUARD_SIZE (#3380)
|
||||
- Fix typo for 'native' in wasm_export.h (#3376)
|
||||
- CI: Use macos-13 instead of macos-latest (#3366)
|
||||
- Test more samples in nightly-run CI (#3358)
|
||||
- Random improvements to samples/native-stack-overflow (#3353)
|
||||
- Reduce WASM_STACK_GUARD_SIZE a bit for posix-like platforms (#3350)
|
||||
- doc: Add ADOPTERS.md (#3324)
|
||||
- Update binary size info in README.md (#3030)
|
||||
- core/config.h: Bump the default WASM_STACK_GUARD_SIZE (#3344)
|
||||
- Add unit test suites (#3490)
|
||||
- Fix internal global getter types (#3495)
|
||||
- Fix CI build and run unit tests (#3499)
|
||||
|
||||
---
|
||||
|
||||
## WAMR-2.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
|
|
@ -1 +1 @@
|
|||
requests==2.31.0
|
||||
requests==2.32.3
|
|
@ -663,4 +663,17 @@
|
|||
#define WASM_MEM_ALLOC_WITH_USAGE 0
|
||||
#endif
|
||||
|
||||
#ifndef WASM_ENABLE_FUZZ_TEST
|
||||
#define WASM_ENABLE_FUZZ_TEST 0
|
||||
#endif
|
||||
|
||||
#ifndef WASM_MEM_ALLOC_MAX_SIZE
|
||||
#if WASM_ENABLE_FUZZ_TEST != 0
|
||||
/* In oss-fuzz, the maximum RAM is ~2.5G */
|
||||
#define WASM_MEM_ALLOC_MAX_SIZE (2U * 1024 * 1024 * 1024)
|
||||
#else
|
||||
#define WASM_MEM_ALLOC_MAX_SIZE UINT32_MAX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* end of _CONFIG_H_ */
|
||||
|
|
|
@ -1043,16 +1043,16 @@ load_memory_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
|||
}
|
||||
|
||||
for (i = 0; i < module->memory_count; i++) {
|
||||
read_uint32(buf, buf_end, module->memories[i].memory_flags);
|
||||
read_uint32(buf, buf_end, module->memories[i].flags);
|
||||
|
||||
if (!wasm_memory_check_flags(module->memories[i].memory_flags,
|
||||
error_buf, error_buf_size, true)) {
|
||||
if (!wasm_memory_check_flags(module->memories[i].flags, error_buf,
|
||||
error_buf_size, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
read_uint32(buf, buf_end, module->memories[i].num_bytes_per_page);
|
||||
read_uint32(buf, buf_end, module->memories[i].mem_init_page_count);
|
||||
read_uint32(buf, buf_end, module->memories[i].mem_max_page_count);
|
||||
read_uint32(buf, buf_end, module->memories[i].init_page_count);
|
||||
read_uint32(buf, buf_end, module->memories[i].max_page_count);
|
||||
}
|
||||
|
||||
read_uint32(buf, buf_end, module->mem_init_data_count);
|
||||
|
@ -3637,9 +3637,9 @@ has_module_memory64(AOTModule *module)
|
|||
/* TODO: multi-memories for now assuming the memory idx type is consistent
|
||||
* across multi-memories */
|
||||
if (module->import_memory_count > 0)
|
||||
return !!(module->import_memories[0].memory_flags & MEMORY64_FLAG);
|
||||
return !!(module->import_memories[0].mem_type.flags & MEMORY64_FLAG);
|
||||
else if (module->memory_count > 0)
|
||||
return !!(module->memories[0].memory_flags & MEMORY64_FLAG);
|
||||
return !!(module->memories[0].flags & MEMORY64_FLAG);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -789,10 +789,9 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
{
|
||||
void *heap_handle;
|
||||
uint32 num_bytes_per_page = memory->num_bytes_per_page;
|
||||
uint32 init_page_count = memory->mem_init_page_count;
|
||||
uint32 max_page_count =
|
||||
wasm_runtime_get_max_mem(max_memory_pages, memory->mem_init_page_count,
|
||||
memory->mem_max_page_count);
|
||||
uint32 init_page_count = memory->init_page_count;
|
||||
uint32 max_page_count = wasm_runtime_get_max_mem(
|
||||
max_memory_pages, memory->init_page_count, memory->max_page_count);
|
||||
uint32 default_max_pages;
|
||||
uint32 inc_page_count, global_idx;
|
||||
uint32 bytes_of_last_page, bytes_to_page_end;
|
||||
|
@ -800,11 +799,11 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
|||
heap_offset = (uint64)num_bytes_per_page * init_page_count;
|
||||
uint64 memory_data_size, max_memory_data_size;
|
||||
uint8 *p = NULL, *global_addr;
|
||||
bool is_memory64 = memory->memory_flags & MEMORY64_FLAG;
|
||||
bool is_memory64 = memory->flags & MEMORY64_FLAG;
|
||||
|
||||
bool is_shared_memory = false;
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
is_shared_memory = memory->memory_flags & SHARED_MEMORY_FLAG ? true : false;
|
||||
is_shared_memory = memory->flags & SHARED_MEMORY_FLAG ? true : false;
|
||||
/* Shared memory */
|
||||
if (is_shared_memory && parent != NULL) {
|
||||
AOTMemoryInstance *shared_memory_instance;
|
||||
|
@ -1946,7 +1945,7 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
|
|||
|
||||
if (!is_sub_inst) {
|
||||
#if WASM_ENABLE_WASI_NN != 0
|
||||
wasi_nn_destroy(module_inst);
|
||||
wasi_nn_destroy((WASMModuleInstanceCommon *)module_inst);
|
||||
#endif
|
||||
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
|
||||
}
|
||||
|
|
|
@ -846,12 +846,6 @@ wasm_is_reftype_supers_of_func(uint8 type)
|
|||
return (type == REF_TYPE_FUNCREF) ? true : false;
|
||||
}
|
||||
|
||||
inline static bool
|
||||
wasm_is_reftype_supers_of_extern(uint8 type)
|
||||
{
|
||||
return (type == REF_TYPE_EXTERNREF) ? true : false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
inline static bool
|
||||
wasm_is_reftype_supers_of_string(uint8 type)
|
||||
|
|
|
@ -201,9 +201,23 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
|
|||
if (func_type->param_count) {
|
||||
for (i = 0; i < argc; i++)
|
||||
total_argv_size += (uint32)(strlen(argv[i]) + 1);
|
||||
total_argv_size = align_uint(total_argv_size, 4);
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64)
|
||||
/* `char **argv` is an array of 64-bit elements in memory64 */
|
||||
total_argv_size = align_uint(total_argv_size, 8);
|
||||
else
|
||||
#endif
|
||||
total_argv_size = align_uint(total_argv_size, 4);
|
||||
|
||||
total_size = (uint64)total_argv_size + sizeof(int32) * (uint64)argc;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64)
|
||||
/* `char **argv` is an array of 64-bit elements in memory64 */
|
||||
total_size =
|
||||
(uint64)total_argv_size + sizeof(uint64) * (uint64)argc;
|
||||
else
|
||||
#endif
|
||||
total_size =
|
||||
(uint64)total_argv_size + sizeof(uint32) * (uint64)argc;
|
||||
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(argv_buf_offset = wasm_runtime_module_malloc(
|
||||
|
@ -219,7 +233,15 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
|
|||
for (i = 0; i < argc; i++) {
|
||||
bh_memcpy_s(p, (uint32)(p_end - p), argv[i],
|
||||
(uint32)(strlen(argv[i]) + 1));
|
||||
argv_offsets[i] = (uint32)argv_buf_offset + (uint32)(p - argv_buf);
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (is_memory64)
|
||||
/* `char **argv` is an array of 64-bit elements in memory64 */
|
||||
((uint64 *)argv_offsets)[i] =
|
||||
(uint32)argv_buf_offset + (uint32)(p - argv_buf);
|
||||
else
|
||||
#endif
|
||||
argv_offsets[i] =
|
||||
(uint32)argv_buf_offset + (uint32)(p - argv_buf);
|
||||
p += strlen(argv[i]) + 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -2580,8 +2580,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
|
|||
+ (i - import_func_count - import_global_count);
|
||||
module_name_rt = import->u.names.module_name;
|
||||
field_name_rt = import->u.names.field_name;
|
||||
min_page = import->u.memory.init_page_count;
|
||||
max_page = import->u.memory.max_page_count;
|
||||
min_page = import->u.memory.mem_type.init_page_count;
|
||||
max_page = import->u.memory.mem_type.max_page_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2592,8 +2592,8 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
|
|||
+ (i - import_func_count - import_global_count);
|
||||
module_name_rt = import->module_name;
|
||||
field_name_rt = import->memory_name;
|
||||
min_page = import->mem_init_page_count;
|
||||
max_page = import->mem_max_page_count;
|
||||
min_page = import->mem_type.init_page_count;
|
||||
max_page = import->mem_type.max_page_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -4308,12 +4308,12 @@ wasm_memory_new_internal(wasm_store_t *store, uint16 memory_idx_rt,
|
|||
AOTModule *module_aot = (AOTModule *)inst_aot->module;
|
||||
|
||||
if (memory_idx_rt < module_aot->import_memory_count) {
|
||||
min_pages = module_aot->import_memories->mem_init_page_count;
|
||||
max_pages = module_aot->import_memories->mem_max_page_count;
|
||||
min_pages = module_aot->import_memories->mem_type.init_page_count;
|
||||
max_pages = module_aot->import_memories->mem_type.max_page_count;
|
||||
}
|
||||
else {
|
||||
min_pages = module_aot->memories->mem_init_page_count;
|
||||
max_pages = module_aot->memories->mem_max_page_count;
|
||||
min_pages = module_aot->memories->init_page_count;
|
||||
max_pages = module_aot->memories->max_page_count;
|
||||
}
|
||||
init_flag = true;
|
||||
}
|
||||
|
|
|
@ -384,12 +384,14 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
|
|||
return ret;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
LOG_WARNING("Unhandled exception thrown: exception code: 0x%lx, "
|
||||
"exception address: %p, exception information: %p\n",
|
||||
ExceptionRecord->ExceptionCode,
|
||||
ExceptionRecord->ExceptionAddress, sig_addr);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR("Unhandled exception thrown: exception code: 0x%lx, "
|
||||
"exception address: %p, exception information: %p\n",
|
||||
ExceptionRecord->ExceptionCode, ExceptionRecord->ExceptionAddress,
|
||||
sig_addr);
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
#endif /* end of BH_PLATFORM_WINDOWS */
|
||||
|
@ -3871,7 +3873,8 @@ wasm_runtime_get_import_type(WASMModuleCommon *const module, int32 import_index,
|
|||
import_type->kind = WASM_IMPORT_EXPORT_KIND_FUNC;
|
||||
import_type->linked =
|
||||
aot_import_func->func_ptr_linked ? true : false;
|
||||
import_type->u.func_type = aot_import_func->func_type;
|
||||
import_type->u.func_type =
|
||||
(WASMFuncType *)aot_import_func->func_type;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3907,6 +3910,8 @@ wasm_runtime_get_import_type(WASMModuleCommon *const module, int32 import_index,
|
|||
import_type->name = aot_import_memory->memory_name;
|
||||
import_type->kind = WASM_IMPORT_EXPORT_KIND_MEMORY;
|
||||
import_type->linked = false;
|
||||
import_type->u.memory_type =
|
||||
(WASMMemoryType *)&aot_import_memory->mem_type;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3931,7 +3936,8 @@ wasm_runtime_get_import_type(WASMModuleCommon *const module, int32 import_index,
|
|||
switch (import_type->kind) {
|
||||
case WASM_IMPORT_EXPORT_KIND_FUNC:
|
||||
import_type->linked = wasm_import->u.function.func_ptr_linked;
|
||||
import_type->u.func_type = wasm_import->u.function.func_type;
|
||||
import_type->u.func_type =
|
||||
(WASMFuncType *)wasm_import->u.function.func_type;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_GLOBAL:
|
||||
import_type->linked = wasm_import->u.global.is_linked;
|
||||
|
@ -3939,12 +3945,12 @@ wasm_runtime_get_import_type(WASMModuleCommon *const module, int32 import_index,
|
|||
(WASMGlobalType *)&wasm_import->u.global.type;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_TABLE:
|
||||
/* not supported */
|
||||
import_type->linked = false;
|
||||
import_type->linked = false; /* not supported */
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_MEMORY:
|
||||
/* not supported */
|
||||
import_type->linked = false;
|
||||
import_type->linked = false; /* not supported */
|
||||
import_type->u.memory_type =
|
||||
(WASMMemoryType *)&wasm_import->u.memory.mem_type;
|
||||
break;
|
||||
default:
|
||||
bh_assert(0);
|
||||
|
@ -4024,12 +4030,11 @@ wasm_runtime_get_export_type(WASMModuleCommon *const module, int32 export_index,
|
|||
.type;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_TABLE:
|
||||
/* not supported */
|
||||
// export_type->linked = false;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_MEMORY:
|
||||
/* not supported */
|
||||
// export_type->linked = false;
|
||||
export_type->u.memory_type =
|
||||
&aot_module->memories[aot_export->index
|
||||
- aot_module->import_memory_count];
|
||||
break;
|
||||
default:
|
||||
bh_assert(0);
|
||||
|
@ -4066,13 +4071,13 @@ wasm_runtime_get_export_type(WASMModuleCommon *const module, int32 export_index,
|
|||
.type;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_TABLE:
|
||||
/* not supported */
|
||||
// export_type->linked = false;
|
||||
break;
|
||||
case WASM_IMPORT_EXPORT_KIND_MEMORY:
|
||||
/* not supported */
|
||||
// export_type->linked = false;
|
||||
export_type->u.memory_type =
|
||||
&wasm_module->memories[wasm_export->index
|
||||
- wasm_module->import_memory_count];
|
||||
break;
|
||||
default:
|
||||
bh_assert(0);
|
||||
break;
|
||||
}
|
||||
|
@ -4168,7 +4173,7 @@ wasm_func_type_get_result_valkind(WASMFuncType *const func_type,
|
|||
}
|
||||
|
||||
wasm_valkind_t
|
||||
wasm_global_type_get_valkind(const wasm_global_type_t global_type)
|
||||
wasm_global_type_get_valkind(WASMGlobalType *const global_type)
|
||||
{
|
||||
bh_assert(global_type);
|
||||
|
||||
|
@ -4176,13 +4181,37 @@ 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)
|
||||
wasm_global_type_get_mutable(WASMGlobalType *const global_type)
|
||||
{
|
||||
bh_assert(global_type);
|
||||
|
||||
return global_type->is_mutable;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_memory_type_get_shared(WASMMemoryType *const memory_type)
|
||||
{
|
||||
bh_assert(memory_type);
|
||||
|
||||
return (memory_type->flags & SHARED_MEMORY_FLAG) ? true : false;
|
||||
}
|
||||
|
||||
uint32
|
||||
wasm_memory_type_get_init_page_count(WASMMemoryType *const memory_type)
|
||||
{
|
||||
bh_assert(memory_type);
|
||||
|
||||
return memory_type->init_page_count;
|
||||
}
|
||||
|
||||
uint32
|
||||
wasm_memory_type_get_max_page_count(WASMMemoryType *const memory_type)
|
||||
{
|
||||
bh_assert(memory_type);
|
||||
|
||||
return memory_type->max_page_count;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_register_natives(const char *module_name,
|
||||
NativeSymbol *native_symbols,
|
||||
|
@ -6517,8 +6546,8 @@ wasm_runtime_get_export_memory_type(const WASMModuleCommon *module_comm,
|
|||
if (export->index < module->import_memory_count) {
|
||||
WASMMemoryImport *import_memory =
|
||||
&((module->import_memories + export->index)->u.memory);
|
||||
*out_min_page = import_memory->init_page_count;
|
||||
*out_max_page = import_memory->max_page_count;
|
||||
*out_min_page = import_memory->mem_type.init_page_count;
|
||||
*out_max_page = import_memory->mem_type.max_page_count;
|
||||
}
|
||||
else {
|
||||
WASMMemory *memory =
|
||||
|
@ -6538,14 +6567,14 @@ wasm_runtime_get_export_memory_type(const WASMModuleCommon *module_comm,
|
|||
if (export->index < module->import_memory_count) {
|
||||
AOTImportMemory *import_memory =
|
||||
module->import_memories + export->index;
|
||||
*out_min_page = import_memory->mem_init_page_count;
|
||||
*out_max_page = import_memory->mem_max_page_count;
|
||||
*out_min_page = import_memory->mem_type.init_page_count;
|
||||
*out_max_page = import_memory->mem_type.max_page_count;
|
||||
}
|
||||
else {
|
||||
AOTMemory *memory = module->memories
|
||||
+ (export->index - module->import_memory_count);
|
||||
*out_min_page = memory->mem_init_page_count;
|
||||
*out_max_page = memory->mem_max_page_count;
|
||||
*out_min_page = memory->init_page_count;
|
||||
*out_max_page = memory->max_page_count;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -558,28 +558,24 @@ aot_create_comp_data(WASMModule *module, const char *target_arch,
|
|||
/* Set memory page count */
|
||||
for (i = 0; i < module->import_memory_count + module->memory_count; i++) {
|
||||
if (i < module->import_memory_count) {
|
||||
comp_data->memories[i].memory_flags =
|
||||
module->import_memories[i].u.memory.flags;
|
||||
comp_data->memories[i].flags =
|
||||
module->import_memories[i].u.memory.mem_type.flags;
|
||||
comp_data->memories[i].num_bytes_per_page =
|
||||
module->import_memories[i].u.memory.num_bytes_per_page;
|
||||
comp_data->memories[i].mem_init_page_count =
|
||||
module->import_memories[i].u.memory.init_page_count;
|
||||
comp_data->memories[i].mem_max_page_count =
|
||||
module->import_memories[i].u.memory.max_page_count;
|
||||
comp_data->memories[i].num_bytes_per_page =
|
||||
module->import_memories[i].u.memory.num_bytes_per_page;
|
||||
module->import_memories[i].u.memory.mem_type.num_bytes_per_page;
|
||||
comp_data->memories[i].init_page_count =
|
||||
module->import_memories[i].u.memory.mem_type.init_page_count;
|
||||
comp_data->memories[i].max_page_count =
|
||||
module->import_memories[i].u.memory.mem_type.max_page_count;
|
||||
}
|
||||
else {
|
||||
j = i - module->import_memory_count;
|
||||
comp_data->memories[i].memory_flags = module->memories[j].flags;
|
||||
comp_data->memories[i].flags = module->memories[j].flags;
|
||||
comp_data->memories[i].num_bytes_per_page =
|
||||
module->memories[j].num_bytes_per_page;
|
||||
comp_data->memories[i].mem_init_page_count =
|
||||
comp_data->memories[i].init_page_count =
|
||||
module->memories[j].init_page_count;
|
||||
comp_data->memories[i].mem_max_page_count =
|
||||
comp_data->memories[i].max_page_count =
|
||||
module->memories[j].max_page_count;
|
||||
comp_data->memories[i].num_bytes_per_page =
|
||||
module->memories[j].num_bytes_per_page;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ typedef WASMStructType AOTStructType;
|
|||
typedef WASMArrayType AOTArrayType;
|
||||
#endif
|
||||
typedef WASMExport AOTExport;
|
||||
typedef WASMMemory AOTMemory;
|
||||
typedef WASMMemoryType AOTMemoryType;
|
||||
|
||||
#if WASM_ENABLE_DEBUG_AOT != 0
|
||||
typedef void *dwarf_extractor_handle_t;
|
||||
|
@ -81,23 +83,9 @@ typedef enum AOTFloatCond {
|
|||
typedef struct AOTImportMemory {
|
||||
char *module_name;
|
||||
char *memory_name;
|
||||
uint32 memory_flags;
|
||||
uint32 num_bytes_per_page;
|
||||
uint32 mem_init_page_count;
|
||||
uint32 mem_max_page_count;
|
||||
AOTMemoryType mem_type;
|
||||
} AOTImportMemory;
|
||||
|
||||
/**
|
||||
* Memory information
|
||||
*/
|
||||
typedef struct AOTMemory {
|
||||
/* memory info */
|
||||
uint32 memory_flags;
|
||||
uint32 num_bytes_per_page;
|
||||
uint32 mem_init_page_count;
|
||||
uint32 mem_max_page_count;
|
||||
} AOTMemory;
|
||||
|
||||
/**
|
||||
* A segment of memory init data
|
||||
*/
|
||||
|
|
|
@ -1028,7 +1028,9 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
}
|
||||
else {
|
||||
frame_ip--;
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_index);
|
||||
read_leb_int32(frame_ip, frame_ip_end, type_index);
|
||||
/* type index was checked in wasm loader */
|
||||
bh_assert(type_index < comp_ctx->comp_data->type_count);
|
||||
func_type =
|
||||
(AOTFuncType *)comp_ctx->comp_data->types[type_index];
|
||||
param_count = func_type->param_count;
|
||||
|
@ -1048,7 +1050,9 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
case EXT_OP_LOOP:
|
||||
case EXT_OP_IF:
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_index);
|
||||
read_leb_int32(frame_ip, frame_ip_end, type_index);
|
||||
/* type index was checked in wasm loader */
|
||||
bh_assert(type_index < comp_ctx->comp_data->type_count);
|
||||
func_type =
|
||||
(AOTFuncType *)comp_ctx->comp_data->types[type_index];
|
||||
param_count = func_type->param_count;
|
||||
|
|
|
@ -520,8 +520,7 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type)
|
|||
} while (0)
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
#define IS_MEMORY64 \
|
||||
(comp_ctx->comp_data->memories[0].memory_flags & MEMORY64_FLAG)
|
||||
#define IS_MEMORY64 (comp_ctx->comp_data->memories[0].flags & MEMORY64_FLAG)
|
||||
#define MEMORY64_COND_VALUE(VAL_IF_ENABLED, VAL_IF_DISABLED) \
|
||||
(IS_MEMORY64 ? VAL_IF_ENABLED : VAL_IF_DISABLED)
|
||||
#else
|
||||
|
|
|
@ -189,7 +189,7 @@ get_import_memory_size(AOTCompData *comp_data)
|
|||
static uint32
|
||||
get_memory_size(AOTCompData *comp_data)
|
||||
{
|
||||
/* memory_count + count * (memory_flags + num_bytes_per_page +
|
||||
/* memory_count + count * (flags + num_bytes_per_page +
|
||||
init_page_count + max_page_count) */
|
||||
return (uint32)(sizeof(uint32)
|
||||
+ comp_data->memory_count * sizeof(uint32) * 4);
|
||||
|
@ -1762,10 +1762,10 @@ aot_emit_mem_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
|
|||
EMIT_U32(comp_data->memory_count);
|
||||
/* Emit memory items */
|
||||
for (i = 0; i < comp_data->memory_count; i++) {
|
||||
EMIT_U32(comp_data->memories[i].memory_flags);
|
||||
EMIT_U32(comp_data->memories[i].flags);
|
||||
EMIT_U32(comp_data->memories[i].num_bytes_per_page);
|
||||
EMIT_U32(comp_data->memories[i].mem_init_page_count);
|
||||
EMIT_U32(comp_data->memories[i].mem_max_page_count);
|
||||
EMIT_U32(comp_data->memories[i].init_page_count);
|
||||
EMIT_U32(comp_data->memories[i].max_page_count);
|
||||
}
|
||||
|
||||
/* Emit mem init data count */
|
||||
|
|
|
@ -853,7 +853,7 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMBasicBlockRef terminate_block, non_terminate_block;
|
||||
AOTFuncType *aot_func_type = func_ctx->aot_func->func_type;
|
||||
bool is_shared_memory =
|
||||
comp_ctx->comp_data->memories[0].memory_flags & 0x02 ? true : false;
|
||||
comp_ctx->comp_data->memories[0].flags & 0x02 ? true : false;
|
||||
|
||||
/* Only need to check the suspend flags when memory is shared since
|
||||
shared memory must be enabled for multi-threading */
|
||||
|
|
|
@ -109,7 +109,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
bool is_target_64bit, is_local_of_aot_value = false;
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
bool is_shared_memory =
|
||||
comp_ctx->comp_data->memories[0].memory_flags & SHARED_MEMORY_FLAG;
|
||||
comp_ctx->comp_data->memories[0].flags & SHARED_MEMORY_FLAG;
|
||||
#endif
|
||||
|
||||
is_target_64bit = (comp_ctx->pointer_size == sizeof(uint64)) ? true : false;
|
||||
|
@ -177,7 +177,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
uint32 num_bytes_per_page =
|
||||
comp_ctx->comp_data->memories[0].num_bytes_per_page;
|
||||
uint32 init_page_count =
|
||||
comp_ctx->comp_data->memories[0].mem_init_page_count;
|
||||
comp_ctx->comp_data->memories[0].init_page_count;
|
||||
uint64 mem_data_size = (uint64)num_bytes_per_page * init_page_count;
|
||||
|
||||
if (mem_offset + bytes <= mem_data_size) {
|
||||
|
@ -224,7 +224,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
&& aot_checked_addr_list_find(func_ctx, local_idx_of_aot_value,
|
||||
offset, bytes))) {
|
||||
uint32 init_page_count =
|
||||
comp_ctx->comp_data->memories[0].mem_init_page_count;
|
||||
comp_ctx->comp_data->memories[0].init_page_count;
|
||||
if (init_page_count == 0) {
|
||||
LLVMValueRef mem_size;
|
||||
|
||||
|
@ -932,8 +932,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
/* Get memory base address and memory data size */
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
bool is_shared_memory =
|
||||
comp_ctx->comp_data->memories[0].memory_flags & 0x02;
|
||||
bool is_shared_memory = comp_ctx->comp_data->memories[0].flags & 0x02;
|
||||
|
||||
if (func_ctx->mem_space_unchanged || is_shared_memory) {
|
||||
#else
|
||||
|
@ -961,7 +960,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
uint32 num_bytes_per_page =
|
||||
comp_ctx->comp_data->memories[0].num_bytes_per_page;
|
||||
uint32 init_page_count =
|
||||
comp_ctx->comp_data->memories[0].mem_init_page_count;
|
||||
comp_ctx->comp_data->memories[0].init_page_count;
|
||||
uint64 mem_data_size = (uint64)num_bytes_per_page * init_page_count;
|
||||
if (mem_data_size > 0 && mem_offset + mem_len <= mem_data_size) {
|
||||
/* inside memory space */
|
||||
|
|
|
@ -1219,7 +1219,7 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
/* Load memory base address */
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
is_shared_memory =
|
||||
comp_ctx->comp_data->memories[0].memory_flags & 0x02 ? true : false;
|
||||
comp_ctx->comp_data->memories[0].flags & 0x02 ? true : false;
|
||||
if (is_shared_memory) {
|
||||
LLVMValueRef shared_mem_addr;
|
||||
offset = I32_CONST(offsetof(AOTModuleInstance, memories));
|
||||
|
|
|
@ -234,7 +234,7 @@ is_shared_memory(WASMModule *module, uint32 mem_idx)
|
|||
|
||||
if (mem_idx < module->import_memory_count) {
|
||||
memory_import = &(module->import_memories[mem_idx].u.memory);
|
||||
is_shared = memory_import->flags & 0x02 ? true : false;
|
||||
is_shared = memory_import->mem_type.flags & 0x02 ? true : false;
|
||||
}
|
||||
else {
|
||||
memory = &module->memories[mem_idx - module->import_memory_count];
|
||||
|
@ -1510,7 +1510,9 @@ jit_compile_func(JitCompContext *cc)
|
|||
case EXT_OP_LOOP:
|
||||
case EXT_OP_IF:
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_idx);
|
||||
read_leb_int32(frame_ip, frame_ip_end, type_idx);
|
||||
/* type index was checked in wasm loader */
|
||||
bh_assert(type_idx < cc->cur_wasm_module->type_count);
|
||||
func_type = cc->cur_wasm_module->types[type_idx];
|
||||
param_count = func_type->param_count;
|
||||
param_types = func_type->types;
|
||||
|
|
|
@ -78,6 +78,10 @@ typedef struct WASMFuncType *wasm_func_type_t;
|
|||
struct WASMGlobalType;
|
||||
typedef struct WASMGlobalType *wasm_global_type_t;
|
||||
|
||||
struct WASMMemory;
|
||||
typedef struct WASMMemory WASMMemoryType;
|
||||
typedef WASMMemoryType *wasm_memory_type_t;
|
||||
|
||||
typedef struct wasm_import_t {
|
||||
const char *module_name;
|
||||
const char *name;
|
||||
|
@ -86,6 +90,7 @@ typedef struct wasm_import_t {
|
|||
union {
|
||||
wasm_func_type_t func_type;
|
||||
wasm_global_type_t global_type;
|
||||
wasm_memory_type_t memory_type;
|
||||
} u;
|
||||
} wasm_import_t;
|
||||
|
||||
|
@ -95,6 +100,7 @@ typedef struct wasm_export_t {
|
|||
union {
|
||||
wasm_func_type_t func_type;
|
||||
wasm_global_type_t global_type;
|
||||
wasm_memory_type_t memory_type;
|
||||
} u;
|
||||
} wasm_export_t;
|
||||
|
||||
|
@ -1350,6 +1356,36 @@ wasm_global_type_get_valkind(const wasm_global_type_t global_type);
|
|||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_global_type_get_mutable(const wasm_global_type_t global_type);
|
||||
|
||||
/**
|
||||
* Get the shared setting for a memory type
|
||||
*
|
||||
* @param memory_type the memory type
|
||||
*
|
||||
* @return true if shared, false otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_memory_type_get_shared(const wasm_memory_type_t memory_type);
|
||||
|
||||
/**
|
||||
* Get the initial page count for a memory type
|
||||
*
|
||||
* @param memory_type the memory type
|
||||
*
|
||||
* @return the initial memory page count
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN uint32_t
|
||||
wasm_memory_type_get_init_page_count(const wasm_memory_type_t memory_type);
|
||||
|
||||
/**
|
||||
* Get the maximum page count for a memory type
|
||||
*
|
||||
* @param memory_type the memory type
|
||||
*
|
||||
* @return the maximum memory page count
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN uint32_t
|
||||
wasm_memory_type_get_max_page_count(const wasm_memory_type_t memory_type);
|
||||
|
||||
/**
|
||||
* Register native functions with same module name
|
||||
*
|
||||
|
|
|
@ -512,7 +512,7 @@ typedef struct WASMMemory {
|
|||
uint32 num_bytes_per_page;
|
||||
uint32 init_page_count;
|
||||
uint32 max_page_count;
|
||||
} WASMMemory;
|
||||
} WASMMemory, WASMMemoryType;
|
||||
|
||||
typedef struct WASMTableImport {
|
||||
char *module_name;
|
||||
|
@ -536,10 +536,7 @@ typedef struct WASMTableImport {
|
|||
typedef struct WASMMemoryImport {
|
||||
char *module_name;
|
||||
char *field_name;
|
||||
uint32 flags;
|
||||
uint32 num_bytes_per_page;
|
||||
uint32 init_page_count;
|
||||
uint32 max_page_count;
|
||||
WASMMemoryType mem_type;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMModule *import_module;
|
||||
WASMMemory *import_memory_linked;
|
||||
|
|
|
@ -3446,10 +3446,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
{
|
||||
/* clang-format off */
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||
local_offset = *frame_ip++;
|
||||
local_offset = *frame_ip++;
|
||||
#else
|
||||
local_offset = *frame_ip;
|
||||
frame_ip += 2;
|
||||
local_offset = *frame_ip;
|
||||
frame_ip += 2;
|
||||
#endif
|
||||
/* clang-format on */
|
||||
*(uint32 *)(frame_lp + local_offset) =
|
||||
|
@ -3463,10 +3463,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
{
|
||||
/* clang-format off */
|
||||
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
|
||||
local_offset = *frame_ip++;
|
||||
local_offset = *frame_ip++;
|
||||
#else
|
||||
local_offset = *frame_ip;
|
||||
frame_ip += 2;
|
||||
local_offset = *frame_ip;
|
||||
frame_ip += 2;
|
||||
#endif
|
||||
/* clang-format on */
|
||||
PUT_I64_TO_ADDR((uint32 *)(frame_lp + local_offset),
|
||||
|
|
|
@ -44,7 +44,8 @@ has_module_memory64(WASMModule *module)
|
|||
/* TODO: multi-memories for now assuming the memory idx type is consistent
|
||||
* across multi-memories */
|
||||
if (module->import_memory_count > 0)
|
||||
return !!(module->import_memories[0].u.memory.flags & MEMORY64_FLAG);
|
||||
return !!(module->import_memories[0].u.memory.mem_type.flags
|
||||
& MEMORY64_FLAG);
|
||||
else if (module->memory_count > 0)
|
||||
return !!(module->memories[0].flags & MEMORY64_FLAG);
|
||||
|
||||
|
@ -379,7 +380,8 @@ loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
|
|||
{
|
||||
void *mem;
|
||||
|
||||
if (size >= UINT32_MAX || !(mem = wasm_runtime_malloc((uint32)size))) {
|
||||
if (size >= WASM_MEM_ALLOC_MAX_SIZE
|
||||
|| !(mem = wasm_runtime_malloc((uint32)size))) {
|
||||
set_error_buf(error_buf, error_buf_size, "allocate memory failed");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2934,10 +2936,10 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
|||
}
|
||||
|
||||
/* now we believe all declaration are ok */
|
||||
memory->flags = mem_flag;
|
||||
memory->init_page_count = declare_init_page_count;
|
||||
memory->max_page_count = declare_max_page_count;
|
||||
memory->num_bytes_per_page = DEFAULT_NUM_BYTES_PER_PAGE;
|
||||
memory->mem_type.flags = mem_flag;
|
||||
memory->mem_type.init_page_count = declare_init_page_count;
|
||||
memory->mem_type.max_page_count = declare_max_page_count;
|
||||
memory->mem_type.num_bytes_per_page = DEFAULT_NUM_BYTES_PER_PAGE;
|
||||
|
||||
*p_buf = p;
|
||||
|
||||
|
@ -3052,7 +3054,12 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
|
|||
|
||||
#if WASM_ENABLE_GC == 0
|
||||
CHECK_BUF(p, p_end, 2);
|
||||
/* global type */
|
||||
declare_type = read_uint8(p);
|
||||
if (!is_value_type(declare_type)) {
|
||||
set_error_buf(error_buf, error_buf_size, "type mismatch");
|
||||
return false;
|
||||
}
|
||||
declare_mutable = read_uint8(p);
|
||||
#else
|
||||
if (!resolve_value_type(&p, p_end, parent_module, parent_module->type_count,
|
||||
|
@ -4034,7 +4041,12 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
for (i = 0; i < global_count; i++, global++) {
|
||||
#if WASM_ENABLE_GC == 0
|
||||
CHECK_BUF(p, p_end, 2);
|
||||
/* global type */
|
||||
global->type.val_type = read_uint8(p);
|
||||
if (!is_value_type(global->type.val_type)) {
|
||||
set_error_buf(error_buf, error_buf_size, "type mismatch");
|
||||
return false;
|
||||
}
|
||||
mutable = read_uint8(p);
|
||||
#else
|
||||
if (!resolve_value_type(&p, p_end, module, module->type_count,
|
||||
|
@ -4705,8 +4717,12 @@ fail:
|
|||
|
||||
static bool
|
||||
load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
WASMModule *module, bool clone_data_seg,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
WASMModule *module,
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
bool has_datacount_section,
|
||||
#endif
|
||||
bool clone_data_seg, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 data_seg_count, i, mem_index, data_seg_len;
|
||||
|
@ -4722,8 +4738,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
|||
read_leb_uint32(p, p_end, data_seg_count);
|
||||
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
if ((module->data_seg_count1 != 0)
|
||||
&& (data_seg_count != module->data_seg_count1)) {
|
||||
if (has_datacount_section && data_seg_count != module->data_seg_count1) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"data count and data section have inconsistent lengths");
|
||||
return false;
|
||||
|
@ -4791,8 +4806,8 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
|||
/* This memory_flag is from memory instead of data segment */
|
||||
uint8 memory_flag;
|
||||
if (module->import_memory_count > 0) {
|
||||
memory_flag =
|
||||
module->import_memories[mem_index].u.memory.flags;
|
||||
memory_flag = module->import_memories[mem_index]
|
||||
.u.memory.mem_type.flags;
|
||||
}
|
||||
else {
|
||||
memory_flag =
|
||||
|
@ -5231,10 +5246,11 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
module->name_section_buf = buf;
|
||||
module->name_section_buf_end = buf_end;
|
||||
p += name_len;
|
||||
handle_name_section(p, p_end, module, is_load_from_file_buf, error_buf,
|
||||
error_buf_size);
|
||||
if (!handle_name_section(p, p_end, module, is_load_from_file_buf,
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
LOG_VERBOSE("Load custom name section success.");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -5778,6 +5794,9 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
uint8 malloc_free_io_type = VALUE_TYPE_I32;
|
||||
bool reuse_const_strings = is_load_from_file_buf && !wasm_binary_freeable;
|
||||
bool clone_data_seg = is_load_from_file_buf && wasm_binary_freeable;
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
bool has_datacount_section = false;
|
||||
#endif
|
||||
|
||||
/* Find code and function sections if have */
|
||||
while (section) {
|
||||
|
@ -5870,6 +5889,9 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
break;
|
||||
case SECTION_TYPE_DATA:
|
||||
if (!load_data_segment_section(buf, buf_end, module,
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
has_datacount_section,
|
||||
#endif
|
||||
clone_data_seg, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
|
@ -5879,6 +5901,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
if (!load_datacount_section(buf, buf_end, module, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
has_datacount_section = true;
|
||||
break;
|
||||
#endif
|
||||
#if WASM_ENABLE_STRINGREF != 0
|
||||
|
@ -6131,13 +6154,14 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
if (shrunk_memory_size <= UINT32_MAX) {
|
||||
if (module->import_memory_count) {
|
||||
memory_import = &module->import_memories[0].u.memory;
|
||||
init_memory_size = (uint64)memory_import->num_bytes_per_page
|
||||
* memory_import->init_page_count;
|
||||
init_memory_size =
|
||||
(uint64)memory_import->mem_type.num_bytes_per_page
|
||||
* memory_import->mem_type.init_page_count;
|
||||
if (shrunk_memory_size <= init_memory_size) {
|
||||
/* Reset memory info to decrease memory usage */
|
||||
memory_import->num_bytes_per_page =
|
||||
memory_import->mem_type.num_bytes_per_page =
|
||||
(uint32)shrunk_memory_size;
|
||||
memory_import->init_page_count = 1;
|
||||
memory_import->mem_type.init_page_count = 1;
|
||||
LOG_VERBOSE("Shrink import memory size to %" PRIu64,
|
||||
shrunk_memory_size);
|
||||
}
|
||||
|
@ -6163,16 +6187,16 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
memory_import = &module->import_memories[0].u.memory;
|
||||
/* Only resize the memory to one big page if num_bytes_per_page is
|
||||
* in valid range of uint32 */
|
||||
if (memory_import->init_page_count < DEFAULT_MAX_PAGES) {
|
||||
memory_import->num_bytes_per_page *=
|
||||
memory_import->init_page_count;
|
||||
if (memory_import->mem_type.init_page_count < DEFAULT_MAX_PAGES) {
|
||||
memory_import->mem_type.num_bytes_per_page *=
|
||||
memory_import->mem_type.init_page_count;
|
||||
|
||||
if (memory_import->init_page_count > 0)
|
||||
memory_import->init_page_count =
|
||||
memory_import->max_page_count = 1;
|
||||
if (memory_import->mem_type.init_page_count > 0)
|
||||
memory_import->mem_type.init_page_count =
|
||||
memory_import->mem_type.max_page_count = 1;
|
||||
else
|
||||
memory_import->init_page_count =
|
||||
memory_import->max_page_count = 0;
|
||||
memory_import->mem_type.init_page_count =
|
||||
memory_import->mem_type.max_page_count = 0;
|
||||
}
|
||||
}
|
||||
if (module->memory_count) {
|
||||
|
@ -6403,7 +6427,7 @@ create_sections(const uint8 *buf, uint32 size, WASMSection **p_section_list,
|
|||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMSection *section_list_end = NULL, *section;
|
||||
const uint8 *p = buf, *p_end = buf + size /*, *section_body*/;
|
||||
const uint8 *p = buf, *p_end = buf + size;
|
||||
uint8 section_type, section_index, last_section_index = (uint8)-1;
|
||||
uint32 section_size;
|
||||
|
||||
|
@ -7075,7 +7099,8 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
}
|
||||
else {
|
||||
p--;
|
||||
skip_leb_uint32(p, p_end);
|
||||
/* block type */
|
||||
skip_leb_int32(p, p_end);
|
||||
}
|
||||
if (block_nested_depth
|
||||
< sizeof(block_stack) / sizeof(BlockAddr)) {
|
||||
|
@ -7090,7 +7115,7 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
case EXT_OP_LOOP:
|
||||
case EXT_OP_IF:
|
||||
/* block type */
|
||||
skip_leb_uint32(p, p_end);
|
||||
skip_leb_int32(p, p_end);
|
||||
if (block_nested_depth
|
||||
< sizeof(block_stack) / sizeof(BlockAddr)) {
|
||||
block_stack[block_nested_depth].start_addr = p;
|
||||
|
@ -7647,7 +7672,6 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0)
|
||||
case WASM_OP_SIMD_PREFIX:
|
||||
{
|
||||
/* TODO: memory64 offset type changes */
|
||||
uint32 opcode1;
|
||||
|
||||
read_leb_uint32(p, p_end, opcode1);
|
||||
|
@ -7672,8 +7696,8 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
case SIMD_v128_store:
|
||||
/* memarg align */
|
||||
skip_leb_uint32(p, p_end);
|
||||
/* memarg offset*/
|
||||
skip_leb_uint32(p, p_end);
|
||||
/* memarg offset */
|
||||
skip_leb_mem_offset(p, p_end);
|
||||
break;
|
||||
|
||||
case SIMD_v128_const:
|
||||
|
@ -7712,8 +7736,8 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
case SIMD_v128_store64_lane:
|
||||
/* memarg align */
|
||||
skip_leb_uint32(p, p_end);
|
||||
/* memarg offset*/
|
||||
skip_leb_uint32(p, p_end);
|
||||
/* memarg offset */
|
||||
skip_leb_mem_offset(p, p_end);
|
||||
/* ImmLaneId */
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
p++;
|
||||
|
@ -7723,8 +7747,8 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
case SIMD_v128_load64_zero:
|
||||
/* memarg align */
|
||||
skip_leb_uint32(p, p_end);
|
||||
/* memarg offset*/
|
||||
skip_leb_uint32(p, p_end);
|
||||
/* memarg offset */
|
||||
skip_leb_mem_offset(p, p_end);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -7840,7 +7864,11 @@ typedef struct BranchBlock {
|
|||
BranchBlockPatch *patch_list;
|
||||
/* This is used to save params frame_offset of of if block */
|
||||
int16 *param_frame_offsets;
|
||||
/* This is used to recover dynamic offset for else branch */
|
||||
/* This is used to recover the dynamic offset for else branch,
|
||||
* and also to remember the start offset of dynamic space which
|
||||
* stores the block arguments for loop block, so we can use it
|
||||
* to copy the stack operands to the loop block's arguments in
|
||||
* wasm_loader_emit_br_info for opcode br. */
|
||||
uint16 start_dynamic_offset;
|
||||
#endif
|
||||
|
||||
|
@ -7991,13 +8019,26 @@ static void
|
|||
free_all_label_patch_lists(BranchBlock *frame_csp, uint32 csp_num)
|
||||
{
|
||||
BranchBlock *tmp_csp = frame_csp;
|
||||
uint32 i;
|
||||
|
||||
for (uint32 i = 0; i < csp_num; i++) {
|
||||
for (i = 0; i < csp_num; i++) {
|
||||
free_label_patch_list(tmp_csp);
|
||||
tmp_csp++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_all_label_param_frame_offsets(BranchBlock *frame_csp, uint32 csp_num)
|
||||
{
|
||||
BranchBlock *tmp_csp = frame_csp;
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < csp_num; i++) {
|
||||
if (tmp_csp->param_frame_offsets)
|
||||
wasm_runtime_free(tmp_csp->param_frame_offsets);
|
||||
tmp_csp++;
|
||||
}
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_FAST_INTERP */
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
|
@ -8116,6 +8157,8 @@ wasm_loader_ctx_destroy(WASMLoaderContext *ctx)
|
|||
if (ctx->frame_csp_bottom) {
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
free_all_label_patch_lists(ctx->frame_csp_bottom, ctx->csp_num);
|
||||
free_all_label_param_frame_offsets(ctx->frame_csp_bottom,
|
||||
ctx->csp_num);
|
||||
#endif
|
||||
#if WASM_ENABLE_GC != 0
|
||||
wasm_loader_clean_all_local_use_masks(ctx);
|
||||
|
@ -9228,8 +9271,14 @@ wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
|
|||
emit_operand(ctx, *(int16 *)(frame_offset));
|
||||
}
|
||||
/* Part e */
|
||||
dynamic_offset =
|
||||
frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
|
||||
if (frame_csp->label_type == LABEL_TYPE_LOOP)
|
||||
/* Use start_dynamic_offset which was set in
|
||||
copy_params_to_dynamic_space */
|
||||
dynamic_offset = frame_csp->start_dynamic_offset
|
||||
+ wasm_get_cell_num(types, arity);
|
||||
else
|
||||
dynamic_offset =
|
||||
frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
|
||||
if (is_br)
|
||||
ctx->dynamic_offset = dynamic_offset;
|
||||
for (i = (int32)arity - 1; i >= 0; i--) {
|
||||
|
@ -10613,8 +10662,8 @@ fail:
|
|||
* Part e: each param's dst offset
|
||||
*/
|
||||
static bool
|
||||
copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
bool ret = false;
|
||||
int16 *frame_offset = NULL;
|
||||
|
@ -10628,6 +10677,7 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
|||
uint32 param_count = block_type->u.type->param_count;
|
||||
int16 condition_offset = 0;
|
||||
bool disable_emit = false;
|
||||
bool is_if_block = (block->label_type == LABEL_TYPE_IF ? true : false);
|
||||
int16 operand_offset = 0;
|
||||
|
||||
uint64 size = (uint64)param_count * (sizeof(*cells) + sizeof(*src_offsets));
|
||||
|
@ -10680,6 +10730,14 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
|||
if (is_if_block)
|
||||
emit_operand(loader_ctx, condition_offset);
|
||||
|
||||
/* Since the start offset to save the block's params and
|
||||
* the start offset to save the block's results may be
|
||||
* different, we remember the dynamic offset for loop block
|
||||
* so that we can use it to copy the stack operands to the
|
||||
* loop block's params in wasm_loader_emit_br_info. */
|
||||
if (block->label_type == LABEL_TYPE_LOOP)
|
||||
block->start_dynamic_offset = loader_ctx->dynamic_offset;
|
||||
|
||||
/* Part e) */
|
||||
/* Push to dynamic space. The push will emit the dst offset. */
|
||||
for (i = 0; i < param_count; i++)
|
||||
|
@ -11052,12 +11110,12 @@ re_scan:
|
|||
#endif /* end of WASM_ENABLE_GC != 0 */
|
||||
}
|
||||
else {
|
||||
uint32 type_index;
|
||||
int32 type_index;
|
||||
/* Resolve the leb128 encoded type index as block type */
|
||||
p--;
|
||||
p_org = p - 1;
|
||||
read_leb_uint32(p, p_end, type_index);
|
||||
if (type_index >= module->type_count) {
|
||||
read_leb_int32(p, p_end, type_index);
|
||||
if ((uint32)type_index >= module->type_count) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"unknown type");
|
||||
goto fail;
|
||||
|
@ -11161,8 +11219,8 @@ re_scan:
|
|||
|
||||
if (BLOCK_HAS_PARAM(block_type)) {
|
||||
/* Make sure params are in dynamic space */
|
||||
if (!copy_params_to_dynamic_space(
|
||||
loader_ctx, false, error_buf, error_buf_size))
|
||||
if (!copy_params_to_dynamic_space(loader_ctx, error_buf,
|
||||
error_buf_size))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -11208,8 +11266,8 @@ re_scan:
|
|||
/* skip the if label */
|
||||
skip_label();
|
||||
/* Emit a copy instruction */
|
||||
if (!copy_params_to_dynamic_space(
|
||||
loader_ctx, true, error_buf, error_buf_size))
|
||||
if (!copy_params_to_dynamic_space(loader_ctx, error_buf,
|
||||
error_buf_size))
|
||||
goto fail;
|
||||
|
||||
/* Emit the if instruction */
|
||||
|
|
|
@ -33,7 +33,7 @@ has_module_memory64(WASMModule *module)
|
|||
/* TODO: multi-memories for now assuming the memory idx type is consistent
|
||||
* across multi-memories */
|
||||
if (module->import_memory_count > 0)
|
||||
return !!(module->import_memories[0].u.memory.flags & MEMORY64_FLAG);
|
||||
return !!(module->import_memories[0].u.mem_type.flags & MEMORY64_FLAG);
|
||||
else if (module->memory_count > 0)
|
||||
return !!(module->memories[0].flags & MEMORY64_FLAG);
|
||||
|
||||
|
@ -761,10 +761,10 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
|||
}
|
||||
|
||||
/* now we believe all declaration are ok */
|
||||
memory->flags = mem_flag;
|
||||
memory->init_page_count = declare_init_page_count;
|
||||
memory->max_page_count = declare_max_page_count;
|
||||
memory->num_bytes_per_page = DEFAULT_NUM_BYTES_PER_PAGE;
|
||||
memory->mem_type.flags = mem_flag;
|
||||
memory->mem_type.init_page_count = declare_init_page_count;
|
||||
memory->mem_type.max_page_count = declare_max_page_count;
|
||||
memory->mem_type.num_bytes_per_page = DEFAULT_NUM_BYTES_PER_PAGE;
|
||||
|
||||
*p_buf = p;
|
||||
return true;
|
||||
|
@ -1740,8 +1740,12 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
|||
|
||||
static bool
|
||||
load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
WASMModule *module, bool clone_data_seg,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
WASMModule *module,
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
bool has_datacount_section,
|
||||
#endif
|
||||
bool clone_data_seg, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 data_seg_count, i, mem_index, data_seg_len;
|
||||
|
@ -1757,7 +1761,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
|||
read_leb_uint32(p, p_end, data_seg_count);
|
||||
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
bh_assert(module->data_seg_count1 == 0
|
||||
bh_assert(!has_datacount_section
|
||||
|| data_seg_count == module->data_seg_count1);
|
||||
#endif
|
||||
|
||||
|
@ -1808,7 +1812,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
|||
uint8 memory_flag;
|
||||
if (module->import_memory_count > 0) {
|
||||
memory_flag =
|
||||
module->import_memories[mem_index].u.memory.flags;
|
||||
module->import_memories[mem_index].u.mem_type.flags;
|
||||
}
|
||||
else {
|
||||
memory_flag =
|
||||
|
@ -2029,8 +2033,10 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||
if (name_len == 4 && memcmp(p, "name", 4) == 0) {
|
||||
p += name_len;
|
||||
handle_name_section(p, p_end, module, is_load_from_file_buf, error_buf,
|
||||
error_buf_size);
|
||||
if (!handle_name_section(p, p_end, module, is_load_from_file_buf,
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
LOG_VERBOSE("Load custom section success.\n");
|
||||
|
@ -2108,7 +2114,7 @@ static bool
|
|||
init_llvm_jit_functions_stage1(WASMModule *module, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
LLVMJITOptions llvm_jit_options = wasm_runtime_get_llvm_jit_options();
|
||||
LLVMJITOptions *llvm_jit_options = wasm_runtime_get_llvm_jit_options();
|
||||
AOTCompOption option = { 0 };
|
||||
char *aot_last_error;
|
||||
uint64 size;
|
||||
|
@ -2579,6 +2585,9 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
uint8 malloc_free_io_type = VALUE_TYPE_I32;
|
||||
bool reuse_const_strings = is_load_from_file_buf && !wasm_binary_freeable;
|
||||
bool clone_data_seg = is_load_from_file_buf && wasm_binary_freeable;
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
bool has_datacount_section = false;
|
||||
#endif
|
||||
|
||||
/* Find code and function sections if have */
|
||||
while (section) {
|
||||
|
@ -2660,6 +2669,9 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
break;
|
||||
case SECTION_TYPE_DATA:
|
||||
if (!load_data_segment_section(buf, buf_end, module,
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
has_datacount_section,
|
||||
#endif
|
||||
clone_data_seg, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
|
@ -2669,6 +2681,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
if (!load_datacount_section(buf, buf_end, module, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
has_datacount_section = true;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -2909,12 +2922,14 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
if (shrunk_memory_size <= UINT32_MAX) {
|
||||
if (module->import_memory_count) {
|
||||
memory_import = &module->import_memories[0].u.memory;
|
||||
init_memory_size = (uint64)memory_import->num_bytes_per_page
|
||||
* memory_import->init_page_count;
|
||||
init_memory_size =
|
||||
(uint64)memory_import->mem_type.num_bytes_per_page
|
||||
* memory_import->mem_type.init_page_count;
|
||||
if (shrunk_memory_size <= init_memory_size) {
|
||||
/* Reset memory info to decrease memory usage */
|
||||
memory_import->num_bytes_per_page = shrunk_memory_size;
|
||||
memory_import->init_page_count = 1;
|
||||
memory_import->mem_type.num_bytes_per_page =
|
||||
shrunk_memory_size;
|
||||
memory_import->mem_type.init_page_count = 1;
|
||||
LOG_VERBOSE("Shrink import memory size to %" PRIu64,
|
||||
shrunk_memory_size);
|
||||
}
|
||||
|
@ -2937,15 +2952,15 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
|
||||
if (module->import_memory_count) {
|
||||
memory_import = &module->import_memories[0].u.memory;
|
||||
if (memory_import->init_page_count < DEFAULT_MAX_PAGES) {
|
||||
memory_import->num_bytes_per_page *=
|
||||
memory_import->init_page_count;
|
||||
if (memory_import->init_page_count > 0)
|
||||
memory_import->init_page_count =
|
||||
memory_import->max_page_count = 1;
|
||||
if (memory_import->mem_type.init_page_count < DEFAULT_MAX_PAGES) {
|
||||
memory_import->mem_type.num_bytes_per_page *=
|
||||
memory_import->mem_type.init_page_count;
|
||||
if (memory_import->mem_type.init_page_count > 0)
|
||||
memory_import->mem_type.init_page_count =
|
||||
memory_import->mem_type.max_page_count = 1;
|
||||
else
|
||||
memory_import->init_page_count =
|
||||
memory_import->max_page_count = 0;
|
||||
memory_import->mem_type.init_page_count =
|
||||
memory_import->mem_type.max_page_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3220,8 +3235,11 @@ load(const uint8 *buf, uint32 size, WASMModule *module,
|
|||
}
|
||||
|
||||
WASMModule *
|
||||
wasm_loader_load(uint8 *buf, uint32 size, const LoadArgs *args, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
wasm_loader_load(uint8 *buf, uint32 size,
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
bool main_module,
|
||||
#endif
|
||||
const LoadArgs *args, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMModule *module = create_module(args->name, error_buf, error_buf_size);
|
||||
if (!module) {
|
||||
|
@ -3239,6 +3257,10 @@ wasm_loader_load(uint8 *buf, uint32 size, const LoadArgs *args, char *error_buf,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
(void)main_module;
|
||||
#endif
|
||||
|
||||
LOG_VERBOSE("Load module success.\n");
|
||||
return module;
|
||||
|
||||
|
@ -3451,7 +3473,7 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
case EXT_OP_LOOP:
|
||||
case EXT_OP_IF:
|
||||
/* block type */
|
||||
skip_leb_uint32(p, p_end);
|
||||
skip_leb_int32(p, p_end);
|
||||
if (block_nested_depth
|
||||
< sizeof(block_stack) / sizeof(BlockAddr)) {
|
||||
block_stack[block_nested_depth].start_addr = p;
|
||||
|
@ -3921,7 +3943,11 @@ typedef struct BranchBlock {
|
|||
/* This is used to store available param num for if/else branch, so the else
|
||||
* opcode can know how many parameters should be copied to the stack */
|
||||
uint32 available_param_num;
|
||||
/* This is used to recover dynamic offset for else branch */
|
||||
/* This is used to recover the dynamic offset for else branch,
|
||||
* and also to remember the start offset of dynamic space which
|
||||
* stores the block arguments for loop block, so we can use it
|
||||
* to copy the stack operands to the loop block's arguments in
|
||||
* wasm_loader_emit_br_info for opcode br. */
|
||||
uint16 start_dynamic_offset;
|
||||
#endif
|
||||
|
||||
|
@ -4050,13 +4076,26 @@ static void
|
|||
free_all_label_patch_lists(BranchBlock *frame_csp, uint32 csp_num)
|
||||
{
|
||||
BranchBlock *tmp_csp = frame_csp;
|
||||
uint32 i;
|
||||
|
||||
for (uint32 i = 0; i < csp_num; i++) {
|
||||
for (i = 0; i < csp_num; i++) {
|
||||
free_label_patch_list(tmp_csp);
|
||||
tmp_csp++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_all_label_param_frame_offsets(BranchBlock *frame_csp, uint32 csp_num)
|
||||
{
|
||||
BranchBlock *tmp_csp = frame_csp;
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < csp_num; i++) {
|
||||
if (tmp_csp->param_frame_offsets)
|
||||
wasm_runtime_free(tmp_csp->param_frame_offsets);
|
||||
tmp_csp++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
|
@ -4120,6 +4159,8 @@ wasm_loader_ctx_destroy(WASMLoaderContext *ctx)
|
|||
if (ctx->frame_csp_bottom) {
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
free_all_label_patch_lists(ctx->frame_csp_bottom, ctx->csp_num);
|
||||
free_all_label_param_frame_offsets(ctx->frame_csp_bottom,
|
||||
ctx->csp_num);
|
||||
#endif
|
||||
wasm_runtime_free(ctx->frame_csp_bottom);
|
||||
}
|
||||
|
@ -4798,8 +4839,14 @@ wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
|
|||
emit_operand(ctx, *(int16 *)(frame_offset));
|
||||
}
|
||||
/* Part e */
|
||||
dynamic_offset =
|
||||
frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
|
||||
if (frame_csp->label_type == LABEL_TYPE_LOOP)
|
||||
/* Use start_dynamic_offset which was set in
|
||||
copy_params_to_dynamic_space */
|
||||
dynamic_offset = frame_csp->start_dynamic_offset
|
||||
+ wasm_get_cell_num(types, arity);
|
||||
else
|
||||
dynamic_offset =
|
||||
frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
|
||||
if (is_br)
|
||||
ctx->dynamic_offset = dynamic_offset;
|
||||
for (i = (int32)arity - 1; i >= 0; i--) {
|
||||
|
@ -5778,8 +5825,8 @@ fail:
|
|||
* Part e: each param's dst offset
|
||||
*/
|
||||
static bool
|
||||
copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
bool ret = false;
|
||||
int16 *frame_offset = NULL;
|
||||
|
@ -5793,6 +5840,7 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
|||
uint32 param_count = block_type->u.type->param_count;
|
||||
int16 condition_offset = 0;
|
||||
bool disable_emit = false;
|
||||
bool is_if_block = (block->label_type == LABEL_TYPE_IF ? true : false);
|
||||
int16 operand_offset = 0;
|
||||
|
||||
uint64 size = (uint64)param_count * (sizeof(*cells) + sizeof(*src_offsets));
|
||||
|
@ -5845,6 +5893,14 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
|||
if (is_if_block)
|
||||
emit_operand(loader_ctx, condition_offset);
|
||||
|
||||
/* Since the start offset to save the block's params and
|
||||
* the start offset to save the block's results may be
|
||||
* different, we remember the dynamic offset for loop block
|
||||
* so that we can use it to copy the stack operands to the
|
||||
* loop block's params in wasm_loader_emit_br_info. */
|
||||
if (block->label_type == LABEL_TYPE_LOOP)
|
||||
block->start_dynamic_offset = loader_ctx->dynamic_offset;
|
||||
|
||||
/* Part e) */
|
||||
/* Push to dynamic space. The push will emit the dst offset. */
|
||||
for (i = 0; i < param_count; i++)
|
||||
|
@ -6043,11 +6099,11 @@ re_scan:
|
|||
block_type.u.value_type.type = value_type;
|
||||
}
|
||||
else {
|
||||
uint32 type_index;
|
||||
int32 type_index;
|
||||
/* Resolve the leb128 encoded type index as block type */
|
||||
p--;
|
||||
read_leb_uint32(p, p_end, type_index);
|
||||
bh_assert(type_index < module->type_count);
|
||||
read_leb_int32(p, p_end, type_index);
|
||||
bh_assert((uint32)type_index < module->type_count);
|
||||
block_type.is_value_type = false;
|
||||
block_type.u.type = module->types[type_index];
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
|
@ -6134,8 +6190,8 @@ re_scan:
|
|||
skip_label();
|
||||
if (BLOCK_HAS_PARAM(block_type)) {
|
||||
/* Make sure params are in dynamic space */
|
||||
if (!copy_params_to_dynamic_space(
|
||||
loader_ctx, false, error_buf, error_buf_size))
|
||||
if (!copy_params_to_dynamic_space(loader_ctx, error_buf,
|
||||
error_buf_size))
|
||||
goto fail;
|
||||
}
|
||||
if (opcode == WASM_OP_LOOP) {
|
||||
|
@ -6175,8 +6231,8 @@ re_scan:
|
|||
/* skip the if label */
|
||||
skip_label();
|
||||
/* Emit a copy instruction */
|
||||
if (!copy_params_to_dynamic_space(
|
||||
loader_ctx, true, error_buf, error_buf_size))
|
||||
if (!copy_params_to_dynamic_space(loader_ctx, error_buf,
|
||||
error_buf_size))
|
||||
goto fail;
|
||||
|
||||
/* Emit the if instruction */
|
||||
|
@ -6942,7 +6998,8 @@ re_scan:
|
|||
uint32 j;
|
||||
|
||||
for (i = 0; i < module->global_count; i++) {
|
||||
if (module->globals[i].type == VALUE_TYPE_FUNCREF
|
||||
if (module->globals[i].type.val_type
|
||||
== VALUE_TYPE_FUNCREF
|
||||
&& module->globals[i].init_expr.init_expr_type
|
||||
== INIT_EXPR_TYPE_FUNCREF_CONST
|
||||
&& module->globals[i].init_expr.u.u32 == func_idx) {
|
||||
|
|
|
@ -396,12 +396,13 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
|||
/* instantiate memories from import section */
|
||||
import = module->import_memories;
|
||||
for (i = 0; i < module->import_memory_count; i++, import++, memory++) {
|
||||
uint32 num_bytes_per_page = import->u.memory.num_bytes_per_page;
|
||||
uint32 init_page_count = import->u.memory.init_page_count;
|
||||
uint32 num_bytes_per_page =
|
||||
import->u.memory.mem_type.num_bytes_per_page;
|
||||
uint32 init_page_count = import->u.memory.mem_type.init_page_count;
|
||||
uint32 max_page_count = wasm_runtime_get_max_mem(
|
||||
max_memory_pages, import->u.memory.init_page_count,
|
||||
import->u.memory.max_page_count);
|
||||
uint32 flags = import->u.memory.flags;
|
||||
max_memory_pages, import->u.memory.mem_type.init_page_count,
|
||||
import->u.memory.mem_type.max_page_count);
|
||||
uint32 flags = import->u.memory.mem_type.flags;
|
||||
uint32 actual_heap_size = heap_size;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
|
@ -3181,7 +3182,7 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
|
|||
|
||||
if (!is_sub_inst) {
|
||||
#if WASM_ENABLE_WASI_NN != 0
|
||||
wasi_nn_destroy(module_inst);
|
||||
wasi_nn_destroy((WASMModuleInstanceCommon *)module_inst);
|
||||
#endif
|
||||
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
|
||||
}
|
||||
|
|
|
@ -16,23 +16,22 @@ By only including this file in your WASM application you will bind WASI-NN into
|
|||
|
||||
To run the tests we assume that the current directory is the root of the repository.
|
||||
|
||||
|
||||
### Build the runtime
|
||||
|
||||
Build the runtime image for your execution target type.
|
||||
|
||||
`EXECUTION_TYPE` can be:
|
||||
* `cpu`
|
||||
* `nvidia-gpu`
|
||||
* `vx-delegate`
|
||||
* `tpu`
|
||||
|
||||
- `cpu`
|
||||
- `nvidia-gpu`
|
||||
- `vx-delegate`
|
||||
- `tpu`
|
||||
|
||||
```
|
||||
EXECUTION_TYPE=cpu
|
||||
docker build -t wasi-nn-${EXECUTION_TYPE} -f core/iwasm/libraries/wasi-nn/test/Dockerfile.${EXECUTION_TYPE} .
|
||||
```
|
||||
|
||||
|
||||
### Build wasm app
|
||||
|
||||
```
|
||||
|
@ -43,7 +42,6 @@ docker build -t wasi-nn-compile -f core/iwasm/libraries/wasi-nn/test/Dockerfile.
|
|||
docker run -v $PWD/core/iwasm/libraries/wasi-nn:/wasi-nn wasi-nn-compile
|
||||
```
|
||||
|
||||
|
||||
### Run wasm app
|
||||
|
||||
If all the tests have run properly you will the the following message in the terminal,
|
||||
|
@ -52,7 +50,7 @@ If all the tests have run properly you will the the following message in the ter
|
|||
Tests: passed!
|
||||
```
|
||||
|
||||
* CPU
|
||||
- CPU
|
||||
|
||||
```
|
||||
docker run \
|
||||
|
@ -64,9 +62,9 @@ docker run \
|
|||
/assets/test_tensorflow.wasm
|
||||
```
|
||||
|
||||
* (NVIDIA) GPU
|
||||
* Requirements:
|
||||
* [NVIDIA docker](https://github.com/NVIDIA/nvidia-docker).
|
||||
- (NVIDIA) GPU
|
||||
- Requirements:
|
||||
- [NVIDIA docker](https://github.com/NVIDIA/nvidia-docker).
|
||||
|
||||
```
|
||||
docker run \
|
||||
|
@ -79,7 +77,7 @@ docker run \
|
|||
/assets/test_tensorflow.wasm
|
||||
```
|
||||
|
||||
* vx-delegate for NPU (x86 simulator)
|
||||
- vx-delegate for NPU (x86 simulator)
|
||||
|
||||
```
|
||||
docker run \
|
||||
|
@ -90,9 +88,9 @@ docker run \
|
|||
/assets/test_tensorflow_quantized.wasm
|
||||
```
|
||||
|
||||
* (Coral) TPU
|
||||
* Requirements:
|
||||
* [Coral USB](https://coral.ai/products/accelerator/).
|
||||
- (Coral) TPU
|
||||
- Requirements:
|
||||
- [Coral USB](https://coral.ai/products/accelerator/).
|
||||
|
||||
```
|
||||
docker run \
|
||||
|
@ -109,6 +107,45 @@ docker run \
|
|||
|
||||
Supported:
|
||||
|
||||
* Graph encoding: `tensorflowlite`.
|
||||
* Execution target: `cpu`, `gpu` and `tpu`.
|
||||
* Tensor type: `fp32`.
|
||||
- Graph encoding: `tensorflowlite`.
|
||||
- Execution target: `cpu`, `gpu` and `tpu`.
|
||||
- Tensor type: `fp32`.
|
||||
|
||||
## Smoke test
|
||||
|
||||
Use [classification-example](https://github.com/bytecodealliance/wasi-nn/tree/main/rust/examples/classification-example) as a smoke test case to make sure the wasi-nn support in WAMR is working properly.
|
||||
|
||||
> [!Important]
|
||||
> It requires openvino.
|
||||
|
||||
### Prepare the model and the wasm
|
||||
|
||||
``` bash
|
||||
$ pwd
|
||||
/workspaces/wasm-micro-runtime/core/iwasm/libraries/wasi-nn/test
|
||||
|
||||
$ docker build -t wasi-nn-example:v1.0 -f Dockerfile.wasi-nn-example .
|
||||
```
|
||||
|
||||
There are model files(*mobilenet\**) and wasm files(*wasi-nn-example.wasm*) in the directory */workspaces/wasi-nn/rust/examples/classification-example/build* in the image of wasi-nn-example:v1.0.
|
||||
|
||||
### build iwasm and test
|
||||
|
||||
*TODO: May need alternative steps to build the iwasm and test in the container of wasi-nn-example:v1.0*
|
||||
|
||||
``` bash
|
||||
$ pwd
|
||||
/workspaces/wasm-micro-runtime
|
||||
|
||||
$ docker run --rm -it -v $(pwd):/workspaces/wasm-micro-runtime wasi-nn-example:v1.0 /bin/bash
|
||||
```
|
||||
|
||||
> [!Caution]
|
||||
> The following steps are executed in the container of wasi-nn-example:v1.0.
|
||||
|
||||
``` bash
|
||||
$ cd /workspaces/wasm-micro-runtime/product-mini/platforms/linux
|
||||
$ cmake -S . -B build -DWAMR_BUILD_WASI_NN=1 -DWAMR_BUILD_WASI_EPHEMERAL_NN=1
|
||||
$ cmake --build build
|
||||
$ ./build/iwasm -v=5 --map-dir=/workspaces/wasi-nn/rust/examples/classification-example/build/::fixture /workspaces/wasi-nn/rust/examples/classification-example/build/wasi-nn-example.wasm
|
||||
```
|
|
@ -22,9 +22,9 @@
|
|||
* @param encoding Model encoding.
|
||||
* @param target Execution target.
|
||||
* @param g Graph.
|
||||
* @return error Execution status.
|
||||
* @return wasi_nn_error Execution status.
|
||||
*/
|
||||
error
|
||||
wasi_nn_error
|
||||
load(graph_builder_array *builder, graph_encoding encoding,
|
||||
execution_target target, graph *g)
|
||||
__attribute__((import_module("wasi_nn")));
|
||||
|
@ -34,17 +34,14 @@ load(graph_builder_array *builder, graph_encoding encoding,
|
|||
*
|
||||
*/
|
||||
|
||||
// Bind a `graph` to the input and output tensors for an inference.
|
||||
typedef uint32_t graph_execution_context;
|
||||
|
||||
/**
|
||||
* @brief Create an execution instance of a loaded graph.
|
||||
*
|
||||
* @param g Graph.
|
||||
* @param ctx Execution context.
|
||||
* @return error Execution status.
|
||||
* @return wasi_nn_error Execution status.
|
||||
*/
|
||||
error
|
||||
wasi_nn_error
|
||||
init_execution_context(graph g, graph_execution_context *ctx)
|
||||
__attribute__((import_module("wasi_nn")));
|
||||
|
||||
|
@ -54,9 +51,9 @@ init_execution_context(graph g, graph_execution_context *ctx)
|
|||
* @param ctx Execution context.
|
||||
* @param index Input tensor index.
|
||||
* @param tensor Input tensor.
|
||||
* @return error Execution status.
|
||||
* @return wasi_nn_error Execution status.
|
||||
*/
|
||||
error
|
||||
wasi_nn_error
|
||||
set_input(graph_execution_context ctx, uint32_t index, tensor *tensor)
|
||||
__attribute__((import_module("wasi_nn")));
|
||||
|
||||
|
@ -64,9 +61,9 @@ set_input(graph_execution_context ctx, uint32_t index, tensor *tensor)
|
|||
* @brief Compute the inference on the given inputs.
|
||||
*
|
||||
* @param ctx Execution context.
|
||||
* @return error Execution status.
|
||||
* @return wasi_nn_error Execution status.
|
||||
*/
|
||||
error
|
||||
wasi_nn_error
|
||||
compute(graph_execution_context ctx) __attribute__((import_module("wasi_nn")));
|
||||
|
||||
/**
|
||||
|
@ -79,9 +76,9 @@ compute(graph_execution_context ctx) __attribute__((import_module("wasi_nn")));
|
|||
* @param output_tensor_size Pointer to `output_tensor` maximum size.
|
||||
* After the function call it is updated with the
|
||||
* copied number of bytes.
|
||||
* @return error Execution status.
|
||||
* @return wasi_nn_error Execution status.
|
||||
*/
|
||||
error
|
||||
wasi_nn_error
|
||||
get_output(graph_execution_context ctx, uint32_t index,
|
||||
tensor_data output_tensor, uint32_t *output_tensor_size)
|
||||
__attribute__((import_module("wasi_nn")));
|
||||
|
|
|
@ -28,7 +28,7 @@ typedef enum {
|
|||
busy,
|
||||
// Runtime Error.
|
||||
runtime_error,
|
||||
} error;
|
||||
} wasi_nn_error;
|
||||
|
||||
/**
|
||||
* TENSOR
|
||||
|
@ -106,4 +106,7 @@ typedef enum {
|
|||
// Define where the graph should be executed.
|
||||
typedef enum execution_target { cpu = 0, gpu, tpu } execution_target;
|
||||
|
||||
// Bind a `graph` to the input and output tensors for an inference.
|
||||
typedef uint32_t graph_execution_context;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "wasi_nn_app_native.h"
|
||||
|
||||
static error
|
||||
static wasi_nn_error
|
||||
graph_builder_app_native(wasm_module_inst_t instance,
|
||||
graph_builder_wasm *builder_wasm,
|
||||
graph_builder *builder)
|
||||
|
@ -27,12 +27,12 @@ graph_builder_app_native(wasm_module_inst_t instance,
|
|||
* builder_array_wasm is consisted of {builder_wasm, size}
|
||||
*/
|
||||
#if WASM_ENABLE_WASI_EPHEMERAL_NN != 0
|
||||
error
|
||||
wasi_nn_error
|
||||
graph_builder_array_app_native(wasm_module_inst_t instance,
|
||||
graph_builder_wasm *builder_wasm, uint32_t size,
|
||||
graph_builder_array *builder_array)
|
||||
#else /* WASM_ENABLE_WASI_EPHEMERAL_NN == 0 */
|
||||
error
|
||||
wasi_nn_error
|
||||
graph_builder_array_app_native(wasm_module_inst_t instance,
|
||||
graph_builder_array_wasm *builder_array_wasm,
|
||||
graph_builder_array *builder_array)
|
||||
|
@ -79,7 +79,7 @@ graph_builder_array_app_native(wasm_module_inst_t instance,
|
|||
return missing_memory;
|
||||
|
||||
for (uint32_t i = 0; i < array_size; ++i) {
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
if (success
|
||||
!= (res = graph_builder_app_native(instance, &builder_wasm[i],
|
||||
&builder[i]))) {
|
||||
|
@ -97,7 +97,7 @@ graph_builder_array_app_native(wasm_module_inst_t instance,
|
|||
#undef array_size
|
||||
}
|
||||
|
||||
static error
|
||||
static wasi_nn_error
|
||||
tensor_data_app_native(wasm_module_inst_t instance, uint32_t total_elements,
|
||||
tensor_wasm *input_tensor_wasm, tensor_data *data)
|
||||
{
|
||||
|
@ -119,7 +119,7 @@ tensor_data_app_native(wasm_module_inst_t instance, uint32_t total_elements,
|
|||
#undef data_size
|
||||
}
|
||||
|
||||
static error
|
||||
static wasi_nn_error
|
||||
tensor_dimensions_app_native(wasm_module_inst_t instance,
|
||||
tensor_wasm *input_tensor_wasm,
|
||||
tensor_dimensions **dimensions)
|
||||
|
@ -159,7 +159,7 @@ tensor_dimensions_app_native(wasm_module_inst_t instance,
|
|||
return success;
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensor_app_native(wasm_module_inst_t instance, tensor_wasm *input_tensor_wasm,
|
||||
tensor *input_tensor)
|
||||
{
|
||||
|
@ -170,7 +170,7 @@ tensor_app_native(wasm_module_inst_t instance, tensor_wasm *input_tensor_wasm,
|
|||
return invalid_argument;
|
||||
}
|
||||
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
|
||||
tensor_dimensions *dimensions = NULL;
|
||||
if (success
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wasi_nn.h"
|
||||
#include "wasi_nn_types.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
@ -47,18 +47,18 @@ typedef struct {
|
|||
} tensor_wasm;
|
||||
|
||||
#if WASM_ENABLE_WASI_EPHEMERAL_NN != 0
|
||||
error
|
||||
wasi_nn_error
|
||||
graph_builder_array_app_native(wasm_module_inst_t instance,
|
||||
graph_builder_wasm *builder_wasm, uint32_t size,
|
||||
graph_builder_array *builder_array);
|
||||
#else /* WASM_ENABLE_WASI_EPHEMERAL_NN == 0 */
|
||||
error
|
||||
wasi_nn_error
|
||||
graph_builder_array_app_native(wasm_module_inst_t instance,
|
||||
graph_builder_array_wasm *builder,
|
||||
graph_builder_array *builder_native);
|
||||
#endif /* WASM_ENABLE_WASI_EPHEMERAL_NN != 0 */
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensor_app_native(wasm_module_inst_t instance, tensor_wasm *input_tensor,
|
||||
tensor *input_tensor_native);
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "wasi_nn.h"
|
||||
#include "wasi_nn_private.h"
|
||||
#include "wasi_nn_app_native.h"
|
||||
#include "wasi_nn_tensorflowlite.hpp"
|
||||
|
@ -24,14 +23,15 @@
|
|||
|
||||
/* Definition of 'wasi_nn.h' structs in WASM app format (using offset) */
|
||||
|
||||
typedef error (*LOAD)(void *, graph_builder_array *, graph_encoding,
|
||||
execution_target, graph *);
|
||||
typedef error (*INIT_EXECUTION_CONTEXT)(void *, graph,
|
||||
graph_execution_context *);
|
||||
typedef error (*SET_INPUT)(void *, graph_execution_context, uint32_t, tensor *);
|
||||
typedef error (*COMPUTE)(void *, graph_execution_context);
|
||||
typedef error (*GET_OUTPUT)(void *, graph_execution_context, uint32_t,
|
||||
tensor_data, uint32_t *);
|
||||
typedef wasi_nn_error (*LOAD)(void *, graph_builder_array *, graph_encoding,
|
||||
execution_target, graph *);
|
||||
typedef wasi_nn_error (*INIT_EXECUTION_CONTEXT)(void *, graph,
|
||||
graph_execution_context *);
|
||||
typedef wasi_nn_error (*SET_INPUT)(void *, graph_execution_context, uint32_t,
|
||||
tensor *);
|
||||
typedef wasi_nn_error (*COMPUTE)(void *, graph_execution_context);
|
||||
typedef wasi_nn_error (*GET_OUTPUT)(void *, graph_execution_context, uint32_t,
|
||||
tensor_data, uint32_t *);
|
||||
|
||||
typedef struct {
|
||||
LOAD load;
|
||||
|
@ -177,7 +177,7 @@ is_encoding_implemented(graph_encoding encoding)
|
|||
&& lookup[encoding].get_output;
|
||||
}
|
||||
|
||||
static error
|
||||
static wasi_nn_error
|
||||
is_model_initialized(WASINNContext *wasi_nn_ctx)
|
||||
{
|
||||
if (!wasi_nn_ctx->is_model_loaded) {
|
||||
|
@ -190,12 +190,12 @@ is_model_initialized(WASINNContext *wasi_nn_ctx)
|
|||
/* WASI-NN implementation */
|
||||
|
||||
#if WASM_ENABLE_WASI_EPHEMERAL_NN != 0
|
||||
error
|
||||
wasi_nn_error
|
||||
wasi_nn_load(wasm_exec_env_t exec_env, graph_builder_wasm *builder,
|
||||
uint32_t builder_wasm_size, graph_encoding encoding,
|
||||
execution_target target, graph *g)
|
||||
#else /* WASM_ENABLE_WASI_EPHEMERAL_NN == 0 */
|
||||
error
|
||||
wasi_nn_error
|
||||
wasi_nn_load(wasm_exec_env_t exec_env, graph_builder_array_wasm *builder,
|
||||
graph_encoding encoding, execution_target target, graph *g)
|
||||
#endif /* WASM_ENABLE_WASI_EPHEMERAL_NN != 0 */
|
||||
|
@ -211,7 +211,7 @@ wasi_nn_load(wasm_exec_env_t exec_env, graph_builder_array_wasm *builder,
|
|||
wasm_module_inst_t instance = wasm_runtime_get_module_inst(exec_env);
|
||||
bh_assert(instance);
|
||||
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
graph_builder_array builder_native = { 0 };
|
||||
#if WASM_ENABLE_WASI_EPHEMERAL_NN != 0
|
||||
if (success
|
||||
|
@ -249,7 +249,7 @@ fail:
|
|||
return res;
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasi_nn_init_execution_context(wasm_exec_env_t exec_env, graph g,
|
||||
graph_execution_context *ctx)
|
||||
{
|
||||
|
@ -259,7 +259,7 @@ wasi_nn_init_execution_context(wasm_exec_env_t exec_env, graph g,
|
|||
bh_assert(instance);
|
||||
WASINNContext *wasi_nn_ctx = wasm_runtime_get_wasi_nn_ctx(instance);
|
||||
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
if (success != (res = is_model_initialized(wasi_nn_ctx)))
|
||||
return res;
|
||||
|
||||
|
@ -278,7 +278,7 @@ wasi_nn_init_execution_context(wasm_exec_env_t exec_env, graph g,
|
|||
return res;
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasi_nn_set_input(wasm_exec_env_t exec_env, graph_execution_context ctx,
|
||||
uint32_t index, tensor_wasm *input_tensor)
|
||||
{
|
||||
|
@ -289,7 +289,7 @@ wasi_nn_set_input(wasm_exec_env_t exec_env, graph_execution_context ctx,
|
|||
bh_assert(instance);
|
||||
WASINNContext *wasi_nn_ctx = wasm_runtime_get_wasi_nn_ctx(instance);
|
||||
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
if (success != (res = is_model_initialized(wasi_nn_ctx)))
|
||||
return res;
|
||||
|
||||
|
@ -310,7 +310,7 @@ wasi_nn_set_input(wasm_exec_env_t exec_env, graph_execution_context ctx,
|
|||
return res;
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasi_nn_compute(wasm_exec_env_t exec_env, graph_execution_context ctx)
|
||||
{
|
||||
NN_DBG_PRINTF("Running wasi_nn_compute [ctx=%d]...", ctx);
|
||||
|
@ -319,7 +319,7 @@ wasi_nn_compute(wasm_exec_env_t exec_env, graph_execution_context ctx)
|
|||
bh_assert(instance);
|
||||
WASINNContext *wasi_nn_ctx = wasm_runtime_get_wasi_nn_ctx(instance);
|
||||
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
if (success != (res = is_model_initialized(wasi_nn_ctx)))
|
||||
return res;
|
||||
|
||||
|
@ -330,12 +330,12 @@ wasi_nn_compute(wasm_exec_env_t exec_env, graph_execution_context ctx)
|
|||
}
|
||||
|
||||
#if WASM_ENABLE_WASI_EPHEMERAL_NN != 0
|
||||
error
|
||||
wasi_nn_error
|
||||
wasi_nn_get_output(wasm_exec_env_t exec_env, graph_execution_context ctx,
|
||||
uint32_t index, tensor_data output_tensor,
|
||||
uint32_t output_tensor_len, uint32_t *output_tensor_size)
|
||||
#else /* WASM_ENABLE_WASI_EPHEMERAL_NN == 0 */
|
||||
error
|
||||
wasi_nn_error
|
||||
wasi_nn_get_output(wasm_exec_env_t exec_env, graph_execution_context ctx,
|
||||
uint32_t index, tensor_data output_tensor,
|
||||
uint32_t *output_tensor_size)
|
||||
|
@ -348,7 +348,7 @@ wasi_nn_get_output(wasm_exec_env_t exec_env, graph_execution_context ctx,
|
|||
bh_assert(instance);
|
||||
WASINNContext *wasi_nn_ctx = wasm_runtime_get_wasi_nn_ctx(instance);
|
||||
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
if (success != (res = is_model_initialized(wasi_nn_ctx)))
|
||||
return res;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "wasi_nn.h"
|
||||
#include "wasi_nn_types.h"
|
||||
#include "wasi_nn_tensorflowlite.hpp"
|
||||
#include "logger.h"
|
||||
|
||||
|
@ -50,7 +50,7 @@ typedef struct {
|
|||
|
||||
/* Utils */
|
||||
|
||||
static error
|
||||
static wasi_nn_error
|
||||
initialize_g(TFLiteContext *tfl_ctx, graph *g)
|
||||
{
|
||||
os_mutex_lock(&tfl_ctx->g_lock);
|
||||
|
@ -63,7 +63,7 @@ initialize_g(TFLiteContext *tfl_ctx, graph *g)
|
|||
os_mutex_unlock(&tfl_ctx->g_lock);
|
||||
return success;
|
||||
}
|
||||
static error
|
||||
static wasi_nn_error
|
||||
initialize_graph_ctx(TFLiteContext *tfl_ctx, graph g,
|
||||
graph_execution_context *ctx)
|
||||
{
|
||||
|
@ -78,7 +78,7 @@ initialize_graph_ctx(TFLiteContext *tfl_ctx, graph g,
|
|||
return success;
|
||||
}
|
||||
|
||||
static error
|
||||
static wasi_nn_error
|
||||
is_valid_graph(TFLiteContext *tfl_ctx, graph g)
|
||||
{
|
||||
if (g >= MAX_GRAPHS_PER_INST) {
|
||||
|
@ -96,7 +96,7 @@ is_valid_graph(TFLiteContext *tfl_ctx, graph g)
|
|||
return success;
|
||||
}
|
||||
|
||||
static error
|
||||
static wasi_nn_error
|
||||
is_valid_graph_execution_context(TFLiteContext *tfl_ctx,
|
||||
graph_execution_context ctx)
|
||||
{
|
||||
|
@ -114,7 +114,7 @@ is_valid_graph_execution_context(TFLiteContext *tfl_ctx,
|
|||
|
||||
/* WASI-NN (tensorflow) implementation */
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensorflowlite_load(void *tflite_ctx, graph_builder_array *builder,
|
||||
graph_encoding encoding, execution_target target, graph *g)
|
||||
{
|
||||
|
@ -135,7 +135,7 @@ tensorflowlite_load(void *tflite_ctx, graph_builder_array *builder,
|
|||
return invalid_argument;
|
||||
}
|
||||
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
if (success != (res = initialize_g(tfl_ctx, g)))
|
||||
return res;
|
||||
|
||||
|
@ -168,13 +168,13 @@ tensorflowlite_load(void *tflite_ctx, graph_builder_array *builder,
|
|||
return success;
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensorflowlite_init_execution_context(void *tflite_ctx, graph g,
|
||||
graph_execution_context *ctx)
|
||||
{
|
||||
TFLiteContext *tfl_ctx = (TFLiteContext *)tflite_ctx;
|
||||
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
if (success != (res = is_valid_graph(tfl_ctx, g)))
|
||||
return res;
|
||||
|
||||
|
@ -257,13 +257,13 @@ tensorflowlite_init_execution_context(void *tflite_ctx, graph g,
|
|||
return success;
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensorflowlite_set_input(void *tflite_ctx, graph_execution_context ctx,
|
||||
uint32_t index, tensor *input_tensor)
|
||||
{
|
||||
TFLiteContext *tfl_ctx = (TFLiteContext *)tflite_ctx;
|
||||
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
if (success != (res = is_valid_graph_execution_context(tfl_ctx, ctx)))
|
||||
return res;
|
||||
|
||||
|
@ -328,12 +328,12 @@ tensorflowlite_set_input(void *tflite_ctx, graph_execution_context ctx,
|
|||
return success;
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensorflowlite_compute(void *tflite_ctx, graph_execution_context ctx)
|
||||
{
|
||||
TFLiteContext *tfl_ctx = (TFLiteContext *)tflite_ctx;
|
||||
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
if (success != (res = is_valid_graph_execution_context(tfl_ctx, ctx)))
|
||||
return res;
|
||||
|
||||
|
@ -341,14 +341,14 @@ tensorflowlite_compute(void *tflite_ctx, graph_execution_context ctx)
|
|||
return success;
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensorflowlite_get_output(void *tflite_ctx, graph_execution_context ctx,
|
||||
uint32_t index, tensor_data output_tensor,
|
||||
uint32_t *output_tensor_size)
|
||||
{
|
||||
TFLiteContext *tfl_ctx = (TFLiteContext *)tflite_ctx;
|
||||
|
||||
error res;
|
||||
wasi_nn_error res;
|
||||
if (success != (res = is_valid_graph_execution_context(tfl_ctx, ctx)))
|
||||
return res;
|
||||
|
||||
|
@ -472,6 +472,8 @@ tensorflowlite_destroy(void *tflite_ctx)
|
|||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
wasm_runtime_free(tfl_ctx->models[i].model_pointer);
|
||||
|
|
|
@ -6,28 +6,28 @@
|
|||
#ifndef WASI_NN_TENSORFLOWLITE_HPP
|
||||
#define WASI_NN_TENSORFLOWLITE_HPP
|
||||
|
||||
#include "wasi_nn.h"
|
||||
#include "wasi_nn_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensorflowlite_load(void *tflite_ctx, graph_builder_array *builder,
|
||||
graph_encoding encoding, execution_target target, graph *g);
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensorflowlite_init_execution_context(void *tflite_ctx, graph g,
|
||||
graph_execution_context *ctx);
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensorflowlite_set_input(void *tflite_ctx, graph_execution_context ctx,
|
||||
uint32_t index, tensor *input_tensor);
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensorflowlite_compute(void *tflite_ctx, graph_execution_context ctx);
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
tensorflowlite_get_output(void *tflite_ctx, graph_execution_context ctx,
|
||||
uint32_t index, tensor_data output_tensor,
|
||||
uint32_t *output_tensor_size);
|
||||
|
|
57
core/iwasm/libraries/wasi-nn/test/Dockerfile.wasi-nn-example
Normal file
57
core/iwasm/libraries/wasi-nn/test/Dockerfile.wasi-nn-example
Normal file
|
@ -0,0 +1,57 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Asian/Shanghai
|
||||
|
||||
# hadolint ignore=DL3009
|
||||
RUN apt-get update \
|
||||
&& apt-get upgrade -y
|
||||
|
||||
#
|
||||
# Rust targets
|
||||
RUN rustup target add wasm32-wasi wasm32-unknown-unknown
|
||||
|
||||
#
|
||||
# Openvino
|
||||
# Refer to
|
||||
# - https://docs.openvino.ai/2022.3/openvino_docs_install_guides_installing_openvino_from_archive_linux.html
|
||||
# - https://docs.openvino.ai/2023.3/openvino_docs_install_guides_installing_openvino_from_archive_linux.html
|
||||
# - https://docs.openvino.ai/2024/get-started/install-openvino/install-openvino-archive-linux.html
|
||||
#
|
||||
# FIXME: upgrade to 2024.1 or latest after wasi-nn(rust binding) is ready
|
||||
WORKDIR /opt/intel
|
||||
RUN wget -q https://storage.openvinotoolkit.org/repositories/openvino/packages/2022.3.2/linux/l_openvino_toolkit_ubuntu20_2022.3.2.9279.e2c7e4d7b4d_x86_64.tgz
|
||||
RUN tar -xf l_openvino_toolkit_ubuntu20_2022.3.2.9279.e2c7e4d7b4d_x86_64.tgz \
|
||||
&& rm l_openvino_toolkit_ubuntu20_2022.3.2.9279.e2c7e4d7b4d_x86_64.tgz \
|
||||
&& mv l_openvino_toolkit_ubuntu20_2022.3.2.9279.e2c7e4d7b4d_x86_64 /opt/intel/openvino
|
||||
|
||||
WORKDIR /opt/intel/openvino
|
||||
RUN ./install_dependencies/install_openvino_dependencies.sh -y \
|
||||
&& ./setupvars.sh
|
||||
|
||||
#
|
||||
# wasmtime
|
||||
WORKDIR /opt
|
||||
RUN wget -q https://github.com/bytecodealliance/wasmtime/releases/download/v21.0.0/wasmtime-v21.0.0-x86_64-linux.tar.xz
|
||||
RUN tar -xf wasmtime-v21.0.0-x86_64-linux.tar.xz \
|
||||
&& rm wasmtime-v21.0.0-x86_64-linux.tar.xz \
|
||||
&& ln -sf "$(realpath ./wasmtime-v21.0.0-x86_64-linux/wasmtime)" /usr/local/bin/wasmtime
|
||||
|
||||
#
|
||||
# wasi-nn
|
||||
WORKDIR /workspaces/wasi-nn
|
||||
RUN git clone --depth 1 https://github.com/bytecodealliance/wasi-nn.git .
|
||||
# hadolint ignore=DL3059
|
||||
RUN ./build.sh rust
|
||||
|
||||
# There are model files(mobilenet*) and wasm files(wasi-nn-example.wasm) in the directory,
|
||||
# /workspaces/wasi-nn/rust/examples/classification-example/build
|
||||
|
||||
RUN apt-get autoremove -y \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /tmp/*
|
||||
|
||||
WORKDIR /workspaces
|
|
@ -9,7 +9,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasm_load(char *model_name, graph *g, execution_target target)
|
||||
{
|
||||
FILE *pFile = fopen(model_name, "r");
|
||||
|
@ -46,7 +46,7 @@ wasm_load(char *model_name, graph *g, execution_target target)
|
|||
arr.buf[0].size = result;
|
||||
arr.buf[0].buf = buffer;
|
||||
|
||||
error res = load(&arr, tensorflowlite, target, g);
|
||||
wasi_nn_error res = load(&arr, tensorflowlite, target, g);
|
||||
|
||||
fclose(pFile);
|
||||
free(buffer);
|
||||
|
@ -54,13 +54,13 @@ wasm_load(char *model_name, graph *g, execution_target target)
|
|||
return res;
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasm_init_execution_context(graph g, graph_execution_context *ctx)
|
||||
{
|
||||
return init_execution_context(g, ctx);
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasm_set_input(graph_execution_context ctx, float *input_tensor, uint32_t *dim)
|
||||
{
|
||||
tensor_dimensions dims;
|
||||
|
@ -75,19 +75,19 @@ wasm_set_input(graph_execution_context ctx, float *input_tensor, uint32_t *dim)
|
|||
tensor.dimensions->buf[i] = dim[i];
|
||||
tensor.type = fp32;
|
||||
tensor.data = (uint8_t *)input_tensor;
|
||||
error err = set_input(ctx, 0, &tensor);
|
||||
wasi_nn_error err = set_input(ctx, 0, &tensor);
|
||||
|
||||
free(dims.buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasm_compute(graph_execution_context ctx)
|
||||
{
|
||||
return compute(ctx);
|
||||
}
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasm_get_output(graph_execution_context ctx, uint32_t index, float *out_tensor,
|
||||
uint32_t *out_size)
|
||||
{
|
||||
|
|
|
@ -23,19 +23,19 @@ typedef struct {
|
|||
|
||||
/* wasi-nn wrappers */
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasm_load(char *model_name, graph *g, execution_target target);
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasm_init_execution_context(graph g, graph_execution_context *ctx);
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasm_set_input(graph_execution_context ctx, float *input_tensor, uint32_t *dim);
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasm_compute(graph_execution_context ctx);
|
||||
|
||||
error
|
||||
wasi_nn_error
|
||||
wasm_get_output(graph_execution_context ctx, uint32_t index, float *out_tensor,
|
||||
uint32_t *out_size);
|
||||
|
||||
|
|
|
@ -9,6 +9,11 @@ if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1)
|
|||
list(REMOVE_ITEM source_all
|
||||
${PLATFORM_COMMON_POSIX_DIR}/posix_file.c
|
||||
${PLATFORM_COMMON_POSIX_DIR}/posix_clock.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if ((NOT WAMR_BUILD_LIBC_WASI EQUAL 1) AND (NOT WAMR_BUILD_DEBUG_INTERP EQUAL 1))
|
||||
list(REMOVE_ITEM source_all
|
||||
${PLATFORM_COMMON_POSIX_DIR}/posix_socket.c
|
||||
)
|
||||
else()
|
||||
|
|
|
@ -94,4 +94,12 @@ os_get_invalid_handle()
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* There is no MMU in RIOT so the function return 1024 to make the compiler
|
||||
happy */
|
||||
static inline int
|
||||
os_getpagesize()
|
||||
{
|
||||
return 1024;
|
||||
}
|
||||
|
||||
#endif /* end of _BH_PLATFORM_H */
|
||||
|
|
|
@ -57,6 +57,12 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
|
|||
return BH_MALLOC((unsigned)size);
|
||||
}
|
||||
|
||||
void *
|
||||
os_mremap(void *old_addr, size_t old_size, size_t new_size)
|
||||
{
|
||||
return os_mremap_slow(old_addr, old_size, new_size);
|
||||
}
|
||||
|
||||
void
|
||||
os_munmap(void *addr, size_t size)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
#ifndef _WAMR_VERSION_H_
|
||||
#define _WAMR_VERSION_H_
|
||||
#define WAMR_VERSION_MAJOR 2
|
||||
#define WAMR_VERSION_MINOR 0
|
||||
#define WAMR_VERSION_MINOR 1
|
||||
#define WAMR_VERSION_PATCH 0
|
||||
#endif
|
||||
|
|
|
@ -105,6 +105,8 @@ set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
|
|||
|
||||
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||
|
||||
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections -pie -fPIE")
|
||||
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
|
||||
|
|
|
@ -535,21 +535,23 @@ void *
|
|||
timeout_thread(void *vp)
|
||||
{
|
||||
const struct timeout_arg *arg = vp;
|
||||
uint32 left = arg->timeout_ms;
|
||||
const uint64 end_time =
|
||||
os_time_get_boot_us() + (uint64)arg->timeout_ms * 1000;
|
||||
while (!arg->cancel) {
|
||||
uint32 ms;
|
||||
if (left >= 100) {
|
||||
ms = 100;
|
||||
}
|
||||
else {
|
||||
ms = left;
|
||||
}
|
||||
os_usleep((uint64)ms * 1000);
|
||||
left -= ms;
|
||||
if (left == 0) {
|
||||
const uint64 now = os_time_get_boot_us();
|
||||
if ((int64)(now - end_time) > 0) {
|
||||
wasm_runtime_terminate(arg->inst);
|
||||
break;
|
||||
}
|
||||
const uint64 left_us = end_time - now;
|
||||
uint32 us;
|
||||
if (left_us >= 100 * 1000) {
|
||||
us = 100 * 1000;
|
||||
}
|
||||
else {
|
||||
us = left_us;
|
||||
}
|
||||
os_usleep(us);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -272,9 +272,9 @@ DumpDetails(AoTFile *aot)
|
|||
AOTImportMemory memory = import_memories[index];
|
||||
printf(" -[%u] num_bytes_per_page:%5u init_page_count:%5u "
|
||||
"max_page_count:%5u module_name: %s memory_name: %s\n",
|
||||
index, memory.num_bytes_per_page, memory.mem_init_page_count,
|
||||
memory.mem_max_page_count, memory.module_name,
|
||||
memory.memory_name);
|
||||
index, memory.memory.num_bytes_per_page,
|
||||
memory.memory.init_page_count, memory.memory.max_page_count,
|
||||
memory.module_name, memory.memory_name);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
@ -365,10 +365,10 @@ DumpDetails(AoTFile *aot)
|
|||
|
||||
for (uint32_t index = 0; index < memory_count; index++) {
|
||||
AOTMemory memory = memories[index];
|
||||
printf(" -[%u] memory_flags:%5u bytes_per_page:%5u "
|
||||
printf(" -[%u] flags:%5u bytes_per_page:%5u "
|
||||
"init_page_count:%5u max_page_count:%5u\n",
|
||||
index, memory.memory_flags, memory.num_bytes_per_page,
|
||||
memory.mem_init_page_count, memory.mem_max_page_count);
|
||||
index, memory.flags, memory.num_bytes_per_page,
|
||||
memory.init_page_count, memory.max_page_count);
|
||||
}
|
||||
printf("\n\n");
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node16",
|
||||
"target": "es6",
|
||||
"outDir": "out",
|
||||
"lib": ["es6"],
|
||||
|
|
|
@ -58,12 +58,12 @@ endif ()
|
|||
|
||||
if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
|
||||
# Enable libc builtin support by default
|
||||
set (WAMR_BUILD_LIBC_BUILTIN 1)
|
||||
set (WAMR_BUILD_LIBC_BUILTIN 0)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
|
||||
# Enable libc wasi support by default
|
||||
set (WAMR_BUILD_LIBC_WASI 1)
|
||||
set (WAMR_BUILD_LIBC_WASI 0)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_FAST_INTERP)
|
||||
|
@ -92,8 +92,8 @@ if (NOT DEFINED WAMR_BUILD_SIMD)
|
|||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_REF_TYPES)
|
||||
# Disable reference types by default
|
||||
set (WAMR_BUILD_REF_TYPES 0)
|
||||
# Enable reference type by default
|
||||
set (WAMR_BUILD_REF_TYPES 1)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_DEBUG_INTERP)
|
||||
|
@ -113,7 +113,7 @@ message([ceith]:REPO_ROOT_DIR, ${REPO_ROOT_DIR})
|
|||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
add_definitions(-DWAMR_USE_MEM_POOL=0)
|
||||
add_definitions(-DWAMR_USE_MEM_POOL=0 -DWASM_ENABLE_FUZZ_TEST=1)
|
||||
|
||||
# Enable fuzzer
|
||||
add_compile_options(-fsanitize=fuzzer)
|
||||
|
|
|
@ -8,51 +8,61 @@
|
|||
# 1.check parameter
|
||||
if [ ! $1 ]; then
|
||||
echo "Parameter is empty, please enter parameter !"
|
||||
exit
|
||||
exit
|
||||
fi
|
||||
EXPECTED_NUM=$1
|
||||
|
||||
# 2.check dir
|
||||
buildPath="./build"
|
||||
corpusPath="$buildPath/CORPUS_DIR"
|
||||
if [[ ! -d "$buildPath" ]]; then
|
||||
echo "auto create the build folder !"
|
||||
mkdir build
|
||||
else # build Folder exists
|
||||
if [[ -d "$buildPath" ]]; then # CORPUS_DIR exists
|
||||
rm -rf $corpusPath
|
||||
fi
|
||||
fi
|
||||
rm -rf "${corpusPath}"
|
||||
mkdir -p "${corpusPath}"
|
||||
|
||||
# 3.change dir
|
||||
# cd build && mkdir CORPUS_DIR && cd CORPUS_DIR
|
||||
cd build && mkdir CORPUS_DIR && cd CORPUS_DIR
|
||||
cd "${corpusPath}"
|
||||
|
||||
# 4.generate *.wasm file
|
||||
echo "Generate $@ files according to user requirements"
|
||||
echo "Generating $EXPECTED_NUM Wasm files for each kind as required"
|
||||
|
||||
for((i=1; i<($@+1); i++));
|
||||
# Generate wasm files with different features
|
||||
# Try on and on until the generated wasm file exists
|
||||
function try_generate_wasm()
|
||||
{
|
||||
SMITH_OPTIONS=$1
|
||||
GENERATED_WASM_NAME=$2
|
||||
|
||||
local try_i=0
|
||||
until [[ -f $GENERATED_WASM_NAME ]]; do
|
||||
head -c 100 /dev/urandom | wasm-tools smith $SMITH_OPTIONS -o $GENERATED_WASM_NAME >/dev/null 2>&1
|
||||
try_i=$((try_i+1))
|
||||
done
|
||||
|
||||
printf -- "-- output ${GENERATED_WASM_NAME} in %d retries\n" $try_i
|
||||
}
|
||||
|
||||
# try_generate_wasm "--min-memories=1 --min-tables=1" "test_min.wasm"
|
||||
|
||||
for i in $(seq 1 $EXPECTED_NUM)
|
||||
do
|
||||
head -c 100 /dev/urandom | wasm-tools smith -o test_$i.wasm
|
||||
# by default
|
||||
try_generate_wasm "" test_$i.wasm
|
||||
|
||||
# with different features
|
||||
# mvp
|
||||
try_generate_wasm "--min-memories=1 --min-tables=1" test_min_$i.wasm
|
||||
try_generate_wasm "--min-memories=1 --min-tables=1 --bulk-memory-enabled true" test_bulk_$i.wasm
|
||||
try_generate_wasm "--min-memories=1 --min-tables=1 --reference-types-enabled true" test_ref_$i.wasm
|
||||
try_generate_wasm "--min-memories=1 --min-tables=1 --multi-value-enabled true" test_multi_$i.wasm
|
||||
try_generate_wasm "--min-memories=1 --min-tables=1 --simd-enabled true" test_simd_$i.wasm
|
||||
try_generate_wasm "--min-memories=1 --min-tables=1 --tail-call-enabled true " test_tail_$i.wasm
|
||||
|
||||
# enable me when compiling iwasm with those features
|
||||
#try_generate_wasm "--min-memories=1 --min-tables=1 --threads-enabled true" test_thread_$i.wasm
|
||||
#try_generate_wasm "--min-memories=1 --min-tables=1 --memory64-enabled true" test_memory64_$i.wasm
|
||||
#try_generate_wasm "--min-memories=1 --min-tables=1 --exceptions-enabled true" test_exception_$i.wasm
|
||||
#try_generate_wasm "--min-memories=1 --min-tables=1 --gc-enabled true" test_gc_$i.wasm
|
||||
# with custom-section
|
||||
try_generate_wasm "--min-memories=1 --min-tables=1 --generate-custom-sections true" test_custom_$i.wasm
|
||||
done
|
||||
|
||||
# 5.check wasm file
|
||||
dir=$(pwd)
|
||||
d=$(find . ! -name "." -type d -prune -o -type f -name "*.wasm" -print)
|
||||
#echo "current dir=$dir"
|
||||
num=0
|
||||
|
||||
for((i=1; i<($@+1); i++));
|
||||
do
|
||||
wasmFile="test_$i.wasm"
|
||||
if [[ ! -f "$wasmFile" ]]; then
|
||||
echo "The file $wasmFile is not exists !"
|
||||
else
|
||||
let "num++"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "$@ user requirements, $num actually generated !"
|
||||
|
||||
if [ $num == $@ ]; then echo "Wasm file generated successfully !"
|
||||
else echo "Wasm file generated faild !"
|
||||
fi
|
||||
printf "Done\n"
|
||||
|
|
|
@ -92,8 +92,8 @@ if (NOT DEFINED WAMR_BUILD_SIMD)
|
|||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_REF_TYPES)
|
||||
# Disable reference types by default
|
||||
set (WAMR_BUILD_REF_TYPES 0)
|
||||
# Enable reference type by default
|
||||
set (WAMR_BUILD_REF_TYPES 1)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_DEBUG_INTERP)
|
||||
|
@ -113,7 +113,7 @@ message([ceith]:REPO_ROOT_DIR, ${REPO_ROOT_DIR})
|
|||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
add_definitions(-DWAMR_USE_MEM_POOL=0)
|
||||
add_definitions(-DWAMR_USE_MEM_POOL=0 -DWASM_ENABLE_FUZZ_TEST=1)
|
||||
|
||||
# Enable fuzzer
|
||||
add_compile_options(-fsanitize=fuzzer)
|
||||
|
|
BIN
tests/regression/ba-issues/issues/issue-3467/tt_unreachable.wasm
Normal file
BIN
tests/regression/ba-issues/issues/issue-3467/tt_unreachable.wasm
Normal file
Binary file not shown.
BIN
tests/regression/ba-issues/issues/issue-3468/i64.add.wasm
Normal file
BIN
tests/regression/ba-issues/issues/issue-3468/i64.add.wasm
Normal file
Binary file not shown.
Binary file not shown.
|
@ -912,7 +912,7 @@
|
|||
"options": "",
|
||||
"argument": "",
|
||||
"expected return": {
|
||||
"ret code": 57,
|
||||
"ret code": 8,
|
||||
"stdout content": "",
|
||||
"description": "sock_shutdown on a non-socket file descriptor should fail with 57 notsock"
|
||||
}
|
||||
|
@ -1674,6 +1674,54 @@
|
|||
"stdout content": "Hello from Kotlin via WASI\nCurrent 'realtime' timestamp is:",
|
||||
"description": "no 'type mismatch: expect (ref null ht) but got other1 unknown type'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"deprecated": false,
|
||||
"ids": [
|
||||
3467
|
||||
],
|
||||
"runtime": "iwasm-default-wasi-disabled",
|
||||
"file": "tt_unreachable.wasm",
|
||||
"mode": "fast-interp",
|
||||
"options": "--heap-size=0 -f to_test",
|
||||
"argument": "",
|
||||
"expected return": {
|
||||
"ret code": 1,
|
||||
"stdout content": "Exception: unreachable",
|
||||
"description": "no '-1.861157e+19:f32'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"deprecated": false,
|
||||
"ids": [
|
||||
3468
|
||||
],
|
||||
"runtime": "iwasm-default-wasi-disabled",
|
||||
"file": "i64.add.wasm",
|
||||
"mode": "fast-interp",
|
||||
"options": "--heap-size=0 -f to_test",
|
||||
"argument": "",
|
||||
"expected return": {
|
||||
"ret code": 255,
|
||||
"stdout content": "WASM module load failed: unknown type",
|
||||
"description": "no '0x0:i64'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"deprecated": false,
|
||||
"ids": [
|
||||
3491
|
||||
],
|
||||
"runtime": "iwasm-default-wasi-disabled",
|
||||
"file": "nop_0LM_592_17171016522810388.wasm",
|
||||
"mode": "fast-interp",
|
||||
"options": "",
|
||||
"argument": "",
|
||||
"expected return": {
|
||||
"ret code": 255,
|
||||
"stdout content": "WASM module load failed: data count and data section have inconsistent lengths",
|
||||
"description": "Check data segment count"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,51 +1,52 @@
|
|||
# Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required (VERSION 3.14)
|
||||
cmake_minimum_required(VERSION 2.9)
|
||||
|
||||
project (wamr_unit_tests)
|
||||
project(unit-test)
|
||||
|
||||
include (CTest)
|
||||
SET(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_INTERP)
|
||||
# Enable Interpreter by default
|
||||
set (WAMR_BUILD_INTERP 1)
|
||||
endif ()
|
||||
# add_definitions (-m32)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_PLATFORM)
|
||||
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
||||
endif ()
|
||||
if(WAMR_BUILD_TARGET STREQUAL "X86_32")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
|
||||
endif()
|
||||
|
||||
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||
add_library (vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
# Prevent overriding the parent project's compiler/linker
|
||||
# settings on Windows
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
|
||||
# Fetch Google test
|
||||
include (FetchContent)
|
||||
FetchContent_Declare (
|
||||
googletest
|
||||
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
|
||||
)
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
set (gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
FetchContent_MakeAvailable (googletest)
|
||||
|
||||
include (GoogleTest)
|
||||
SET(GOOGLETEST_INCLUDED 1)
|
||||
|
||||
add_library (wamr_gtest_main main.cpp)
|
||||
target_link_libraries (wamr_gtest_main PUBLIC gtest vmlib)
|
||||
include(GoogleTest)
|
||||
enable_testing()
|
||||
|
||||
function (create_wamr_unit_test test_name)
|
||||
set (sources ${ARGN})
|
||||
add_executable (${test_name} ${sources})
|
||||
target_link_libraries (
|
||||
${test_name}
|
||||
wamr_gtest_main
|
||||
vmlib
|
||||
${LLVM_AVAILABLE_LIBS}
|
||||
)
|
||||
gtest_discover_tests (${test_name})
|
||||
endfunction ()
|
||||
|
||||
if (WAMR_BUILD_LIB_WASI_THREADS EQUAL 1)
|
||||
include (${IWASM_DIR}/libraries/lib-wasi-threads/unit-test/lib_wasi_threads_unit_tests.cmake)
|
||||
endif ()
|
||||
add_subdirectory(wasm-vm)
|
||||
add_subdirectory(interpreter)
|
||||
add_subdirectory(aot)
|
||||
add_subdirectory(wasm-c-api)
|
||||
add_subdirectory(libc-builtin)
|
||||
add_subdirectory(shared-utils)
|
||||
add_subdirectory(running-modes)
|
||||
add_subdirectory(runtime-common)
|
||||
add_subdirectory(custom-section)
|
||||
add_subdirectory(compilation)
|
||||
add_subdirectory(linear-memory-wasm)
|
||||
add_subdirectory(linear-memory-aot)
|
||||
add_subdirectory(aot-stack-frame)
|
||||
add_subdirectory(linux-perf)
|
||||
add_subdirectory(gc)
|
||||
add_subdirectory(memory64)
|
||||
add_subdirectory(tid-allocator)
|
||||
|
|
55
tests/unit/aot-stack-frame/CMakeLists.txt
Normal file
55
tests/unit/aot-stack-frame/CMakeLists.txt
Normal file
|
@ -0,0 +1,55 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 2.9)
|
||||
|
||||
project (test-aot-stack-frame)
|
||||
|
||||
add_definitions (-DRUN_ON_LINUX)
|
||||
|
||||
set (WAMR_BUILD_AOT 1)
|
||||
set (WAMR_BUILD_INTERP 0)
|
||||
set (WAMR_BUILD_JIT 0)
|
||||
set (WAMR_BUILD_SIMD 1)
|
||||
set (WAMR_BUILD_REF_TYPES 1)
|
||||
set (WAMR_BUILD_LIBC_WASI 0)
|
||||
set (WAMR_BUILD_LIBC_BUILTIN 0)
|
||||
set (WAMR_BUILD_MULTI_MODULE 0)
|
||||
set (WAMR_DISABLE_HW_BOUND_CHECK 1)
|
||||
set (WAMR_DISABLE_WRITE_GS_BASE 1)
|
||||
|
||||
include (../unit_common.cmake)
|
||||
|
||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_definitions (-DWASM_ENABLE_AOT_STACK_FRAME=1)
|
||||
add_definitions (-DAOT_STACK_FRAME_DEBUG)
|
||||
#add_definitions (-DWASM_ENABLE_DUMP_CALL_STACK=1)
|
||||
|
||||
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
|
||||
|
||||
set (UNIT_SOURCE ${source_all})
|
||||
|
||||
set (unit_test_sources
|
||||
${UNIT_SOURCE}
|
||||
${PLATFORM_SHARED_SOURCE}
|
||||
${UTILS_SHARED_SOURCE}
|
||||
${MEM_ALLOC_SHARED_SOURCE}
|
||||
${NATIVE_INTERFACE_SOURCE}
|
||||
${IWASM_COMMON_SOURCE}
|
||||
${IWASM_INTERP_SOURCE}
|
||||
${IWASM_AOT_SOURCE}
|
||||
${WASM_APP_LIB_SOURCE_ALL}
|
||||
)
|
||||
|
||||
# Automatically build wasm-apps for this test
|
||||
add_subdirectory(wasm-apps)
|
||||
|
||||
# Now simply link against gtest or gtest_main as needed. Eg
|
||||
add_executable (aot_stack_frame_test ${unit_test_sources})
|
||||
|
||||
add_dependencies (aot_stack_frame_test aot-stack-frame-test-wasm)
|
||||
|
||||
target_link_libraries (aot_stack_frame_test ${LLVM_AVAILABLE_LIBS} gtest_main )
|
||||
|
||||
#gtest_discover_tests(aot_stack_frame_test)
|
288
tests/unit/aot-stack-frame/aot_stack_frame_test.cc
Normal file
288
tests/unit/aot-stack-frame/aot_stack_frame_test.cc
Normal file
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "bh_platform.h"
|
||||
#include "wasm_runtime_common.h"
|
||||
#include "aot_runtime.h"
|
||||
#include "test_helper.h"
|
||||
|
||||
#ifndef __aligned
|
||||
#define __aligned(n)
|
||||
#endif
|
||||
#include "wasm-apps/test_aot.h"
|
||||
|
||||
typedef struct MyAOTFrame {
|
||||
uintptr_t func_index;
|
||||
|
||||
/* Instruction pointer: offset to the bytecode array */
|
||||
uintptr_t ip_offset;
|
||||
|
||||
/* Operand stack top pointer of the current frame */
|
||||
uint32 *sp;
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
/* Frame ref flags (GC only) */
|
||||
uint8 *frame_ref;
|
||||
#endif
|
||||
|
||||
uint32 lp[1];
|
||||
} MyAOTFrame;
|
||||
|
||||
class AOTStackFrameTest : public testing::Test
|
||||
{
|
||||
protected:
|
||||
virtual void SetUp()
|
||||
{
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
|
||||
init_args.mem_alloc_type = Alloc_With_Pool;
|
||||
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
|
||||
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
|
||||
|
||||
ASSERT_EQ(wasm_runtime_full_init(&init_args), true);
|
||||
}
|
||||
|
||||
virtual void TearDown()
|
||||
{
|
||||
DestroyFrames();
|
||||
wasm_runtime_destroy();
|
||||
}
|
||||
|
||||
public:
|
||||
static void DestroyFrames()
|
||||
{
|
||||
if (my_frames) {
|
||||
for (uint32 i = 0; i < my_frame_num; i++) {
|
||||
if (my_frames[i])
|
||||
wasm_runtime_free(my_frames[i]);
|
||||
}
|
||||
wasm_runtime_free(my_frames);
|
||||
my_frames = NULL;
|
||||
my_frame_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
RuntimeInitArgs init_args;
|
||||
wasm_module_t module = NULL;
|
||||
wasm_module_inst_t module_inst = NULL;
|
||||
wasm_function_inst_t func_inst = NULL;
|
||||
wasm_exec_env_t exec_env = NULL;
|
||||
static MyAOTFrame **my_frames;
|
||||
static uint32 my_frame_num;
|
||||
char error_buf[128];
|
||||
char global_heap_buf[512 * 1024];
|
||||
unsigned char test_aot_buf[16 * 1024];
|
||||
unsigned argv[8];
|
||||
};
|
||||
|
||||
MyAOTFrame **AOTStackFrameTest::my_frames = NULL;
|
||||
uint32 AOTStackFrameTest::my_frame_num = 0;
|
||||
|
||||
extern "C" {
|
||||
|
||||
typedef void (*stack_frame_callback_t)(struct WASMExecEnv *exec_env);
|
||||
|
||||
void
|
||||
aot_set_stack_frame_callback(stack_frame_callback_t callback);
|
||||
|
||||
void
|
||||
aot_stack_frame_cb(struct WASMExecEnv *exec_env)
|
||||
{
|
||||
AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
|
||||
AOTModule *module = (AOTModule *)module_inst->module;
|
||||
AOTFrame *frame = (AOTFrame *)exec_env->cur_frame;
|
||||
MyAOTFrame *my_frame, **my_frames;
|
||||
uint32 all_cell_num, max_local_cell_num, max_stack_cell_num;
|
||||
uint32 frame_size_old, frame_size, i, frame_num = 0, aot_func_idx;
|
||||
|
||||
AOTStackFrameTest::DestroyFrames();
|
||||
|
||||
while (frame) {
|
||||
frame_num++;
|
||||
frame = frame->prev_frame;
|
||||
}
|
||||
|
||||
my_frames =
|
||||
(MyAOTFrame **)wasm_runtime_malloc(sizeof(MyAOTFrame *) * frame_num);
|
||||
bh_assert(my_frames);
|
||||
|
||||
frame = (AOTFrame *)exec_env->cur_frame;
|
||||
for (i = 0; i < frame_num; i++) {
|
||||
aot_func_idx = frame->func_index;
|
||||
max_local_cell_num = module->max_local_cell_nums[aot_func_idx];
|
||||
max_stack_cell_num = module->max_stack_cell_nums[aot_func_idx];
|
||||
all_cell_num = max_local_cell_num + max_stack_cell_num;
|
||||
|
||||
frame_size_old = (uint32)offsetof(AOTFrame, lp) + all_cell_num * 4;
|
||||
frame_size = (uint32)offsetof(MyAOTFrame, lp) + all_cell_num * 4;
|
||||
|
||||
my_frames[frame_num - 1 - i] = my_frame =
|
||||
(MyAOTFrame *)wasm_runtime_malloc(frame_size);
|
||||
|
||||
my_frame->func_index = aot_func_idx;
|
||||
my_frame->ip_offset = frame->ip_offset;
|
||||
my_frame->sp = my_frame->lp + (frame->sp - frame->lp);
|
||||
#if WASM_ENABLE_GC != 0
|
||||
my_frame->frame_ref =
|
||||
(uint8 *)my_frame->lp + (frame->frame_ref - (uint8 *)frame->lp);
|
||||
#endif
|
||||
|
||||
bh_memcpy_s(my_frame->lp, all_cell_num * 4, frame->lp,
|
||||
all_cell_num * 4);
|
||||
|
||||
frame = frame->prev_frame;
|
||||
}
|
||||
|
||||
AOTStackFrameTest::my_frames = my_frames;
|
||||
AOTStackFrameTest::my_frame_num = frame_num;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(AOTStackFrameTest, test1)
|
||||
{
|
||||
MyAOTFrame *frame, **frames;
|
||||
uint32 frame_num;
|
||||
|
||||
aot_set_stack_frame_callback(aot_stack_frame_cb);
|
||||
|
||||
bh_memcpy_s(test_aot_buf, sizeof(test_aot_buf), test_aot, sizeof(test_aot));
|
||||
|
||||
module = wasm_runtime_load(test_aot_buf, sizeof(test_aot), error_buf,
|
||||
sizeof(error_buf));
|
||||
ASSERT_TRUE(module != NULL);
|
||||
|
||||
module_inst = wasm_runtime_instantiate(module, 16384, 0, error_buf,
|
||||
sizeof(error_buf));
|
||||
ASSERT_TRUE(module_inst != NULL);
|
||||
|
||||
exec_env = wasm_runtime_create_exec_env(module_inst, 8 * 1024);
|
||||
ASSERT_TRUE(exec_env != NULL);
|
||||
|
||||
func_inst = wasm_runtime_lookup_function(module_inst, "test1");
|
||||
ASSERT_TRUE(func_inst != NULL);
|
||||
|
||||
argv[0] = 33;
|
||||
argv[1] = 44;
|
||||
wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
|
||||
ASSERT_TRUE(wasm_runtime_get_exception(module_inst));
|
||||
|
||||
frames = AOTStackFrameTest::my_frames;
|
||||
frame_num = AOTStackFrameTest::my_frame_num;
|
||||
|
||||
ASSERT_TRUE(frames != NULL);
|
||||
ASSERT_TRUE(frame_num == 1);
|
||||
|
||||
ASSERT_TRUE(frames[0]->lp[0] == 33);
|
||||
ASSERT_TRUE(frames[0]->lp[1] == 44);
|
||||
ASSERT_TRUE(frames[0]->lp[2] == 0x11223344);
|
||||
ASSERT_TRUE(*(uint64 *)(frames[0]->lp + 3) == 0x12345678ABCDEF99LL);
|
||||
ASSERT_TRUE(*(float *)(frames[0]->lp + 5) == 5566.7788f);
|
||||
ASSERT_TRUE(*(double *)(frames[0]->lp + 6) == 99887766.55443322);
|
||||
|
||||
wasm_runtime_destroy_exec_env(exec_env);
|
||||
exec_env = NULL;
|
||||
|
||||
wasm_runtime_deinstantiate(module_inst);
|
||||
module_inst = NULL;
|
||||
|
||||
wasm_runtime_unload(module);
|
||||
module = NULL;
|
||||
}
|
||||
|
||||
TEST_F(AOTStackFrameTest, test2)
|
||||
{
|
||||
MyAOTFrame *frame, **frames;
|
||||
uint32 frame_num;
|
||||
|
||||
aot_set_stack_frame_callback(aot_stack_frame_cb);
|
||||
|
||||
bh_memcpy_s(test_aot_buf, sizeof(test_aot_buf), test_aot, sizeof(test_aot));
|
||||
|
||||
module = wasm_runtime_load(test_aot_buf, sizeof(test_aot), error_buf,
|
||||
sizeof(error_buf));
|
||||
ASSERT_TRUE(module != NULL);
|
||||
|
||||
module_inst = wasm_runtime_instantiate(module, 16384, 0, error_buf,
|
||||
sizeof(error_buf));
|
||||
ASSERT_TRUE(module_inst != NULL);
|
||||
|
||||
exec_env = wasm_runtime_create_exec_env(module_inst, 8 * 1024);
|
||||
ASSERT_TRUE(exec_env != NULL);
|
||||
|
||||
func_inst = wasm_runtime_lookup_function(module_inst, "test2");
|
||||
ASSERT_TRUE(func_inst != NULL);
|
||||
|
||||
argv[0] = 1234;
|
||||
argv[1] = 5678;
|
||||
wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
|
||||
ASSERT_TRUE(wasm_runtime_get_exception(module_inst));
|
||||
|
||||
frames = AOTStackFrameTest::my_frames;
|
||||
frame_num = AOTStackFrameTest::my_frame_num;
|
||||
|
||||
ASSERT_TRUE(frames != NULL);
|
||||
ASSERT_TRUE(frame_num == 1);
|
||||
|
||||
ASSERT_TRUE(frames[0]->lp[0] == 1234);
|
||||
ASSERT_TRUE(frames[0]->lp[1] == 5678);
|
||||
ASSERT_TRUE(frames[0]->lp[2] == 0x11223344);
|
||||
ASSERT_TRUE(*(uint64 *)(frames[0]->lp + 3) == 0x12345678ABCDEF99LL);
|
||||
ASSERT_TRUE(*(float *)(frames[0]->lp + 5) == 5566.7788f);
|
||||
ASSERT_TRUE(*(double *)(frames[0]->lp + 6) == 99887766.55443322);
|
||||
ASSERT_TRUE(frames[0]->lp[8] == 0x1234);
|
||||
ASSERT_TRUE(frames[0]->lp[9] == 0x5678);
|
||||
}
|
||||
|
||||
TEST_F(AOTStackFrameTest, test3)
|
||||
{
|
||||
MyAOTFrame *frame, **frames;
|
||||
uint32 frame_num;
|
||||
|
||||
aot_set_stack_frame_callback(aot_stack_frame_cb);
|
||||
|
||||
bh_memcpy_s(test_aot_buf, sizeof(test_aot_buf), test_aot, sizeof(test_aot));
|
||||
|
||||
module = wasm_runtime_load(test_aot_buf, sizeof(test_aot), error_buf,
|
||||
sizeof(error_buf));
|
||||
ASSERT_TRUE(module != NULL);
|
||||
|
||||
module_inst = wasm_runtime_instantiate(module, 16384, 0, error_buf,
|
||||
sizeof(error_buf));
|
||||
ASSERT_TRUE(module_inst != NULL);
|
||||
|
||||
exec_env = wasm_runtime_create_exec_env(module_inst, 8 * 1024);
|
||||
ASSERT_TRUE(exec_env != NULL);
|
||||
|
||||
func_inst = wasm_runtime_lookup_function(module_inst, "test3");
|
||||
ASSERT_TRUE(func_inst != NULL);
|
||||
|
||||
argv[0] = 1234;
|
||||
argv[1] = 5678;
|
||||
wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
|
||||
ASSERT_TRUE(wasm_runtime_get_exception(module_inst));
|
||||
|
||||
frames = AOTStackFrameTest::my_frames;
|
||||
frame_num = AOTStackFrameTest::my_frame_num;
|
||||
|
||||
ASSERT_TRUE(frames != NULL);
|
||||
ASSERT_TRUE(frame_num == 2);
|
||||
|
||||
ASSERT_TRUE(frames[0]->sp - frames[0]->lp == 5);
|
||||
ASSERT_TRUE(frames[0]->ip_offset == 24);
|
||||
|
||||
ASSERT_TRUE(frames[0]->lp[0] == 1234);
|
||||
ASSERT_TRUE(frames[0]->lp[1] == 5678);
|
||||
ASSERT_TRUE(frames[0]->lp[2] == 0x11223344);
|
||||
ASSERT_TRUE(*(uint64 *)(frames[0]->lp + 3) == 0x12345678ABCDEF99LL);
|
||||
|
||||
ASSERT_TRUE(frames[1]->lp[0] == 0x1234);
|
||||
ASSERT_TRUE(frames[1]->lp[1] == 0x5678);
|
||||
ASSERT_TRUE(frames[1]->lp[2] == 0x11223344);
|
||||
ASSERT_TRUE(*(uint64 *)(frames[1]->lp + 3) == 0x12345678ABCDEF99LL);
|
||||
ASSERT_TRUE(*(float *)(frames[1]->lp + 5) == 5566.7788f);
|
||||
ASSERT_TRUE(*(double *)(frames[1]->lp + 6) == 99887766.55443322);
|
||||
}
|
27
tests/unit/aot-stack-frame/wasm-apps/CMakeLists.txt
Normal file
27
tests/unit/aot-stack-frame/wasm-apps/CMakeLists.txt
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 2.9)
|
||||
|
||||
project(wasm-apps-aot-stack-frame)
|
||||
|
||||
add_custom_target(aot-stack-frame-test-wasm ALL
|
||||
COMMAND cmake -B ${CMAKE_CURRENT_BINARY_DIR}/build-wamrc
|
||||
-S ${WAMR_ROOT_DIR}/wamr-compiler
|
||||
&& cmake --build ${CMAKE_CURRENT_BINARY_DIR}/build-wamrc
|
||||
&& /opt/wabt/bin/wat2wasm
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/test.wasm
|
||||
${CMAKE_CURRENT_LIST_DIR}/test.wast
|
||||
&& ${CMAKE_CURRENT_BINARY_DIR}/build-wamrc/wamrc
|
||||
--enable-dump-call-stack --bounds-checks=1
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/test.aot
|
||||
${CMAKE_CURRENT_BINARY_DIR}/test.wasm
|
||||
&& cmake -B ${CMAKE_CURRENT_BINARY_DIR}/build-binarydump
|
||||
-S ${WAMR_ROOT_DIR}/test-tools/binarydump-tool
|
||||
&& cmake --build ${CMAKE_CURRENT_BINARY_DIR}/build-binarydump
|
||||
&& ${CMAKE_CURRENT_BINARY_DIR}/build-binarydump/binarydump
|
||||
-o ${CMAKE_CURRENT_LIST_DIR}/test_aot.h -n test_aot
|
||||
${CMAKE_CURRENT_BINARY_DIR}/test.aot
|
||||
|
||||
)
|
||||
|
36
tests/unit/aot-stack-frame/wasm-apps/test.wast
Normal file
36
tests/unit/aot-stack-frame/wasm-apps/test.wast
Normal file
|
@ -0,0 +1,36 @@
|
|||
(module
|
||||
(func $test1 (export "test1") (param i32 i32) (result i32)
|
||||
i32.const 0x11223344
|
||||
i64.const 0x1234_5678_ABCD_EF99
|
||||
f32.const 5566.7788
|
||||
f64.const 99887766.55443322
|
||||
unreachable
|
||||
)
|
||||
|
||||
(func $test2 (export "test2") (param f32 f32) (result i32)
|
||||
i32.const 0x11223344
|
||||
i64.const 0x1234_5678_ABCD_EF99
|
||||
f32.const 5566.7788
|
||||
f64.const 99887766.55443322
|
||||
|
||||
loop
|
||||
i32.const 0x1234
|
||||
i32.const 0x5678
|
||||
unreachable
|
||||
end
|
||||
|
||||
unreachable
|
||||
)
|
||||
|
||||
(func $test3 (export "test3") (param i32 i32) (result i32)
|
||||
i32.const 0x11223344
|
||||
i64.const 0x1234_5678_ABCD_EF99
|
||||
|
||||
i32.const 0x1234
|
||||
i32.const 0x5678
|
||||
call $test1
|
||||
|
||||
drop
|
||||
drop
|
||||
)
|
||||
)
|
59
tests/unit/aot/CMakeLists.txt
Normal file
59
tests/unit/aot/CMakeLists.txt
Normal file
|
@ -0,0 +1,59 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 2.9)
|
||||
|
||||
project (test-aot)
|
||||
|
||||
add_definitions (-DRUN_ON_LINUX)
|
||||
|
||||
add_definitions (-Dattr_container_malloc=malloc)
|
||||
add_definitions (-Dattr_container_free=free)
|
||||
add_definitions (-DWASM_ENABLE_WAMR_COMPILER=1)
|
||||
add_definitions (-DWASM_ENABLE_DUMP_CALL_STACK=1)
|
||||
add_definitions (-DWASM_ENABLE_AOT_STACK_FRAME=1)
|
||||
|
||||
set (WAMR_BUILD_LIBC_WASI 0)
|
||||
set (WAMR_BUILD_APP_FRAMEWORK 1)
|
||||
|
||||
include (../unit_common.cmake)
|
||||
|
||||
set (LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm")
|
||||
if (NOT EXISTS "${LLVM_SRC_ROOT}/build")
|
||||
message (FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/build")
|
||||
endif ()
|
||||
set (CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/build;${CMAKE_PREFIX_PATH}")
|
||||
find_package(LLVM REQUIRED CONFIG)
|
||||
include_directories(${LLVM_INCLUDE_DIRS})
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||
|
||||
include (${IWASM_DIR}/compilation/iwasm_compl.cmake)
|
||||
|
||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
|
||||
|
||||
set (UNIT_SOURCE ${source_all})
|
||||
|
||||
set (unit_test_sources
|
||||
${UNIT_SOURCE}
|
||||
${PLATFORM_SHARED_SOURCE}
|
||||
${UTILS_SHARED_SOURCE}
|
||||
${MEM_ALLOC_SHARED_SOURCE}
|
||||
${NATIVE_INTERFACE_SOURCE}
|
||||
${LIBC_BUILTIN_SOURCE}
|
||||
${IWASM_COMMON_SOURCE}
|
||||
${IWASM_INTERP_SOURCE}
|
||||
${IWASM_AOT_SOURCE}
|
||||
${IWASM_COMPL_SOURCE}
|
||||
)
|
||||
|
||||
# Now simply link against gtest or gtest_main as needed. Eg
|
||||
add_executable (aot_test ${unit_test_sources})
|
||||
|
||||
target_link_libraries (aot_test ${LLVM_AVAILABLE_LIBS} gtest_main )
|
||||
|
||||
gtest_discover_tests(aot_test)
|
||||
|
1190
tests/unit/aot/aot_test.cc
Normal file
1190
tests/unit/aot/aot_test.cc
Normal file
File diff suppressed because it is too large
Load Diff
89
tests/unit/common/mock_allocator.h
Normal file
89
tests/unit/common/mock_allocator.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "wasm_export.h"
|
||||
#include <functional>
|
||||
|
||||
template<int MaxAllocCount>
|
||||
class MockAllocator
|
||||
{
|
||||
private:
|
||||
RuntimeInitArgs init_args;
|
||||
|
||||
public:
|
||||
MockAllocator()
|
||||
{
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
|
||||
init_args.mem_alloc_type = Alloc_With_Allocator;
|
||||
init_args.mem_alloc_option.allocator.malloc_func = (void *)my_malloc;
|
||||
init_args.mem_alloc_option.allocator.realloc_func = (void *)realloc;
|
||||
init_args.mem_alloc_option.allocator.free_func = (void *)free;
|
||||
|
||||
/* Set count to INT32_MIN so the initialization will not fail */
|
||||
alloc_count = INT32_MIN;
|
||||
|
||||
wasm_runtime_full_init(&init_args);
|
||||
reset_count();
|
||||
}
|
||||
|
||||
~MockAllocator() { wasm_runtime_destroy(); }
|
||||
|
||||
void reset_count() { alloc_count = 0; }
|
||||
|
||||
protected:
|
||||
static int32_t alloc_count;
|
||||
static void *my_malloc(int32_t size)
|
||||
{
|
||||
if (alloc_count >= MaxAllocCount) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
alloc_count++;
|
||||
|
||||
return malloc(size);
|
||||
}
|
||||
};
|
||||
|
||||
template<int MaxAllocCount>
|
||||
int32_t MockAllocator<MaxAllocCount>::alloc_count = 0;
|
||||
|
||||
class DumpAllocUsage : public MockAllocator<INT32_MAX>
|
||||
{
|
||||
public:
|
||||
DumpAllocUsage()
|
||||
: MockAllocator<INT32_MAX>()
|
||||
{}
|
||||
|
||||
~DumpAllocUsage()
|
||||
{
|
||||
std::cout << "Alloc usage count: " << alloc_count << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
template<int AllocRequired>
|
||||
void
|
||||
LIMIT_MALLOC_COUNT(std::function<void()> func)
|
||||
{
|
||||
{
|
||||
MockAllocator<AllocRequired> allocator;
|
||||
func();
|
||||
}
|
||||
|
||||
if (AllocRequired > 1)
|
||||
LIMIT_MALLOC_COUNT<AllocRequired - 1>(func);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
LIMIT_MALLOC_COUNT<0>(std::function<void()> func)
|
||||
{
|
||||
{
|
||||
MockAllocator<0> allocator;
|
||||
func();
|
||||
}
|
||||
}
|
325
tests/unit/common/test_helper.h
Normal file
325
tests/unit/common/test_helper.h
Normal file
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "wasm_export.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
|
||||
template<int Size = 512 * 1024>
|
||||
class WAMRRuntimeRAII
|
||||
{
|
||||
private:
|
||||
char global_heap_buf[Size];
|
||||
RuntimeInitArgs init_args;
|
||||
|
||||
public:
|
||||
WAMRRuntimeRAII()
|
||||
{
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
|
||||
init_args.mem_alloc_type = Alloc_With_Pool;
|
||||
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
|
||||
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
|
||||
|
||||
wasm_runtime_full_init(&init_args);
|
||||
}
|
||||
|
||||
~WAMRRuntimeRAII() { wasm_runtime_destroy(); }
|
||||
};
|
||||
|
||||
class WAMRModule
|
||||
{
|
||||
private:
|
||||
wasm_module_t module_;
|
||||
|
||||
public:
|
||||
WAMRModule(uint8_t *buffer, uint32_t size)
|
||||
{
|
||||
module_ = wasm_runtime_load(buffer, size, NULL, 0);
|
||||
}
|
||||
|
||||
~WAMRModule() { wasm_runtime_unload(module_); }
|
||||
|
||||
wasm_module_t get() const { return module_; }
|
||||
};
|
||||
|
||||
class WAMRInstance
|
||||
{
|
||||
private:
|
||||
wasm_module_inst_t module_inst_;
|
||||
|
||||
public:
|
||||
WAMRInstance(WAMRModule &module, uint32_t stack_size = 8192,
|
||||
uint32_t heap_size = 8192)
|
||||
{
|
||||
module_inst_ = wasm_runtime_instantiate(module.get(), stack_size,
|
||||
heap_size, NULL, 0);
|
||||
}
|
||||
|
||||
~WAMRInstance() { wasm_runtime_deinstantiate(module_inst_); }
|
||||
|
||||
wasm_module_inst_t get() const { return module_inst_; }
|
||||
};
|
||||
|
||||
class WAMRExecEnv
|
||||
{
|
||||
private:
|
||||
wasm_exec_env_t exec_env_;
|
||||
|
||||
public:
|
||||
WAMRExecEnv(WAMRInstance &instance, uint32_t stack_size = 8192)
|
||||
{
|
||||
exec_env_ = wasm_runtime_create_exec_env(instance.get(), stack_size);
|
||||
}
|
||||
|
||||
~WAMRExecEnv() { wasm_runtime_destroy_exec_env(exec_env_); }
|
||||
|
||||
wasm_exec_env_t get() const { return exec_env_; }
|
||||
wasm_module_inst_t get_inst() const
|
||||
{
|
||||
return wasm_runtime_get_module_inst(exec_env_);
|
||||
}
|
||||
};
|
||||
|
||||
static uint8_t dummy_wasm_buffer[] = {
|
||||
0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x05, 0x03, 0x01, 0x00,
|
||||
0x02, 0x06, 0x08, 0x01, 0x7F, 0x01, 0x41, 0x80, 0x88, 0x04, 0x0B, 0x07,
|
||||
0x0A, 0x01, 0x06, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x02, 0x00, 0x00,
|
||||
0x19, 0x04, 0x6E, 0x61, 0x6D, 0x65, 0x07, 0x12, 0x01, 0x00, 0x0F, 0x5F,
|
||||
0x5F, 0x73, 0x74, 0x61, 0x63, 0x6B, 0x5F, 0x70, 0x6F, 0x69, 0x6E, 0x74,
|
||||
0x65, 0x72, 0x00, 0x76, 0x09, 0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x65,
|
||||
0x72, 0x73, 0x01, 0x0C, 0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, 0x65,
|
||||
0x64, 0x2D, 0x62, 0x79, 0x01, 0x05, 0x63, 0x6C, 0x61, 0x6E, 0x67, 0x56,
|
||||
0x31, 0x33, 0x2E, 0x30, 0x2E, 0x30, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
|
||||
0x73, 0x3A, 0x2F, 0x2F, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2E, 0x63,
|
||||
0x6F, 0x6D, 0x2F, 0x6C, 0x6C, 0x76, 0x6D, 0x2F, 0x6C, 0x6C, 0x76, 0x6D,
|
||||
0x2D, 0x70, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x66, 0x64, 0x31,
|
||||
0x64, 0x38, 0x63, 0x32, 0x66, 0x30, 0x34, 0x64, 0x64, 0x65, 0x32, 0x33,
|
||||
0x62, 0x65, 0x65, 0x30, 0x66, 0x62, 0x33, 0x61, 0x37, 0x64, 0x30, 0x36,
|
||||
0x39, 0x61, 0x39, 0x62, 0x31, 0x30, 0x34, 0x36, 0x64, 0x61, 0x39, 0x37,
|
||||
0x39, 0x29
|
||||
};
|
||||
|
||||
class DummyExecEnv
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<WAMRExecEnv> dummy_exec_env_;
|
||||
std::shared_ptr<WAMRInstance> inst_;
|
||||
std::shared_ptr<WAMRModule> mod_;
|
||||
std::vector<uint8_t> my_wasm_buffer;
|
||||
|
||||
private:
|
||||
void construct(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
std::vector<uint8_t> buffer(buf, buf + len);
|
||||
my_wasm_buffer = buffer;
|
||||
|
||||
mod_ = std::make_shared<WAMRModule>(my_wasm_buffer.data(),
|
||||
my_wasm_buffer.size());
|
||||
EXPECT_NE(mod_.get(), nullptr);
|
||||
inst_ = std::make_shared<WAMRInstance>(*mod_);
|
||||
EXPECT_NE(inst_.get(), nullptr);
|
||||
dummy_exec_env_ = std::make_shared<WAMRExecEnv>(*inst_);
|
||||
EXPECT_NE(dummy_exec_env_.get(), nullptr);
|
||||
}
|
||||
|
||||
public:
|
||||
DummyExecEnv() { construct(dummy_wasm_buffer, sizeof(dummy_wasm_buffer)); }
|
||||
|
||||
DummyExecEnv(uint8_t *buf, uint32_t len) { construct(buf, len); }
|
||||
|
||||
DummyExecEnv(std::string filename)
|
||||
{
|
||||
std::ifstream wasm_file(filename, std::ios::binary);
|
||||
std::vector<uint8_t> buffer(std::istreambuf_iterator<char>(wasm_file),
|
||||
{});
|
||||
|
||||
construct(buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
~DummyExecEnv() {}
|
||||
|
||||
wasm_exec_env_t get() const { return dummy_exec_env_->get(); }
|
||||
|
||||
void *app_to_native(uint32_t app_addr) const
|
||||
{
|
||||
return wasm_runtime_addr_app_to_native(inst_->get(), app_addr);
|
||||
}
|
||||
|
||||
uint32_t native_to_app(void *ptr) const
|
||||
{
|
||||
return wasm_runtime_addr_native_to_app(inst_->get(), ptr);
|
||||
}
|
||||
|
||||
const char *get_exception() const
|
||||
{
|
||||
return wasm_runtime_get_exception(inst_->get());
|
||||
}
|
||||
|
||||
void set_exception(std::string str) const
|
||||
{
|
||||
wasm_runtime_set_exception(inst_->get(), str.c_str());
|
||||
}
|
||||
|
||||
void clear_exception() const { wasm_runtime_clear_exception(inst_->get()); }
|
||||
|
||||
bool execute(const char *func_name, uint32_t argc, uint32_t argv[])
|
||||
{
|
||||
wasm_function_inst_t func;
|
||||
|
||||
if (!(func = wasm_runtime_lookup_function(inst_->get(), func_name))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return wasm_runtime_call_wasm(dummy_exec_env_->get(), func, argc, argv);
|
||||
}
|
||||
};
|
||||
|
||||
class WAMRVaList
|
||||
{
|
||||
private:
|
||||
void *buffer_;
|
||||
uint32_t current_loc_;
|
||||
uint32_t capacity_;
|
||||
wasm_exec_env_t exec_env_;
|
||||
|
||||
void _append(void *ptr, uint32_t size)
|
||||
{
|
||||
if (current_loc_ + size >= capacity_) {
|
||||
capacity_ *= 2;
|
||||
buffer_ = realloc(buffer_, capacity_);
|
||||
ASSERT_NE(buffer_, nullptr);
|
||||
}
|
||||
|
||||
memcpy((void *)((uintptr_t)buffer_ + current_loc_), ptr, size);
|
||||
current_loc_ += size;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit WAMRVaList(wasm_exec_env_t exec_env)
|
||||
: exec_env_(exec_env)
|
||||
{
|
||||
capacity_ = 64;
|
||||
buffer_ = malloc(capacity_);
|
||||
EXPECT_NE(buffer_, nullptr);
|
||||
current_loc_ = 0;
|
||||
}
|
||||
|
||||
~WAMRVaList()
|
||||
{
|
||||
current_loc_ = 0;
|
||||
free(buffer_);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void add(T arg)
|
||||
{
|
||||
if (std::is_floating_point<T>::value) {
|
||||
/* float data should be 8 bytes aligned */
|
||||
current_loc_ = ((current_loc_ + 7) & ~7);
|
||||
_append(&arg, sizeof(T));
|
||||
}
|
||||
else if (std::is_integral<T>::value) {
|
||||
if (sizeof(T) > 4) {
|
||||
current_loc_ = ((current_loc_ + 7) & ~7);
|
||||
}
|
||||
_append(&arg, sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
void add(std::string arg)
|
||||
{
|
||||
void *native_addr;
|
||||
auto inst = wasm_runtime_get_module_inst(exec_env_);
|
||||
uint32_t addr =
|
||||
wasm_runtime_module_malloc(inst, arg.size() + 1, &native_addr);
|
||||
ASSERT_NE(addr, 0);
|
||||
memcpy(native_addr, arg.data(), arg.size());
|
||||
*(char *)((uintptr_t)native_addr + arg.size()) = 0;
|
||||
_append(&addr, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void add(const char *arg) { add(std::string(arg)); }
|
||||
|
||||
char *get() const
|
||||
{
|
||||
auto inst = wasm_runtime_get_module_inst(exec_env_);
|
||||
uint32_t addr = wasm_runtime_module_dup_data(
|
||||
inst, (const char *)buffer_, current_loc_);
|
||||
EXPECT_NE(addr, 0);
|
||||
return (char *)wasm_runtime_addr_app_to_native(inst, addr);
|
||||
}
|
||||
};
|
||||
|
||||
/* Get memory space in app */
|
||||
class AppMemory
|
||||
{
|
||||
private:
|
||||
wasm_exec_env_t exec_env_;
|
||||
void *native_addr_;
|
||||
uint32_t app_addr_;
|
||||
|
||||
public:
|
||||
AppMemory(wasm_exec_env_t exec_env, uint32_t size)
|
||||
: exec_env_(exec_env)
|
||||
{
|
||||
app_addr_ = wasm_runtime_module_malloc(get_module_inst(exec_env_), size,
|
||||
&native_addr_);
|
||||
}
|
||||
|
||||
~AppMemory()
|
||||
{
|
||||
wasm_runtime_module_free(get_module_inst(exec_env_), app_addr_);
|
||||
}
|
||||
|
||||
void *get_native_addr() const
|
||||
{
|
||||
return wasm_runtime_addr_app_to_native(get_module_inst(exec_env_),
|
||||
app_addr_);
|
||||
}
|
||||
uint32_t get_app_addr() const { return app_addr_; }
|
||||
};
|
||||
|
||||
/* Put the data to app */
|
||||
class AppData
|
||||
{
|
||||
private:
|
||||
wasm_exec_env_t exec_env_;
|
||||
void *native_addr_;
|
||||
uint32_t app_addr_;
|
||||
|
||||
public:
|
||||
AppData(wasm_exec_env_t exec_env, void *data, uint32_t size)
|
||||
: exec_env_(exec_env)
|
||||
{
|
||||
app_addr_ = wasm_runtime_module_dup_data(get_module_inst(exec_env_),
|
||||
(const char *)data, size);
|
||||
}
|
||||
|
||||
AppData(wasm_exec_env_t exec_env, std::string str)
|
||||
: exec_env_(exec_env)
|
||||
{
|
||||
app_addr_ = wasm_runtime_module_dup_data(get_module_inst(exec_env_),
|
||||
(const char *)str.c_str(),
|
||||
str.size() + 1);
|
||||
}
|
||||
|
||||
~AppData()
|
||||
{
|
||||
wasm_runtime_module_free(get_module_inst(exec_env_), app_addr_);
|
||||
}
|
||||
|
||||
void *get_native_addr() const
|
||||
{
|
||||
return wasm_runtime_addr_app_to_native(get_module_inst(exec_env_),
|
||||
app_addr_);
|
||||
}
|
||||
uint32_t get_app_addr() const { return app_addr_; }
|
||||
};
|
72
tests/unit/compilation/CMakeLists.txt
Normal file
72
tests/unit/compilation/CMakeLists.txt
Normal file
|
@ -0,0 +1,72 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 2.9)
|
||||
|
||||
project (test-compilation)
|
||||
|
||||
add_definitions (-DRUN_ON_LINUX)
|
||||
|
||||
add_definitions (-Dattr_container_malloc=malloc)
|
||||
add_definitions (-Dattr_container_free=free)
|
||||
add_definitions (-DWASM_ENABLE_WAMR_COMPILER=1)
|
||||
add_definitions (-DWASM_ENABLE_DUMP_CALL_STACK=1)
|
||||
add_definitions (-DWASM_ENABLE_AOT_STACK_FRAME=1)
|
||||
|
||||
set (WAMR_BUILD_LIBC_WASI 0)
|
||||
set (WAMR_BUILD_APP_FRAMEWORK 0)
|
||||
set (WAMR_BUILD_THREAD_MGR 1)
|
||||
set (WAMR_BUILD_AOT 1)
|
||||
|
||||
include (../unit_common.cmake)
|
||||
|
||||
set (LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm")
|
||||
if (NOT EXISTS "${LLVM_SRC_ROOT}/build")
|
||||
message (FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/build")
|
||||
endif ()
|
||||
set (CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/build;${CMAKE_PREFIX_PATH}")
|
||||
find_package(LLVM REQUIRED CONFIG)
|
||||
include_directories(${LLVM_INCLUDE_DIRS})
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||
|
||||
include (${IWASM_DIR}/compilation/iwasm_compl.cmake)
|
||||
|
||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
|
||||
|
||||
set (UNIT_SOURCE ${source_all})
|
||||
|
||||
set (unit_test_sources
|
||||
${UNIT_SOURCE}
|
||||
${WAMR_RUNTIME_LIB_SOURCE}
|
||||
${UNCOMMON_SHARED_SOURCE}
|
||||
${SRC_LIST}
|
||||
${PLATFORM_SHARED_SOURCE}
|
||||
${UTILS_SHARED_SOURCE}
|
||||
${MEM_ALLOC_SHARED_SOURCE}
|
||||
${LIB_HOST_AGENT_SOURCE}
|
||||
${NATIVE_INTERFACE_SOURCE}
|
||||
${LIBC_BUILTIN_SOURCE}
|
||||
${IWASM_COMMON_SOURCE}
|
||||
${IWASM_INTERP_SOURCE}
|
||||
${IWASM_AOT_SOURCE}
|
||||
${IWASM_COMPL_SOURCE}
|
||||
${WASM_APP_LIB_SOURCE_ALL}
|
||||
)
|
||||
|
||||
# Now simply link against gtest or gtest_main as needed. Eg
|
||||
add_executable (compilation_test ${unit_test_sources})
|
||||
|
||||
target_link_libraries (compilation_test ${LLVM_AVAILABLE_LIBS} gtest_main )
|
||||
|
||||
add_custom_command(TARGET compilation_test POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_LIST_DIR}/wasm-apps/main.wasm
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Copy main.wasm to the directory: build/compilation."
|
||||
)
|
||||
|
||||
gtest_discover_tests(compilation_test)
|
203
tests/unit/compilation/aot_compiler_test.cc
Normal file
203
tests/unit/compilation/aot_compiler_test.cc
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "test_helper.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "wasm_export.h"
|
||||
#include "aot_export.h"
|
||||
#include "bh_read_file.h"
|
||||
|
||||
static std::string CWD;
|
||||
static std::string MAIN_WASM = "/main.wasm";
|
||||
static char *WASM_FILE;
|
||||
|
||||
static std::string
|
||||
get_binary_path()
|
||||
{
|
||||
char cwd[1024];
|
||||
memset(cwd, 0, 1024);
|
||||
|
||||
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
|
||||
}
|
||||
|
||||
char *path_end = strrchr(cwd, '/');
|
||||
if (path_end != NULL) {
|
||||
*path_end = '\0';
|
||||
}
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
char *
|
||||
aot_generate_tempfile_name(const char *prefix, const char *extension,
|
||||
char *buffer, uint32 len);
|
||||
}
|
||||
|
||||
class aot_compiler_test_suit : public testing::Test
|
||||
{
|
||||
protected:
|
||||
// You should make the members protected s.t. they can be
|
||||
// accessed from sub-classes.
|
||||
|
||||
// virtual void SetUp() will be called before each test is run. You
|
||||
// should define it if you need to initialize the varaibles.
|
||||
// Otherwise, this can be skipped.
|
||||
virtual void SetUp() {}
|
||||
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
CWD = get_binary_path();
|
||||
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
|
||||
}
|
||||
|
||||
// virtual void TearDown() will be called after each test is run.
|
||||
// You should define it if there is cleanup work to do. Otherwise,
|
||||
// you don't have to provide it.
|
||||
//
|
||||
virtual void TearDown() {}
|
||||
|
||||
static void TearDownTestCase() { free(WASM_FILE); }
|
||||
|
||||
WAMRRuntimeRAII<512 * 1024> runtime;
|
||||
};
|
||||
|
||||
void
|
||||
test_aot_emit_object_file_with_option(AOTCompOption *option_ptr)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
aot_comp_data_t comp_data = nullptr;
|
||||
aot_comp_context_t comp_ctx = nullptr;
|
||||
char out_file_name[] = "test.aot";
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data(wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
|
||||
comp_ctx = aot_create_comp_context(comp_data, option_ptr);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_STREQ(aot_get_last_error(), "");
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
|
||||
EXPECT_TRUE(aot_emit_object_file(comp_ctx, out_file_name));
|
||||
}
|
||||
|
||||
TEST_F(aot_compiler_test_suit, aot_emit_object_file)
|
||||
{
|
||||
AOTCompOption option = { 0 };
|
||||
uint32_t i = 0;
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
// Test opt_level in range from 0 to 3.
|
||||
for (i = 0; i <= 3; i++) {
|
||||
option.opt_level = i;
|
||||
test_aot_emit_object_file_with_option(&option);
|
||||
}
|
||||
|
||||
// Test size_level in range from 0 to 3.
|
||||
option.opt_level = 3;
|
||||
for (i = 0; i <= 3; i++) {
|
||||
option.size_level = i;
|
||||
test_aot_emit_object_file_with_option(&option);
|
||||
}
|
||||
|
||||
// Test output_format in range from AOT_FORMAT_FILE to AOT_LLVMIR_OPT_FILE.
|
||||
option.size_level = 3;
|
||||
for (i = AOT_FORMAT_FILE; i <= AOT_LLVMIR_OPT_FILE; i++) {
|
||||
option.output_format = i;
|
||||
test_aot_emit_object_file_with_option(&option);
|
||||
}
|
||||
|
||||
// Test bounds_checks in range 0 to 2.
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
for (i = 0; i <= 2; i++) {
|
||||
option.bounds_checks = i;
|
||||
test_aot_emit_object_file_with_option(&option);
|
||||
}
|
||||
|
||||
// Test all enable option is false.
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = false;
|
||||
option.enable_aux_stack_check = false;
|
||||
option.enable_bulk_memory = false;
|
||||
option.enable_ref_types = false;
|
||||
test_aot_emit_object_file_with_option(&option);
|
||||
}
|
||||
|
||||
TEST_F(aot_compiler_test_suit, aot_emit_llvm_file)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
aot_comp_data_t comp_data = nullptr;
|
||||
aot_comp_context_t comp_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
char out_file_name[] = "out_file_name_test";
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data(wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_STREQ(aot_get_last_error(), "");
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
|
||||
EXPECT_EQ(true, aot_emit_llvm_file(comp_ctx, out_file_name));
|
||||
}
|
||||
|
||||
TEST_F(aot_compiler_test_suit, aot_generate_tempfile_name)
|
||||
{
|
||||
char obj_file_name[64];
|
||||
|
||||
// Test common case.
|
||||
aot_generate_tempfile_name("wamrc-obj", "o", obj_file_name,
|
||||
sizeof(obj_file_name));
|
||||
EXPECT_NE(nullptr, strstr(obj_file_name, ".o"));
|
||||
|
||||
// Test abnormal cases.
|
||||
EXPECT_EQ(nullptr,
|
||||
aot_generate_tempfile_name("wamrc-obj", "o", obj_file_name, 0));
|
||||
char obj_file_name_1[20];
|
||||
EXPECT_EQ(nullptr, aot_generate_tempfile_name(
|
||||
"wamrc-obj", "12345678901234567890", obj_file_name_1,
|
||||
sizeof(obj_file_name_1)));
|
||||
}
|
104
tests/unit/compilation/aot_emit_aot_file_test.cc
Normal file
104
tests/unit/compilation/aot_emit_aot_file_test.cc
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "test_helper.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "wasm_export.h"
|
||||
#include "aot_export.h"
|
||||
#include "bh_read_file.h"
|
||||
|
||||
static std::string CWD;
|
||||
static std::string MAIN_WASM = "/main.wasm";
|
||||
static char *WASM_FILE;
|
||||
|
||||
static std::string
|
||||
get_binary_path()
|
||||
{
|
||||
char cwd[1024];
|
||||
memset(cwd, 0, 1024);
|
||||
|
||||
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
|
||||
}
|
||||
|
||||
char *path_end = strrchr(cwd, '/');
|
||||
if (path_end != NULL) {
|
||||
*path_end = '\0';
|
||||
}
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
uint8 *
|
||||
aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|
||||
uint32 *p_aot_file_size);
|
||||
}
|
||||
|
||||
class aot_emit_aot_file_test_suite : public testing::Test
|
||||
{
|
||||
protected:
|
||||
// You should make the members protected s.t. they can be
|
||||
// accessed from sub-classes.
|
||||
|
||||
// virtual void SetUp() will be called before each test is run. You
|
||||
// should define it if you need to initialize the varaibles.
|
||||
// Otherwise, this can be skipped.
|
||||
virtual void SetUp() {}
|
||||
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
CWD = get_binary_path();
|
||||
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
|
||||
}
|
||||
|
||||
// virtual void TearDown() will be called after each test is run.
|
||||
// You should define it if there is cleanup work to do. Otherwise,
|
||||
// you don't have to provide it.
|
||||
//
|
||||
virtual void TearDown() {}
|
||||
|
||||
static void TearDownTestCase() { free(WASM_FILE); }
|
||||
|
||||
WAMRRuntimeRAII<512 * 1024> runtime;
|
||||
};
|
||||
|
||||
TEST_F(aot_emit_aot_file_test_suite, aot_emit_aot_file)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
aot_comp_data_t comp_data = nullptr;
|
||||
aot_comp_context_t comp_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
char out_file_name[] = "test.aot";
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = false;
|
||||
option.enable_aux_stack_check = false;
|
||||
option.enable_bulk_memory = false;
|
||||
option.enable_ref_types = false;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data(wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
|
||||
EXPECT_EQ(false, aot_emit_aot_file(comp_ctx, comp_data, nullptr));
|
||||
}
|
112
tests/unit/compilation/aot_emit_compare_test.cc
Normal file
112
tests/unit/compilation/aot_emit_compare_test.cc
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "aot_emit_compare.h"
|
||||
|
||||
class compilation_aot_emit_compare_test : public testing::Test
|
||||
{
|
||||
protected:
|
||||
virtual void SetUp() {}
|
||||
virtual void TearDown() {}
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
TEST_F(compilation_aot_emit_compare_test, aot_compile_op_i32_compare)
|
||||
{
|
||||
AOTCompContext comp_ctx = { 0 };
|
||||
AOTFuncContext func_ctx = { 0 };
|
||||
IntCond cond = INT_EQZ;
|
||||
IntCond cond1 = INT_EQZ;
|
||||
|
||||
/* false cond = 0 */
|
||||
EXPECT_FALSE(aot_compile_op_i32_compare(&comp_ctx, &func_ctx, cond));
|
||||
|
||||
/* false cond = -1 */
|
||||
EXPECT_FALSE(
|
||||
aot_compile_op_i32_compare(&comp_ctx, &func_ctx, (IntCond)(-1)));
|
||||
|
||||
/* false cond = [1:10] || [11:100] */
|
||||
for (int i = 0; i < 0xFFFF; i++) {
|
||||
/* Generate random number range:[m,n] int a=m+rand()%(n-m+1); */
|
||||
cond = (IntCond)(1 + (rand() % (INT_GE_U - 1 + 1)));
|
||||
cond1 = (IntCond)((INT_GE_U + 1) + (rand() % (100 - 1 + 1)));
|
||||
EXPECT_FALSE(aot_compile_op_i32_compare(&comp_ctx, &func_ctx, cond));
|
||||
EXPECT_FALSE(aot_compile_op_i32_compare(&comp_ctx, &func_ctx, cond1));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_compare_test, aot_compile_op_i64_compare)
|
||||
{
|
||||
AOTCompContext comp_ctx = { 0 };
|
||||
AOTFuncContext func_ctx = { 0 };
|
||||
IntCond cond = INT_EQZ;
|
||||
IntCond cond1 = INT_EQZ;
|
||||
|
||||
/* false cond = 0 */
|
||||
// EXPECT_FALSE(aot_compile_op_i64_compare(&comp_ctx, &func_ctx, cond));
|
||||
|
||||
/* false cond = -1 */
|
||||
EXPECT_FALSE(
|
||||
aot_compile_op_i64_compare(&comp_ctx, &func_ctx, (IntCond)(-1)));
|
||||
|
||||
/* false cond = [1:10] || [11:100] */
|
||||
for (int i = 0; i < 0xFFFF; i++) {
|
||||
/* Generate random number range:[m,n] int a=m+rand()%(n-m+1); */
|
||||
cond = (IntCond)(1 + (rand() % (INT_GE_U - 1 + 1)));
|
||||
cond1 = (IntCond)((INT_GE_U + 1) + (rand() % (100 - 1 + 1)));
|
||||
EXPECT_FALSE(aot_compile_op_i64_compare(&comp_ctx, &func_ctx, cond));
|
||||
EXPECT_FALSE(aot_compile_op_i64_compare(&comp_ctx, &func_ctx, cond1));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_compare_test, aot_compile_op_f32_compare)
|
||||
{
|
||||
AOTCompContext comp_ctx = { 0 };
|
||||
AOTFuncContext func_ctx = { 0 };
|
||||
FloatCond cond = FLOAT_EQ;
|
||||
FloatCond cond1 = FLOAT_EQ;
|
||||
|
||||
/* false cond = 0 */
|
||||
EXPECT_FALSE(aot_compile_op_f32_compare(&comp_ctx, &func_ctx, cond));
|
||||
|
||||
/* false cond = -1 */
|
||||
EXPECT_FALSE(
|
||||
aot_compile_op_f32_compare(&comp_ctx, &func_ctx, (FloatCond)(-1)));
|
||||
|
||||
/* false cond = [1:10] || [7:100] */
|
||||
for (int i = 0; i < 0xFFFF; i++) {
|
||||
/* Generate random number range:[m,n] int a=m+rand()%(n-m+1); */
|
||||
cond = (FloatCond)(1 + (rand() % (FLOAT_UNO - 1 + 1)));
|
||||
cond1 = (FloatCond)((FLOAT_UNO + 1) + (rand() % (100 - 1 + 1)));
|
||||
EXPECT_FALSE(aot_compile_op_f32_compare(&comp_ctx, &func_ctx, cond));
|
||||
EXPECT_FALSE(aot_compile_op_f32_compare(&comp_ctx, &func_ctx, cond1));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_compare_test, aot_compile_op_f64_compare)
|
||||
{
|
||||
AOTCompContext comp_ctx = { 0 };
|
||||
AOTFuncContext func_ctx = { 0 };
|
||||
FloatCond cond = FLOAT_EQ;
|
||||
FloatCond cond1 = FLOAT_EQ;
|
||||
|
||||
/* false cond = 0 */
|
||||
EXPECT_FALSE(aot_compile_op_f64_compare(&comp_ctx, &func_ctx, cond));
|
||||
|
||||
/* false cond = -1 */
|
||||
EXPECT_FALSE(
|
||||
aot_compile_op_f64_compare(&comp_ctx, &func_ctx, (FloatCond)(-1)));
|
||||
|
||||
/* false cond = [1:10] || [7:100] */
|
||||
for (int i = 0; i < 0xFFFF; i++) {
|
||||
/* Generate random number range:[m,n] int a=m+rand()%(n-m+1); */
|
||||
cond = (FloatCond)(1 + (rand() % (FLOAT_UNO - 1 + 1)));
|
||||
cond1 = (FloatCond)((FLOAT_UNO + 1) + (rand() % (100 - 1 + 1)));
|
||||
EXPECT_FALSE(aot_compile_op_f64_compare(&comp_ctx, &func_ctx, cond));
|
||||
EXPECT_FALSE(aot_compile_op_f64_compare(&comp_ctx, &func_ctx, cond1));
|
||||
}
|
||||
}
|
196
tests/unit/compilation/aot_emit_control_test.cc
Normal file
196
tests/unit/compilation/aot_emit_control_test.cc
Normal file
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "test_helper.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "bh_read_file.h"
|
||||
#include "aot.h"
|
||||
#include "aot_llvm.h"
|
||||
#include "aot_emit_control.h"
|
||||
|
||||
static std::string CWD;
|
||||
static std::string MAIN_WASM = "/main.wasm";
|
||||
static char *WASM_FILE;
|
||||
|
||||
static std::string
|
||||
get_binary_path()
|
||||
{
|
||||
char cwd[1024];
|
||||
memset(cwd, 0, 1024);
|
||||
|
||||
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
|
||||
}
|
||||
|
||||
char *path_end = strrchr(cwd, '/');
|
||||
if (path_end != NULL) {
|
||||
*path_end = '\0';
|
||||
}
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
class aot_emit_control_test_suite : public testing::Test
|
||||
{
|
||||
protected:
|
||||
// You should make the members protected s.t. they can be
|
||||
// accessed from sub-classes.
|
||||
|
||||
// virtual void SetUp() will be called before each test is run. You
|
||||
// should define it if you need to initialize the varaibles.
|
||||
// Otherwise, this can be skipped.
|
||||
virtual void SetUp() {}
|
||||
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
CWD = get_binary_path();
|
||||
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
|
||||
}
|
||||
|
||||
// virtual void TearDown() will be called after each test is run.
|
||||
// You should define it if there is cleanup work to do. Otherwise,
|
||||
// you don't have to provide it.
|
||||
//
|
||||
virtual void TearDown() {}
|
||||
|
||||
static void TearDownTestCase() { free(WASM_FILE); }
|
||||
|
||||
WAMRRuntimeRAII<512 * 1024> runtime;
|
||||
};
|
||||
|
||||
TEST_F(aot_emit_control_test_suite, check_suspend_flags)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
char out_file_name[] = "out_file_name_test";
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
|
||||
func_ctx = comp_ctx->func_ctxes[1];
|
||||
EXPECT_EQ(true, check_suspend_flags(comp_ctx, func_ctx, false));
|
||||
}
|
||||
|
||||
TEST_F(aot_emit_control_test_suite, aot_compile_op_block)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
char out_file_name[] = "out_file_name_test";
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
|
||||
func_ctx = comp_ctx->func_ctxes[1];
|
||||
func_ctx->block_stack.block_list_end = nullptr;
|
||||
EXPECT_EQ(false, aot_compile_op_block(comp_ctx, func_ctx, nullptr, nullptr,
|
||||
0, 0, nullptr, 0, nullptr));
|
||||
}
|
||||
|
||||
TEST_F(aot_emit_control_test_suite, aot_compile_op_else)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
char out_file_name[] = "out_file_name_test";
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
|
||||
func_ctx = comp_ctx->func_ctxes[1];
|
||||
func_ctx->block_stack.block_list_end = nullptr;
|
||||
EXPECT_EQ(false, aot_compile_op_else(comp_ctx, func_ctx, nullptr));
|
||||
|
||||
AOTBlock block_list_end_test;
|
||||
block_list_end_test.label_type = LABEL_TYPE_FUNCTION;
|
||||
func_ctx->block_stack.block_list_end = &block_list_end_test;
|
||||
EXPECT_EQ(false, aot_compile_op_else(comp_ctx, func_ctx, nullptr));
|
||||
|
||||
block_list_end_test.label_type = LABEL_TYPE_IF;
|
||||
block_list_end_test.llvm_else_block = nullptr;
|
||||
EXPECT_EQ(false, aot_compile_op_else(comp_ctx, func_ctx, nullptr));
|
||||
}
|
101
tests/unit/compilation/aot_emit_function_test.cc
Normal file
101
tests/unit/compilation/aot_emit_function_test.cc
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "test_helper.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "bh_read_file.h"
|
||||
#include "aot_emit_control.h"
|
||||
#include "aot_emit_function.h"
|
||||
|
||||
static std::string CWD;
|
||||
static std::string MAIN_WASM = "/main.wasm";
|
||||
static char *WASM_FILE;
|
||||
|
||||
static std::string
|
||||
get_binary_path()
|
||||
{
|
||||
char cwd[1024];
|
||||
memset(cwd, 0, 1024);
|
||||
|
||||
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
|
||||
}
|
||||
|
||||
char *path_end = strrchr(cwd, '/');
|
||||
if (path_end != NULL) {
|
||||
*path_end = '\0';
|
||||
}
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
class aot_emit_function_test_suite : public testing::Test
|
||||
{
|
||||
protected:
|
||||
// You should make the members protected s.t. they can be
|
||||
// accessed from sub-classes.
|
||||
|
||||
// virtual void SetUp() will be called before each test is run. You
|
||||
// should define it if you need to initialize the varaibles.
|
||||
// Otherwise, this can be skipped.
|
||||
virtual void SetUp() {}
|
||||
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
CWD = get_binary_path();
|
||||
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
|
||||
}
|
||||
|
||||
// virtual void TearDown() will be called after each test is run.
|
||||
// You should define it if there is cleanup work to do. Otherwise,
|
||||
// you don't have to provide it.
|
||||
//
|
||||
virtual void TearDown() {}
|
||||
|
||||
static void TearDownTestCase() { free(WASM_FILE); }
|
||||
|
||||
WAMRRuntimeRAII<512 * 1024> runtime;
|
||||
};
|
||||
|
||||
TEST_F(aot_emit_function_test_suite, aot_compile_op_call)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
char out_file_name[] = "out_file_name_test";
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
|
||||
func_ctx = comp_ctx->func_ctxes[1];
|
||||
EXPECT_EQ(false, aot_compile_op_call(comp_ctx, func_ctx, 9999, true));
|
||||
}
|
335
tests/unit/compilation/aot_emit_memory_test.cc
Normal file
335
tests/unit/compilation/aot_emit_memory_test.cc
Normal file
|
@ -0,0 +1,335 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "bh_platform.h"
|
||||
#include "bh_read_file.h"
|
||||
#include "aot_emit_memory.h"
|
||||
#include "test_helper.h"
|
||||
|
||||
#define DEFAULT_CYCLE_TIMES 0xFFFF
|
||||
#define DEFAULT_MAX_RAND_NUM 0xFFFFFFFF
|
||||
|
||||
static std::string CWD;
|
||||
static std::string MAIN_WASM = "/main.wasm";
|
||||
static char *WASM_FILE;
|
||||
|
||||
static std::string
|
||||
get_binary_path()
|
||||
{
|
||||
char cwd[1024];
|
||||
memset(cwd, 0, 1024);
|
||||
|
||||
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
|
||||
}
|
||||
|
||||
char *path_end = strrchr(cwd, '/');
|
||||
if (path_end != NULL) {
|
||||
*path_end = '\0';
|
||||
}
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
class compilation_aot_emit_memory_test : public testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
CWD = get_binary_path();
|
||||
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
|
||||
AOTCompOption option = { 0 };
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.stack_bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = reinterpret_cast<WASMModule *>(wasm_runtime_load(
|
||||
wasm_file_buf, wasm_file_size, error_buf, sizeof(error_buf)));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
comp_data = aot_create_comp_data(wasm_module, NULL, false);
|
||||
EXPECT_NE(comp_data, nullptr);
|
||||
|
||||
// properly init compilation and function context, to do that,
|
||||
// use as a dummy module(instead of compile the function in it, simply
|
||||
// test the APIs)
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
func_ctx = comp_ctx->func_ctxes[0];
|
||||
EXPECT_NE(func_ctx, nullptr);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
aot_destroy_comp_context(comp_ctx);
|
||||
aot_destroy_comp_data(comp_data);
|
||||
wasm_runtime_unload(reinterpret_cast<WASMModuleCommon *>(wasm_module));
|
||||
}
|
||||
|
||||
public:
|
||||
WASMModule *wasm_module = nullptr;
|
||||
AOTCompData *comp_data = nullptr;
|
||||
AOTCompContext *comp_ctx = nullptr;
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
|
||||
WAMRRuntimeRAII<512 * 1024> runtime;
|
||||
};
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_check_memory_overflow)
|
||||
{
|
||||
uint32 offset = 64;
|
||||
uint32 bytes = 4;
|
||||
|
||||
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
offset = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes, false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_i32_load)
|
||||
{
|
||||
uint32 align = 0;
|
||||
uint32 offset = 1024;
|
||||
uint32 bytes = 0;
|
||||
bool sign = false;
|
||||
bool atomic = false;
|
||||
|
||||
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
align = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
offset = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
bytes = (1 + (rand() % (4 - 1 + 1)));
|
||||
printf("---%d", aot_compile_op_i32_load(comp_ctx, func_ctx, align,
|
||||
offset, bytes, sign, atomic));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_i64_load)
|
||||
{
|
||||
uint32 align = 0;
|
||||
uint32 offset = 1024;
|
||||
uint32 bytes = 0;
|
||||
bool sign = false;
|
||||
bool atomic = false;
|
||||
|
||||
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
align = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
offset = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
bytes = (1 + (rand() % (4 - 1 + 1)));
|
||||
sign = !sign;
|
||||
atomic = !atomic;
|
||||
aot_compile_op_i64_load(comp_ctx, func_ctx, align, offset, bytes, sign,
|
||||
atomic);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_f32_load)
|
||||
{
|
||||
uint32 align = 10;
|
||||
uint32 offset = 10;
|
||||
|
||||
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
align = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
offset = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
aot_compile_op_f32_load(comp_ctx, func_ctx, align, offset);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_f64_load)
|
||||
{
|
||||
uint32 align = 10;
|
||||
uint32 offset = 10;
|
||||
|
||||
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
align = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
offset = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
aot_compile_op_f64_load(comp_ctx, func_ctx, align, offset);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_i32_store)
|
||||
{
|
||||
uint32 align = 0;
|
||||
uint32 offset = 0;
|
||||
uint32 bytes = 0;
|
||||
bool atomic = false;
|
||||
|
||||
EXPECT_FALSE(aot_compile_op_i32_store(comp_ctx, func_ctx, align, offset,
|
||||
bytes, atomic));
|
||||
|
||||
/* Generate random number range:[m,n] int a=m+rand()%(n-m+1); */
|
||||
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
bytes = (1 + (rand() % (4 - 1 + 1)));
|
||||
offset = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
|
||||
align = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
|
||||
atomic = !atomic;
|
||||
|
||||
EXPECT_FALSE(aot_compile_op_i32_store(comp_ctx, func_ctx, align, offset,
|
||||
bytes, atomic));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_i64_store)
|
||||
{
|
||||
uint32 align = 0;
|
||||
uint32 offset = 0;
|
||||
uint32 bytes = 0;
|
||||
bool atomic = false;
|
||||
|
||||
EXPECT_FALSE(aot_compile_op_i64_store(comp_ctx, func_ctx, align, offset,
|
||||
bytes, atomic));
|
||||
|
||||
/* Generate random number range:[m,n] int a=m+rand()%(n-m+1); */
|
||||
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
bytes = (1 + (rand() % (8 - 1 + 1)));
|
||||
offset = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
|
||||
align = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
|
||||
atomic = !atomic;
|
||||
|
||||
EXPECT_FALSE(aot_compile_op_i64_store(comp_ctx, func_ctx, align, offset,
|
||||
bytes, atomic));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_f32_store)
|
||||
{
|
||||
uint32 align = 0;
|
||||
uint32 offset = 0;
|
||||
|
||||
EXPECT_FALSE(aot_compile_op_f32_store(comp_ctx, func_ctx, align, offset));
|
||||
|
||||
/* Generate random number range:[m,n] int a=m+rand()%(n-m+1); */
|
||||
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
offset = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
|
||||
align = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
|
||||
|
||||
EXPECT_FALSE(
|
||||
aot_compile_op_f32_store(comp_ctx, func_ctx, align, offset));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_f64_store)
|
||||
{
|
||||
uint32 align = 0;
|
||||
uint32 offset = 0;
|
||||
|
||||
EXPECT_FALSE(aot_compile_op_f64_store(comp_ctx, func_ctx, align, offset));
|
||||
|
||||
/* Generate random number range:[m,n] int a=m+rand()%(n-m+1); */
|
||||
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
offset = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
|
||||
align = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
|
||||
|
||||
EXPECT_FALSE(
|
||||
aot_compile_op_f64_store(comp_ctx, func_ctx, align, offset));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_memory_size)
|
||||
{
|
||||
aot_compile_op_memory_size(comp_ctx, func_ctx);
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_memory_grow)
|
||||
{
|
||||
aot_compile_op_memory_grow(comp_ctx, func_ctx);
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_memory_init)
|
||||
{
|
||||
uint32 seg_index = 0;
|
||||
|
||||
/* Generate random number range:[m,n] int a=m+rand()%(n-m+1); */
|
||||
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
seg_index = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
|
||||
aot_compile_op_memory_init(comp_ctx, func_ctx, seg_index);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_data_drop)
|
||||
{
|
||||
uint32 seg_index = 0;
|
||||
|
||||
/* Generate random number range:[m,n] int a=m+rand()%(n-m+1); */
|
||||
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
seg_index = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
|
||||
aot_compile_op_data_drop(comp_ctx, func_ctx, seg_index);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_memory_copy)
|
||||
{
|
||||
aot_compile_op_memory_copy(comp_ctx, func_ctx);
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_memory_fill)
|
||||
{
|
||||
aot_compile_op_memory_fill(comp_ctx, func_ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_atomic_rmw)
|
||||
{
|
||||
uint8 atomic_op = LLVMAtomicRMWBinOpAdd;
|
||||
uint8 op_type = VALUE_TYPE_I32;
|
||||
uint32 align = 4;
|
||||
uint32 offset = 64;
|
||||
uint32 bytes = 4;
|
||||
|
||||
aot_compile_op_atomic_rmw(comp_ctx, func_ctx, atomic_op, op_type, align,
|
||||
offset, bytes);
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_atomic_cmpxchg)
|
||||
{
|
||||
|
||||
uint8 op_type = VALUE_TYPE_I32;
|
||||
uint32 align = 4;
|
||||
uint32 offset = 64;
|
||||
uint32 bytes = 4;
|
||||
|
||||
aot_compile_op_atomic_cmpxchg(comp_ctx, func_ctx, op_type, align, offset,
|
||||
bytes);
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_atomic_wait)
|
||||
{
|
||||
|
||||
uint8 op_type = VALUE_TYPE_I32;
|
||||
uint32 align = 4;
|
||||
uint32 offset = 64;
|
||||
uint32 bytes = 4;
|
||||
|
||||
aot_compile_op_atomic_wait(comp_ctx, func_ctx, op_type, align, offset,
|
||||
bytes);
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_memory_test, aot_compiler_op_atomic_notify)
|
||||
{
|
||||
|
||||
uint32 align = 4;
|
||||
uint32 offset = 64;
|
||||
uint32 bytes = 4;
|
||||
|
||||
aot_compiler_op_atomic_notify(comp_ctx, func_ctx, align, offset, bytes);
|
||||
}
|
||||
#endif
|
119
tests/unit/compilation/aot_emit_numberic_test.cc
Normal file
119
tests/unit/compilation/aot_emit_numberic_test.cc
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "test_helper.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "bh_read_file.h"
|
||||
#include "aot_llvm.h"
|
||||
#include "aot_emit_numberic.h"
|
||||
#include "aot_compiler.h"
|
||||
|
||||
static std::string CWD;
|
||||
static std::string MAIN_WASM = "/main.wasm";
|
||||
static char *WASM_FILE;
|
||||
|
||||
static std::string
|
||||
get_binary_path()
|
||||
{
|
||||
char cwd[1024];
|
||||
memset(cwd, 0, 1024);
|
||||
|
||||
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
|
||||
}
|
||||
|
||||
char *path_end = strrchr(cwd, '/');
|
||||
if (path_end != NULL) {
|
||||
*path_end = '\0';
|
||||
}
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
class aot_emit_numberic_test_suite : public testing::Test
|
||||
{
|
||||
protected:
|
||||
// You should make the members protected s.t. they can be
|
||||
// accessed from sub-classes.
|
||||
|
||||
// virtual void SetUp() will be called before each test is run. You
|
||||
// should define it if you need to initialize the varaibles.
|
||||
// Otherwise, this can be skipped.
|
||||
virtual void SetUp() {}
|
||||
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
CWD = get_binary_path();
|
||||
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
|
||||
}
|
||||
|
||||
// virtual void TearDown() will be called after each test is run.
|
||||
// You should define it if there is cleanup work to do. Otherwise,
|
||||
// you don't have to provide it.
|
||||
//
|
||||
virtual void TearDown() {}
|
||||
|
||||
static void TearDownTestCase() { free(WASM_FILE); }
|
||||
|
||||
WAMRRuntimeRAII<512 * 1024> runtime;
|
||||
};
|
||||
|
||||
TEST_F(aot_emit_numberic_test_suite, aot_compile_op_functions)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
func_ctx = comp_ctx->func_ctxes[1];
|
||||
|
||||
EXPECT_EQ(false,
|
||||
aot_compile_op_f32_arithmetic(comp_ctx, func_ctx, FLOAT_SUB));
|
||||
EXPECT_EQ(false, aot_compile_op_f32_copysign(comp_ctx, func_ctx));
|
||||
EXPECT_EQ(false, aot_compile_op_f32_math(comp_ctx, func_ctx, FLOAT_NEG));
|
||||
EXPECT_EQ(false,
|
||||
aot_compile_op_f64_arithmetic(comp_ctx, func_ctx, FLOAT_SUB));
|
||||
EXPECT_EQ(false, aot_compile_op_f64_copysign(comp_ctx, func_ctx));
|
||||
EXPECT_EQ(false, aot_compile_op_f64_math(comp_ctx, func_ctx, FLOAT_NEG));
|
||||
EXPECT_EQ(false, aot_compile_op_i32_clz(comp_ctx, func_ctx));
|
||||
EXPECT_EQ(false, aot_compile_op_i32_ctz(comp_ctx, func_ctx));
|
||||
EXPECT_EQ(false, aot_compile_op_i32_popcnt(comp_ctx, func_ctx));
|
||||
EXPECT_EQ(false, aot_compile_op_i32_shift(comp_ctx, func_ctx, INT_SHR_S));
|
||||
EXPECT_EQ(false, aot_compile_op_i64_arithmetic(comp_ctx, func_ctx, INT_SUB,
|
||||
nullptr));
|
||||
EXPECT_EQ(false, aot_compile_op_i64_bitwise(comp_ctx, func_ctx, INT_OR));
|
||||
EXPECT_EQ(false, aot_compile_op_i64_clz(comp_ctx, func_ctx));
|
||||
EXPECT_EQ(false, aot_compile_op_i64_ctz(comp_ctx, func_ctx));
|
||||
EXPECT_EQ(false, aot_compile_op_i64_popcnt(comp_ctx, func_ctx));
|
||||
EXPECT_EQ(false, aot_compile_op_i64_shift(comp_ctx, func_ctx, INT_SHR_S));
|
||||
}
|
143
tests/unit/compilation/aot_emit_parametric_test.cc
Normal file
143
tests/unit/compilation/aot_emit_parametric_test.cc
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "test_helper.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "bh_read_file.h"
|
||||
#include "aot_llvm.h"
|
||||
#include "aot_emit_parametric.h"
|
||||
|
||||
static std::string CWD;
|
||||
static std::string MAIN_WASM = "/main.wasm";
|
||||
static char *WASM_FILE;
|
||||
|
||||
static std::string
|
||||
get_binary_path()
|
||||
{
|
||||
char cwd[1024];
|
||||
memset(cwd, 0, 1024);
|
||||
|
||||
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
|
||||
}
|
||||
|
||||
char *path_end = strrchr(cwd, '/');
|
||||
if (path_end != NULL) {
|
||||
*path_end = '\0';
|
||||
}
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
class aot_emit_parametric_test_suite : public testing::Test
|
||||
{
|
||||
protected:
|
||||
// You should make the members protected s.t. they can be
|
||||
// accessed from sub-classes.
|
||||
|
||||
// virtual void SetUp() will be called before each test is run. You
|
||||
// should define it if you need to initialize the varaibles.
|
||||
// Otherwise, this can be skipped.
|
||||
virtual void SetUp() {}
|
||||
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
CWD = get_binary_path();
|
||||
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
|
||||
}
|
||||
|
||||
// virtual void TearDown() will be called after each test is run.
|
||||
// You should define it if there is cleanup work to do. Otherwise,
|
||||
// you don't have to provide it.
|
||||
//
|
||||
virtual void TearDown() {}
|
||||
|
||||
static void TearDownTestCase() { free(WASM_FILE); }
|
||||
|
||||
WAMRRuntimeRAII<512 * 1024> runtime;
|
||||
};
|
||||
|
||||
TEST_F(aot_emit_parametric_test_suite, aot_compile_op_select)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
func_ctx = comp_ctx->func_ctxes[1];
|
||||
|
||||
EXPECT_FALSE(aot_compile_op_select(comp_ctx, func_ctx, true));
|
||||
EXPECT_FALSE(aot_compile_op_select(comp_ctx, func_ctx, false));
|
||||
}
|
||||
|
||||
TEST_F(aot_emit_parametric_test_suite, aot_compile_op_drop)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
func_ctx = comp_ctx->func_ctxes[1];
|
||||
func_ctx->block_stack.block_list_end = nullptr;
|
||||
|
||||
EXPECT_FALSE(aot_compile_op_drop(comp_ctx, func_ctx, true));
|
||||
EXPECT_FALSE(aot_compile_op_drop(comp_ctx, func_ctx, false));
|
||||
}
|
105
tests/unit/compilation/aot_emit_table_test.cc
Normal file
105
tests/unit/compilation/aot_emit_table_test.cc
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "test_helper.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "bh_read_file.h"
|
||||
#include "aot_llvm.h"
|
||||
#include "aot_emit_table.h"
|
||||
|
||||
static std::string CWD;
|
||||
static std::string MAIN_WASM = "/main.wasm";
|
||||
static char *WASM_FILE;
|
||||
|
||||
static std::string
|
||||
get_binary_path()
|
||||
{
|
||||
char cwd[1024];
|
||||
memset(cwd, 0, 1024);
|
||||
|
||||
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
|
||||
}
|
||||
|
||||
char *path_end = strrchr(cwd, '/');
|
||||
if (path_end != NULL) {
|
||||
*path_end = '\0';
|
||||
}
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
class aot_emit_table_test_suite : public testing::Test
|
||||
{
|
||||
protected:
|
||||
// You should make the members protected s.t. they can be
|
||||
// accessed from sub-classes.
|
||||
|
||||
// virtual void SetUp() will be called before each test is run. You
|
||||
// should define it if you need to initialize the varaibles.
|
||||
// Otherwise, this can be skipped.
|
||||
virtual void SetUp() {}
|
||||
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
CWD = get_binary_path();
|
||||
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
|
||||
}
|
||||
|
||||
// virtual void TearDown() will be called after each test is run.
|
||||
// You should define it if there is cleanup work to do. Otherwise,
|
||||
// you don't have to provide it.
|
||||
//
|
||||
virtual void TearDown() {}
|
||||
static void TearDownTestCase() { free(WASM_FILE); }
|
||||
|
||||
WAMRRuntimeRAII<512 * 1024> runtime;
|
||||
};
|
||||
|
||||
TEST_F(aot_emit_table_test_suite, get_tbl_inst_offset)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
func_ctx = comp_ctx->func_ctxes[1];
|
||||
|
||||
EXPECT_NE(0, get_tbl_inst_offset(comp_ctx, func_ctx, 6));
|
||||
EXPECT_NE(0, get_tbl_inst_offset(comp_ctx, func_ctx, 1));
|
||||
EXPECT_NE(0, get_tbl_inst_offset(comp_ctx, func_ctx, 0));
|
||||
((AOTCompData *)comp_ctx->comp_data)->import_table_count = 1;
|
||||
AOTImportTable import_tables_test;
|
||||
((AOTCompData *)comp_ctx->comp_data)->import_tables = &import_tables_test;
|
||||
EXPECT_NE(0, get_tbl_inst_offset(comp_ctx, func_ctx, 6));
|
||||
}
|
97
tests/unit/compilation/aot_emit_variable_test.cc
Normal file
97
tests/unit/compilation/aot_emit_variable_test.cc
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "aot_emit_variable.h"
|
||||
|
||||
#define DEFAULT_CYCLE_TIMES 0xFFFF
|
||||
#define DEFAULT_MAX_RAND_NUM 0xFFFFFFFF
|
||||
|
||||
class compilation_aot_emit_variable_test : public testing::Test
|
||||
{
|
||||
protected:
|
||||
virtual void SetUp() {}
|
||||
virtual void TearDown() {}
|
||||
|
||||
public:
|
||||
AOTCompContext comp_ctx = { 0 };
|
||||
AOTFuncContext func_ctx = { 0 };
|
||||
};
|
||||
|
||||
TEST_F(compilation_aot_emit_variable_test, aot_compile_op_get_local)
|
||||
{
|
||||
AOTCompContext *pcomp_ctx = &comp_ctx;
|
||||
AOTFuncContext *pfunc_ctx = &func_ctx;
|
||||
uint32 local_idx = 0;
|
||||
|
||||
// aot_compile_op_get_local(NULL, pfunc_ctx, local_idx);
|
||||
|
||||
// for (uint32_t i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
// local_idx = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
// aot_compile_op_get_local(pcomp_ctx, pfunc_ctx, local_idx);
|
||||
// }
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_variable_test, aot_compile_op_set_local)
|
||||
{
|
||||
|
||||
AOTCompContext *pcomp_ctx = &comp_ctx;
|
||||
AOTFuncContext *pfunc_ctx = &func_ctx;
|
||||
uint32 local_idx = 0;
|
||||
|
||||
// aot_compile_op_set_local(pcomp_ctx, pfunc_ctx, local_idx);
|
||||
|
||||
// for (uint32_t i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
// local_idx = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
// aot_compile_op_set_local(pcomp_ctx, pfunc_ctx, local_idx);
|
||||
// }
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_variable_test, aot_compile_op_tee_local)
|
||||
{
|
||||
|
||||
AOTCompContext *pcomp_ctx = &comp_ctx;
|
||||
AOTFuncContext *pfunc_ctx = &func_ctx;
|
||||
uint32 local_idx = 0;
|
||||
|
||||
// aot_compile_op_tee_local(pcomp_ctx, pfunc_ctx, local_idx);
|
||||
|
||||
// for (uint32_t i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
// local_idx = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
// aot_compile_op_tee_local(pcomp_ctx, pfunc_ctx, local_idx);
|
||||
// }
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_variable_test, aot_compile_op_get_global)
|
||||
{
|
||||
AOTCompContext *pcomp_ctx = &comp_ctx;
|
||||
AOTFuncContext *pfunc_ctx = &func_ctx;
|
||||
uint32 global_idx = 0;
|
||||
|
||||
// aot_compile_op_get_global(pcomp_ctx, pfunc_ctx, global_idx);
|
||||
|
||||
// for (uint32_t i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
// local_idx = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
// aot_compile_op_get_global(pcomp_ctx, pfunc_ctx, global_idx);
|
||||
// }
|
||||
}
|
||||
|
||||
TEST_F(compilation_aot_emit_variable_test, aot_compile_op_set_global)
|
||||
{
|
||||
AOTCompContext *pcomp_ctx = &comp_ctx;
|
||||
AOTFuncContext *pfunc_ctx = &func_ctx;
|
||||
uint32 global_idx = 0;
|
||||
bool is_aux_stack = false;
|
||||
|
||||
// aot_compile_op_set_global(pcomp_ctx, pfunc_ctx, global_idx,
|
||||
// is_aux_stack);
|
||||
|
||||
// for (uint32_t i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
|
||||
// is_aux_stack = is_aux_stack ? false : ture;
|
||||
// local_idx = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
|
||||
// aot_compile_op_set_global(pcomp_ctx, pfunc_ctx,
|
||||
// global_idx,is_aux_stack);
|
||||
// }
|
||||
}
|
305
tests/unit/compilation/aot_llvm_test.cc
Normal file
305
tests/unit/compilation/aot_llvm_test.cc
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "test_helper.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "bh_read_file.h"
|
||||
#include "aot_llvm.h"
|
||||
#include "aot_compiler.h"
|
||||
|
||||
static std::string CWD;
|
||||
static std::string MAIN_WASM = "/main.wasm";
|
||||
static char *WASM_FILE;
|
||||
|
||||
static std::string
|
||||
get_binary_path()
|
||||
{
|
||||
char cwd[1024];
|
||||
memset(cwd, 0, 1024);
|
||||
|
||||
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
|
||||
}
|
||||
|
||||
char *path_end = strrchr(cwd, '/');
|
||||
if (path_end != NULL) {
|
||||
*path_end = '\0';
|
||||
}
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
class aot_llvm_test_suite : public testing::Test
|
||||
{
|
||||
protected:
|
||||
// You should make the members protected s.t. they can be
|
||||
// accessed from sub-classes.
|
||||
|
||||
// virtual void SetUp() will be called before each test is run. You
|
||||
// should define it if you need to initialize the varaibles.
|
||||
// Otherwise, this can be skipped.
|
||||
virtual void SetUp() {}
|
||||
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
CWD = get_binary_path();
|
||||
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
|
||||
}
|
||||
|
||||
// virtual void TearDown() will be called after each test is run.
|
||||
// You should define it if there is cleanup work to do. Otherwise,
|
||||
// you don't have to provide it.
|
||||
//
|
||||
virtual void TearDown() {}
|
||||
static void TearDownTestCase() { free(WASM_FILE); }
|
||||
|
||||
WAMRRuntimeRAII<512 * 1024> runtime;
|
||||
};
|
||||
|
||||
TEST_F(aot_llvm_test_suite, aot_functions)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
WASMValue wasm_value;
|
||||
LLVMTypeRef param_types[1];
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
func_ctx = comp_ctx->func_ctxes[1];
|
||||
|
||||
param_types[0] = F64_TYPE;
|
||||
EXPECT_TRUE(aot_call_llvm_intrinsic(comp_ctx, func_ctx, "f32_demote_f64",
|
||||
F32_TYPE, param_types, 0));
|
||||
|
||||
/* Test function aot_get_native_symbol_index. */
|
||||
AOTNativeSymbol elem_insert_1;
|
||||
elem_insert_1.index = -1;
|
||||
bh_list_insert(&comp_ctx->native_symbols, &elem_insert_1);
|
||||
|
||||
AOTNativeSymbol elem_insert_2;
|
||||
strcpy(elem_insert_2.symbol, "f64#_test");
|
||||
elem_insert_2.index = -1;
|
||||
bh_list_insert(&comp_ctx->native_symbols, &elem_insert_2);
|
||||
comp_ctx->pointer_size = sizeof(uint32);
|
||||
strcpy(comp_ctx->target_arch, "i386");
|
||||
EXPECT_NE(-1, aot_get_native_symbol_index(comp_ctx, "f64#_test"));
|
||||
}
|
||||
|
||||
TEST_F(aot_llvm_test_suite, wasm_type_to_llvm_type) {}
|
||||
|
||||
TEST_F(aot_llvm_test_suite, aot_build_zero_function_ret)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
AOTFuncType func_type;
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = false;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
func_ctx = comp_ctx->func_ctxes[1];
|
||||
|
||||
func_type.result_count = 1;
|
||||
func_type.param_count = 0;
|
||||
func_type.types[func_type.param_count] = VALUE_TYPE_I32;
|
||||
EXPECT_NE(0, aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type));
|
||||
func_type.types[func_type.param_count] = VALUE_TYPE_I64;
|
||||
EXPECT_NE(0, aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type));
|
||||
func_type.types[func_type.param_count] = VALUE_TYPE_F32;
|
||||
EXPECT_NE(0, aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type));
|
||||
func_type.types[func_type.param_count] = VALUE_TYPE_F64;
|
||||
EXPECT_NE(0, aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type));
|
||||
func_type.types[func_type.param_count] = VALUE_TYPE_V128;
|
||||
EXPECT_NE(0, aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type));
|
||||
/* THe current optimization, if not actually use ref_types in wasm module,
|
||||
* it will set to false, so test false condition */
|
||||
func_type.types[func_type.param_count] = VALUE_TYPE_FUNCREF;
|
||||
EXPECT_DEATH(aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type),
|
||||
".*");
|
||||
func_type.types[func_type.param_count] = VALUE_TYPE_EXTERNREF;
|
||||
EXPECT_DEATH(aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type),
|
||||
".*");
|
||||
func_type.types[func_type.param_count] = 0xFF;
|
||||
EXPECT_DEATH(aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type),
|
||||
".*");
|
||||
}
|
||||
|
||||
TEST_F(aot_llvm_test_suite, aot_destroy_comp_context)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
AOTFuncContext *func_ctx = nullptr;
|
||||
AOTFuncType func_type;
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
|
||||
AOTNativeSymbol elem_insert_1;
|
||||
elem_insert_1.index = -1;
|
||||
bh_list_insert(&comp_ctx->native_symbols, &elem_insert_1);
|
||||
aot_destroy_comp_context(comp_ctx);
|
||||
|
||||
aot_destroy_comp_context(nullptr);
|
||||
}
|
||||
|
||||
TEST_F(aot_llvm_test_suite, aot_create_comp_context)
|
||||
{
|
||||
const char *wasm_file = WASM_FILE;
|
||||
unsigned int wasm_file_size = 0;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
char error_buf[128] = { 0 };
|
||||
wasm_module_t wasm_module = nullptr;
|
||||
|
||||
struct AOTCompData *comp_data = nullptr;
|
||||
struct AOTCompContext *comp_ctx = nullptr;
|
||||
AOTCompOption option = { 0 };
|
||||
|
||||
option.opt_level = 3;
|
||||
option.size_level = 3;
|
||||
option.output_format = AOT_FORMAT_FILE;
|
||||
/* default value, enable or disable depends on the platform */
|
||||
option.bounds_checks = 2;
|
||||
option.enable_simd = true;
|
||||
option.enable_aux_stack_check = true;
|
||||
option.enable_bulk_memory = true;
|
||||
option.enable_ref_types = true;
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
|
||||
EXPECT_NE(wasm_file_buf, nullptr);
|
||||
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
EXPECT_NE(wasm_module, nullptr);
|
||||
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
|
||||
EXPECT_NE(nullptr, comp_data);
|
||||
|
||||
option.enable_thread_mgr = true;
|
||||
option.enable_tail_call = true;
|
||||
option.is_indirect_mode = true;
|
||||
option.disable_llvm_intrinsics = true;
|
||||
option.disable_llvm_lto = true;
|
||||
option.is_jit_mode = true;
|
||||
|
||||
option.target_arch = (char *)"arm";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
option.output_format = 100;
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
|
||||
// Test every target_arch.
|
||||
option.is_jit_mode = false;
|
||||
option.target_arch = (char *)"arm";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
option.target_arch = (char *)"armeb";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
option.target_arch = (char *)"thumb";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
option.target_arch = (char *)"thumbeb";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
option.target_arch = (char *)"aarch64";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
option.target_arch = (char *)"aarch64_be";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
option.target_arch = (char *)"help";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
|
||||
// Test every target_abi.
|
||||
option.target_arch = (char *)"arm";
|
||||
option.target_abi = (char *)"test";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
option.target_abi = (char *)"help";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
option.target_abi = (char *)"msvc";
|
||||
option.target_arch = (char *)"i386";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
|
||||
option.cpu_features = (char *)"test";
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
option.is_sgx_platform = true;
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
comp_data->func_count = 0;
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
}
|
BIN
tests/unit/compilation/wasm-apps/main.wasm
Normal file
BIN
tests/unit/compilation/wasm-apps/main.wasm
Normal file
Binary file not shown.
65
tests/unit/custom-section/CMakeLists.txt
Normal file
65
tests/unit/custom-section/CMakeLists.txt
Normal file
|
@ -0,0 +1,65 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 2.9)
|
||||
|
||||
project (test-custom-section)
|
||||
|
||||
add_definitions (-DRUN_ON_LINUX)
|
||||
|
||||
set (WAMR_BUILD_LIBC_WASI 0)
|
||||
set (WAMR_BUILD_LIBC_BUILTIN 0)
|
||||
set (WAMR_BUILD_JIT 0)
|
||||
set (WAMR_BUILD_LAZY_JIT 0)
|
||||
set (WAMR_BUILD_AOT 1)
|
||||
|
||||
add_definitions(-DWASM_ENABLE_WAMR_COMPILER=1)
|
||||
add_definitions (-DWASM_ENABLE_DUMP_CALL_STACK=1)
|
||||
add_definitions (-DWASM_ENABLE_AOT_STACK_FRAME=1)
|
||||
|
||||
# Feature to test
|
||||
set (WAMR_BUILD_LOAD_CUSTOM_SECTION 1)
|
||||
|
||||
include (../unit_common.cmake)
|
||||
|
||||
set (LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm")
|
||||
if (NOT EXISTS "${LLVM_SRC_ROOT}/build")
|
||||
message (FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/build")
|
||||
endif ()
|
||||
set (CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/build;${CMAKE_PREFIX_PATH}")
|
||||
find_package(LLVM REQUIRED CONFIG)
|
||||
include_directories(${LLVM_INCLUDE_DIRS})
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||
|
||||
include (${IWASM_DIR}/compilation/iwasm_compl.cmake)
|
||||
|
||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
|
||||
|
||||
set (UNIT_SOURCE ${source_all})
|
||||
|
||||
set (unit_test_sources
|
||||
${UNIT_SOURCE}
|
||||
${PLATFORM_SHARED_SOURCE}
|
||||
${UTILS_SHARED_SOURCE}
|
||||
${MEM_ALLOC_SHARED_SOURCE}
|
||||
${NATIVE_INTERFACE_SOURCE}
|
||||
${IWASM_COMMON_SOURCE}
|
||||
${IWASM_INTERP_SOURCE}
|
||||
${IWASM_AOT_SOURCE}
|
||||
${IWASM_COMPL_SOURCE}
|
||||
${WASM_APP_LIB_SOURCE_ALL}
|
||||
)
|
||||
|
||||
# Automatically build wasm-apps for this test
|
||||
add_subdirectory(wasm-apps)
|
||||
|
||||
# Now simply link against gtest or gtest_main as needed. Eg
|
||||
add_executable (custom_section_test ${unit_test_sources})
|
||||
|
||||
target_link_libraries (custom_section_test ${LLVM_AVAILABLE_LIBS} gtest_main )
|
||||
|
||||
gtest_discover_tests(custom_section_test)
|
161
tests/unit/custom-section/custom_section_test.cc
Normal file
161
tests/unit/custom-section/custom_section_test.cc
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "bh_platform.h"
|
||||
#include <fstream>
|
||||
#include "test_helper.h"
|
||||
#include "aot_export.h"
|
||||
|
||||
class CustomSectionTest : public testing::Test
|
||||
{
|
||||
protected:
|
||||
// You should make the members protected s.t. they can be
|
||||
// accessed from sub-classes.
|
||||
|
||||
// virtual void SetUp() will be called before each test is run. You
|
||||
// should define it if you need to initialize the varaibles.
|
||||
// Otherwise, this can be skipped.
|
||||
virtual void SetUp() {}
|
||||
|
||||
// virtual void TearDown() will be called after each test is run.
|
||||
// You should define it if there is cleanup work to do. Otherwise,
|
||||
// you don't have to provide it.
|
||||
//
|
||||
virtual void TearDown() {}
|
||||
|
||||
public:
|
||||
WAMRRuntimeRAII<1 * 1024 * 1024> runtime;
|
||||
};
|
||||
|
||||
TEST_F(CustomSectionTest, get_custom_section_from_wasm_module_t)
|
||||
{
|
||||
uint32_t length, len_from_aot;
|
||||
const uint8_t *content, *content_from_aot;
|
||||
std::ifstream wasm_file("wasm-apps/app.wasm", std::ios::binary);
|
||||
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(wasm_file),
|
||||
{});
|
||||
{
|
||||
WAMRModule module(buffer.data(), buffer.size());
|
||||
aot_comp_data_t comp_data = NULL;
|
||||
aot_comp_context_t comp_ctx = NULL;
|
||||
std::vector<const char *> sections_to_emit{
|
||||
"name",
|
||||
".debug_info",
|
||||
".debug_abbrev",
|
||||
/* skip ".debug_line" section in AoT module */
|
||||
".debug_str",
|
||||
"producers",
|
||||
};
|
||||
|
||||
AOTCompOption option = { 0 };
|
||||
option.custom_sections = (char **)sections_to_emit.data();
|
||||
option.custom_sections_count = 5;
|
||||
|
||||
{
|
||||
/* Compile an AoT module */
|
||||
comp_data = aot_create_comp_data(module.get(), NULL, false);
|
||||
EXPECT_NE(comp_data, nullptr);
|
||||
|
||||
comp_ctx = aot_create_comp_context(comp_data, &option);
|
||||
EXPECT_NE(comp_ctx, nullptr);
|
||||
|
||||
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
|
||||
|
||||
EXPECT_TRUE(aot_emit_aot_file(comp_ctx, comp_data, "temp.aot"));
|
||||
}
|
||||
|
||||
std::ifstream aot_file("temp.aot", std::ios::binary);
|
||||
std::vector<unsigned char> aot_buffer(
|
||||
std::istreambuf_iterator<char>(aot_file), {});
|
||||
WAMRModule aot_module(aot_buffer.data(), aot_buffer.size());
|
||||
|
||||
/* name */
|
||||
content =
|
||||
wasm_runtime_get_custom_section(module.get(), "name", &length);
|
||||
EXPECT_NE(content, nullptr);
|
||||
EXPECT_GT(length, 0);
|
||||
|
||||
/* TODO: aot_emit_name_section don't
|
||||
EMIT_U32(AOT_CUSTOM_SECTION_RAW);*
|
||||
EMIT_STR("name");
|
||||
but instead
|
||||
EMIT_U32(AOT_CUSTOM_SECTION_NAME);
|
||||
can't use get_custom_section to get it
|
||||
*/
|
||||
// content_from_aot = wasm_runtime_get_custom_section(
|
||||
// aot_module.get(), "name", &len_from_aot);
|
||||
// EXPECT_NE(content_from_aot, nullptr);
|
||||
// EXPECT_EQ(len_from_aot, length);
|
||||
// EXPECT_EQ(memcmp(content_from_aot, content, length), 0);
|
||||
|
||||
/* .debug_info */
|
||||
content = wasm_runtime_get_custom_section(module.get(), ".debug_info",
|
||||
&length);
|
||||
EXPECT_NE(content, nullptr);
|
||||
EXPECT_GT(length, 0);
|
||||
|
||||
content_from_aot = wasm_runtime_get_custom_section(
|
||||
aot_module.get(), ".debug_info", &len_from_aot);
|
||||
EXPECT_NE(content_from_aot, nullptr);
|
||||
EXPECT_EQ(len_from_aot, length);
|
||||
EXPECT_EQ(memcmp(content_from_aot, content, length), 0);
|
||||
|
||||
/* .debug_abbrev */
|
||||
content = wasm_runtime_get_custom_section(module.get(), ".debug_abbrev",
|
||||
&length);
|
||||
EXPECT_NE(content, nullptr);
|
||||
EXPECT_GT(length, 0);
|
||||
|
||||
content_from_aot = wasm_runtime_get_custom_section(
|
||||
aot_module.get(), ".debug_abbrev", &len_from_aot);
|
||||
EXPECT_NE(content_from_aot, nullptr);
|
||||
EXPECT_EQ(len_from_aot, length);
|
||||
EXPECT_EQ(memcmp(content_from_aot, content, length), 0);
|
||||
|
||||
/* .debug_line */
|
||||
content = wasm_runtime_get_custom_section(module.get(), ".debug_line",
|
||||
&length);
|
||||
EXPECT_NE(content, nullptr);
|
||||
EXPECT_GT(length, 0);
|
||||
|
||||
content_from_aot = wasm_runtime_get_custom_section(
|
||||
aot_module.get(), ".debug_line", &len_from_aot);
|
||||
EXPECT_EQ(content_from_aot, nullptr);
|
||||
|
||||
/* .debug_str */
|
||||
content = wasm_runtime_get_custom_section(module.get(), ".debug_str",
|
||||
&length);
|
||||
EXPECT_NE(content, nullptr);
|
||||
EXPECT_GT(length, 0);
|
||||
|
||||
content_from_aot = wasm_runtime_get_custom_section(
|
||||
aot_module.get(), ".debug_str", &len_from_aot);
|
||||
EXPECT_NE(content_from_aot, nullptr);
|
||||
EXPECT_EQ(len_from_aot, length);
|
||||
EXPECT_EQ(memcmp(content_from_aot, content, length), 0);
|
||||
|
||||
/* producers */
|
||||
content =
|
||||
wasm_runtime_get_custom_section(module.get(), "producers", &length);
|
||||
EXPECT_NE(content, nullptr);
|
||||
EXPECT_GT(length, 0);
|
||||
|
||||
content_from_aot = wasm_runtime_get_custom_section(
|
||||
aot_module.get(), "producers", &len_from_aot);
|
||||
EXPECT_NE(content_from_aot, nullptr);
|
||||
EXPECT_EQ(len_from_aot, length);
|
||||
EXPECT_EQ(memcmp(content_from_aot, content, length), 0);
|
||||
|
||||
/* Not exist */
|
||||
content = wasm_runtime_get_custom_section(module.get(), "producers1",
|
||||
&length);
|
||||
EXPECT_EQ(content, nullptr);
|
||||
|
||||
content_from_aot = wasm_runtime_get_custom_section(
|
||||
aot_module.get(), "producers1", &len_from_aot);
|
||||
EXPECT_EQ(content_from_aot, nullptr);
|
||||
}
|
||||
}
|
14
tests/unit/custom-section/wasm-apps/CMakeLists.txt
Normal file
14
tests/unit/custom-section/wasm-apps/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 2.9)
|
||||
|
||||
project(wasm-apps-custom-section)
|
||||
|
||||
# Add -g option so there will be debugger related custom sections
|
||||
add_custom_target(app.wasm ALL
|
||||
COMMAND /opt/wasi-sdk/bin/clang -g -nostdlib
|
||||
-Wl,--no-entry,--export-all
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/app.wasm
|
||||
${CMAKE_CURRENT_LIST_DIR}/app.c
|
||||
)
|
10
tests/unit/custom-section/wasm-apps/app.c
Normal file
10
tests/unit/custom-section/wasm-apps/app.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
int
|
||||
main(int argc, char const *argv[])
|
||||
{
|
||||
return 0;
|
||||
}
|
51
tests/unit/gc/CMakeLists.txt
Normal file
51
tests/unit/gc/CMakeLists.txt
Normal file
|
@ -0,0 +1,51 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 2.9)
|
||||
|
||||
project (test-wamr-gc)
|
||||
|
||||
add_definitions (-DRUN_ON_LINUX)
|
||||
|
||||
set (WAMR_BUILD_GC 1)
|
||||
set (WAMR_BUILD_INTERP 1)
|
||||
set (WAMR_BUILD_AOT 0)
|
||||
set (WAMR_BUILD_APP_FRAMEWORK 0)
|
||||
|
||||
include (../unit_common.cmake)
|
||||
|
||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
|
||||
|
||||
set (UNIT_SOURCE ${source_all})
|
||||
|
||||
set (unit_test_sources
|
||||
${UNIT_SOURCE}
|
||||
${WAMR_RUNTIME_LIB_SOURCE}
|
||||
${UNCOMMON_SHARED_SOURCE}
|
||||
${SRC_LIST}
|
||||
${PLATFORM_SHARED_SOURCE}
|
||||
${UTILS_SHARED_SOURCE}
|
||||
${MEM_ALLOC_SHARED_SOURCE}
|
||||
${LIB_HOST_AGENT_SOURCE}
|
||||
${NATIVE_INTERFACE_SOURCE}
|
||||
${LIBC_BUILTIN_SOURCE}
|
||||
${IWASM_COMMON_SOURCE}
|
||||
${IWASM_INTERP_SOURCE}
|
||||
${IWASM_AOT_SOURCE}
|
||||
${IWASM_COMPL_SOURCE}
|
||||
${WASM_APP_LIB_SOURCE_ALL}
|
||||
)
|
||||
|
||||
add_executable (gc_test ${unit_test_sources})
|
||||
target_link_libraries (gc_test gtest_main)
|
||||
|
||||
add_custom_command(TARGET gc_test POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_LIST_DIR}/wasm-apps/*.was*
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Copy wasm files to directory ${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
|
||||
#gtest_discover_tests(gc_test)
|
102
tests/unit/gc/gc_test.cc
Normal file
102
tests/unit/gc/gc_test.cc
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "bh_platform.h"
|
||||
#include "bh_read_file.h"
|
||||
#include "wasm_export.h"
|
||||
|
||||
class WasmGCTest : public testing::Test
|
||||
{
|
||||
private:
|
||||
std::string get_binary_path()
|
||||
{
|
||||
char cwd[1024] = { 0 };
|
||||
|
||||
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *path_end = strrchr(cwd, '/');
|
||||
if (path_end != NULL) {
|
||||
*path_end = '\0';
|
||||
}
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp()
|
||||
{
|
||||
CWD = get_binary_path();
|
||||
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
|
||||
init_args.mem_alloc_type = Alloc_With_Pool;
|
||||
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
|
||||
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
|
||||
|
||||
ASSERT_EQ(wasm_runtime_full_init(&init_args), true);
|
||||
|
||||
cleanup = true;
|
||||
}
|
||||
|
||||
void TearDown()
|
||||
{
|
||||
if (cleanup) {
|
||||
wasm_runtime_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
bool load_wasm_file(const char *wasm_file)
|
||||
{
|
||||
const char *file;
|
||||
unsigned char *wasm_file_buf;
|
||||
uint32 wasm_file_size;
|
||||
|
||||
file = strdup((CWD + "/" + wasm_file).c_str());
|
||||
|
||||
wasm_file_buf =
|
||||
(unsigned char *)bh_read_file_to_buffer(file, &wasm_file_size);
|
||||
if (!wasm_file_buf)
|
||||
return false;
|
||||
|
||||
module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
if (!module)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
std::string CWD;
|
||||
RuntimeInitArgs init_args;
|
||||
wasm_module_t module = NULL;
|
||||
wasm_module_inst_t module_inst = NULL;
|
||||
wasm_function_inst_t func_inst = NULL;
|
||||
wasm_exec_env_t exec_env = NULL;
|
||||
char error_buf[128];
|
||||
char global_heap_buf[512 * 1024];
|
||||
bool cleanup = true;
|
||||
};
|
||||
|
||||
TEST_F(WasmGCTest, Test_app1)
|
||||
{
|
||||
ASSERT_TRUE(load_wasm_file("test1.wasm"));
|
||||
ASSERT_TRUE(load_wasm_file("test2.wasm"));
|
||||
ASSERT_TRUE(load_wasm_file("test3.wasm"));
|
||||
ASSERT_TRUE(load_wasm_file("test4.wasm"));
|
||||
ASSERT_TRUE(load_wasm_file("test5.wasm"));
|
||||
ASSERT_TRUE(load_wasm_file("test6.wasm"));
|
||||
|
||||
ASSERT_TRUE(load_wasm_file("struct1.wasm"));
|
||||
ASSERT_TRUE(load_wasm_file("struct2.wasm"));
|
||||
ASSERT_TRUE(load_wasm_file("struct3.wasm"));
|
||||
|
||||
ASSERT_TRUE(load_wasm_file("func1.wasm"));
|
||||
ASSERT_TRUE(load_wasm_file("func2.wasm"));
|
||||
}
|
BIN
tests/unit/gc/wasm-apps/func1.wasm
Normal file
BIN
tests/unit/gc/wasm-apps/func1.wasm
Normal file
Binary file not shown.
35
tests/unit/gc/wasm-apps/func1.wast
Normal file
35
tests/unit/gc/wasm-apps/func1.wast
Normal file
|
@ -0,0 +1,35 @@
|
|||
(module
|
||||
(type $t (func))
|
||||
|
||||
(func (export "test") (param structref i31ref)
|
||||
(local funcref)
|
||||
(local funcref)
|
||||
(local funcref)
|
||||
(local externref)
|
||||
(local externref)
|
||||
(local externref)
|
||||
(local anyref)
|
||||
(local eqref)
|
||||
(local structref)
|
||||
(local arrayref)
|
||||
(local i31ref)
|
||||
(local (ref null 0))
|
||||
(local (ref null 0))
|
||||
(local (ref null 0))
|
||||
(local (ref null 1))
|
||||
(local (ref null func))
|
||||
(local (ref null 0))
|
||||
(local (ref null extern))
|
||||
(local (ref null any))
|
||||
(local (ref null eq))
|
||||
(local (ref null i31))
|
||||
(local (ref null struct))
|
||||
|
||||
local.get 0
|
||||
ref.test null array
|
||||
drop
|
||||
local.get 1
|
||||
ref.cast i31
|
||||
drop
|
||||
)
|
||||
)
|
BIN
tests/unit/gc/wasm-apps/func2.wasm
Normal file
BIN
tests/unit/gc/wasm-apps/func2.wasm
Normal file
Binary file not shown.
78
tests/unit/gc/wasm-apps/func2.wast
Normal file
78
tests/unit/gc/wasm-apps/func2.wast
Normal file
|
@ -0,0 +1,78 @@
|
|||
(module
|
||||
(type $t0 (func))
|
||||
(type $t1 (func (param (ref null 1))))
|
||||
(type $t2 (func (param funcref externref (ref func)(ref extern)
|
||||
anyref eqref structref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 1) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 2) (ref null $t0))
|
||||
(result (ref null func))))
|
||||
(type $t3 (func (param i32 i32) (result (ref null 3))))
|
||||
|
||||
(type $t4 (func))
|
||||
(type $t5 (func (param (ref null 3))))
|
||||
(type $t6 (func (param funcref externref (ref func)(ref extern)
|
||||
anyref eqref structref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 5) (ref null $t0))
|
||||
(result (ref null func))))
|
||||
(type $t7 (func (param i32 i32) (result (ref null 4))))
|
||||
|
||||
(type $t11 (struct (field i8 (mut i16) (mut i32) i64 f32 f64
|
||||
funcref externref (ref func)(ref extern)
|
||||
anyref eqref arrayref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null struct)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 5) (ref null $t0))))
|
||||
|
||||
(type $t12 (struct))
|
||||
(type $t13 (struct (field)))
|
||||
(type $t14 (struct (field i8)))
|
||||
(type $t15 (struct (field i8 i8 i8 i8)))
|
||||
(type $t16 (struct (field $x1 i32) (field $y1 i32)))
|
||||
(type $t17 (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
|
||||
(type $t18 (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
|
||||
(type $t19 (struct (field $x2 i32) (field f32 f64) (field $y2 i32)))
|
||||
|
||||
(type $t20 (struct (field i8 (mut i16) (mut i32) i64 f32 f64
|
||||
funcref externref (ref func)(ref extern)
|
||||
anyref eqref structref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 5) (ref null $t0))))
|
||||
|
||||
(type $t21 (struct))
|
||||
(type $t22 (struct (field)))
|
||||
(type $t23 (struct (field i8)))
|
||||
(type $t24 (struct (field i8 i8 i8 i8)))
|
||||
(type $t25 (struct (field $x3 i32) (field $y3 i32)))
|
||||
(type $t26 (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
|
||||
(type $t27 (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
|
||||
(type $t28 (struct (field $x4 i32) (field f32 f64) (field $y4 i32)))
|
||||
|
||||
(type $t31 (array i8))
|
||||
(type $t32 (array i16))
|
||||
(type $t33 (array i32))
|
||||
(type $t34 (array i64))
|
||||
(type $t35 (array f32))
|
||||
(type $t36 (array f64))
|
||||
(type $t37 (array anyref))
|
||||
(type $t38 (array (ref i31)))
|
||||
(type $t39 (array (ref 0)))
|
||||
(type $t40 (array (ref null 1)))
|
||||
(type $t43 (array (mut i8)))
|
||||
(type $t44 (array (mut i16)))
|
||||
(type $t45 (array (mut i32)))
|
||||
(type $t46 (array (mut i64)))
|
||||
(type $t47 (array (mut i32)))
|
||||
(type $t48 (array (mut i64)))
|
||||
(type $t49 (array (mut anyref)))
|
||||
(type $t50 (array (mut (ref struct))))
|
||||
(type $t51 (array (mut (ref 0))))
|
||||
(type $t52 (array (mut (ref null i31))))
|
||||
)
|
BIN
tests/unit/gc/wasm-apps/global1.wasm
Normal file
BIN
tests/unit/gc/wasm-apps/global1.wasm
Normal file
Binary file not shown.
91
tests/unit/gc/wasm-apps/global1.wast
Normal file
91
tests/unit/gc/wasm-apps/global1.wast
Normal file
|
@ -0,0 +1,91 @@
|
|||
(module
|
||||
(type $ftype0 (func (param i32)))
|
||||
(type $ftype1 (func (param i32 i64) (result i32)))
|
||||
(type $ftype2 (func (param f32 f64) (result f64)))
|
||||
(type $t0 (func (param (ref 1) (ref 2) (ref null 1) (ref null 2))))
|
||||
(type $t1 (func (param funcref externref (ref func)(ref extern)
|
||||
anyref eqref arrayref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 3) (ref null $t0))
|
||||
(result (ref null func))))
|
||||
(type $t2 (func (param i32 i32) (result (ref null 4))))
|
||||
|
||||
;; Duplicated types
|
||||
(type $t3 (func))
|
||||
(type $t4 (func (param (ref 1) (ref 2) (ref null 1) (ref null 2))))
|
||||
(type $t5 (func (param funcref externref (ref func)(ref extern)
|
||||
anyref eqref arrayref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 3) (ref null $t0))
|
||||
(result (ref null func))))
|
||||
(type $t6 (func (param i32 i32) (result (ref null 4))))
|
||||
|
||||
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
|
||||
funcref externref (ref func)(ref extern)
|
||||
anyref eqref arrayref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 5) (ref null $t0))))
|
||||
|
||||
(type (struct))
|
||||
(type (struct (field)))
|
||||
(type (struct (field i8)))
|
||||
(type (struct (field i8 i8 i8 i8)))
|
||||
(type (struct (field $x1 i32) (field $y1 i32)))
|
||||
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
|
||||
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
|
||||
(type (struct (field $x2 i32) (field f32 f64) (field $y2 i32)))
|
||||
|
||||
;; Duplicated types
|
||||
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
|
||||
funcref externref (ref func)(ref extern)
|
||||
anyref eqref arrayref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 5) (ref null $t0))))
|
||||
|
||||
(type (struct))
|
||||
(type (struct (field)))
|
||||
(type (struct (field i8)))
|
||||
(type (struct (field i8 i8 i8 i8)))
|
||||
(type (struct (field $x3 i32) (field $y3 i32)))
|
||||
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
|
||||
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
|
||||
(type (struct (field $x4 i32) (field f32 f64) (field $y4 i32)))
|
||||
|
||||
(type (array i8))
|
||||
(type (array i16))
|
||||
(type (array i32))
|
||||
(type (array i64))
|
||||
(type (array f32))
|
||||
(type (array f64))
|
||||
(type (array anyref))
|
||||
(type (array (ref array)))
|
||||
(type (array (ref 0)))
|
||||
(type (array (ref null 1)))
|
||||
(type (array (mut i8)))
|
||||
(type (array (mut i16)))
|
||||
(type (array (mut i32)))
|
||||
(type (array (mut i64)))
|
||||
(type (array (mut i32)))
|
||||
(type (array (mut i64)))
|
||||
(type (array (mut anyref)))
|
||||
(type (array (mut (ref array))))
|
||||
(type (array (mut (ref 0))))
|
||||
(type (array (mut (ref null i31))))
|
||||
|
||||
(global $g0 funcref (ref.func $f0))
|
||||
(global $g1 externref (ref.null extern))
|
||||
(global $g2 anyref (ref.null any))
|
||||
(global $g3 eqref (ref.null array))
|
||||
(global $g4 arrayref (ref.null array))
|
||||
(global $g5 i31ref (ref.null i31))
|
||||
|
||||
(func $f0)
|
||||
)
|
BIN
tests/unit/gc/wasm-apps/struct1.wasm
Normal file
BIN
tests/unit/gc/wasm-apps/struct1.wasm
Normal file
Binary file not shown.
10
tests/unit/gc/wasm-apps/struct1.wast
Normal file
10
tests/unit/gc/wasm-apps/struct1.wast
Normal file
|
@ -0,0 +1,10 @@
|
|||
(module
|
||||
(type (struct))
|
||||
(type (struct (field)))
|
||||
(type (struct (field i8)))
|
||||
(type (struct (field i8 i8 i8 i8)))
|
||||
(type (struct (field $x1 i32) (field $y1 i32)))
|
||||
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
|
||||
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
|
||||
(type (struct (field $x2 i32) (field f32 f64) (field $y2 i32)))
|
||||
)
|
BIN
tests/unit/gc/wasm-apps/struct2.wasm
Normal file
BIN
tests/unit/gc/wasm-apps/struct2.wasm
Normal file
Binary file not shown.
33
tests/unit/gc/wasm-apps/struct2.wast
Normal file
33
tests/unit/gc/wasm-apps/struct2.wast
Normal file
|
@ -0,0 +1,33 @@
|
|||
(module
|
||||
(type $vec (struct (field f32) (field $y (mut f32)) (field $z f32)))
|
||||
|
||||
;;(global (ref $vec) (struct.new_canon $vec (f32.const 1) (f32.const 2) (f32.const 3)))
|
||||
(global (ref $vec) (struct.new_canon_default $vec))
|
||||
|
||||
(func (export "new") (result anyref)
|
||||
(struct.new_canon_default $vec)
|
||||
)
|
||||
|
||||
(func $get_0 (param $v (ref $vec)) (result f32)
|
||||
(struct.get $vec 0 (local.get $v))
|
||||
)
|
||||
(func (export "get_0") (result f32)
|
||||
(call $get_0 (struct.new_canon_default $vec))
|
||||
)
|
||||
|
||||
(func $set_get_y (param $v (ref $vec)) (param $y f32) (result f32)
|
||||
(struct.set $vec $y (local.get $v) (local.get $y))
|
||||
(struct.get $vec $y (local.get $v))
|
||||
)
|
||||
(func (export "set_get_y") (param $y f32) (result f32)
|
||||
(call $set_get_y (struct.new_canon_default $vec) (local.get $y))
|
||||
)
|
||||
|
||||
(func $set_get_1 (param $v (ref $vec)) (param $y f32) (result f32)
|
||||
(struct.set $vec 1 (local.get $v) (local.get $y))
|
||||
(struct.get $vec $y (local.get $v))
|
||||
)
|
||||
(func (export "set_get_1") (param $y f32) (result f32)
|
||||
(call $set_get_1 (struct.new_canon_default $vec) (local.get $y))
|
||||
)
|
||||
)
|
BIN
tests/unit/gc/wasm-apps/struct3.wasm
Normal file
BIN
tests/unit/gc/wasm-apps/struct3.wasm
Normal file
Binary file not shown.
9
tests/unit/gc/wasm-apps/struct3.wast
Normal file
9
tests/unit/gc/wasm-apps/struct3.wast
Normal file
|
@ -0,0 +1,9 @@
|
|||
(module
|
||||
(type $t (struct (field i32 (mut i32))))
|
||||
(func (export "struct.get-null")
|
||||
(local (ref null $t)) (drop (struct.get $t 1 (local.get 0)))
|
||||
)
|
||||
(func (export "struct.set-null")
|
||||
(local (ref null $t)) (struct.set $t 1 (local.get 0) (i32.const 0))
|
||||
)
|
||||
)
|
BIN
tests/unit/gc/wasm-apps/table1.wasm
Normal file
BIN
tests/unit/gc/wasm-apps/table1.wasm
Normal file
Binary file not shown.
108
tests/unit/gc/wasm-apps/table1.wast
Normal file
108
tests/unit/gc/wasm-apps/table1.wast
Normal file
|
@ -0,0 +1,108 @@
|
|||
(module
|
||||
(type $ftype0 (func (param i32)))
|
||||
(type $ftype1 (func (param i32 i64) (result i32)))
|
||||
(type $ftype2 (func (param f32 f64) (result f64)))
|
||||
(type $t0 (func (param (ref 1) (ref 2) (ref null 1) (ref null 2))))
|
||||
(type $t1 (func (param funcref externref (ref func)(ref extern)
|
||||
anyref eqref arrayref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 3) (ref null $t0))
|
||||
(result (ref null func))))
|
||||
(type $t2 (func (param i32 i32) (result (ref null 4))))
|
||||
|
||||
;; Duplicated types
|
||||
(type $t3 (func))
|
||||
(type $t4 (func (param (ref 1) (ref 2) (ref null 1) (ref null 2))))
|
||||
(type $t5 (func (param funcref externref (ref func)(ref extern)
|
||||
anyref eqref arrayref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 3) (ref null $t0))
|
||||
(result (ref null func))))
|
||||
(type $t6 (func (param i32 i32) (result (ref null 4))))
|
||||
|
||||
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
|
||||
funcref externref (ref func)(ref extern)
|
||||
anyref eqref arrayref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 5) (ref null $t0))))
|
||||
(type (struct))
|
||||
(type (struct (field)))
|
||||
(type (struct (field i8)))
|
||||
(type (struct (field i8 i8 i8 i8)))
|
||||
(type (struct (field $x1 i32) (field $y1 i32)))
|
||||
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
|
||||
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
|
||||
(type (struct (field $x2 i32) (field f32 f64) (field $y2 i32)))
|
||||
|
||||
;; Duplicated types
|
||||
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
|
||||
funcref externref (ref func)(ref extern)
|
||||
anyref eqref arrayref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 5) (ref null $t0))))
|
||||
|
||||
(type (struct))
|
||||
(type (struct (field)))
|
||||
(type (struct (field i8)))
|
||||
(type (struct (field i8 i8 i8 i8)))
|
||||
(type (struct (field $x3 i32) (field $y3 i32)))
|
||||
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
|
||||
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
|
||||
(type (struct (field $x4 i32) (field f32 f64) (field $y4 i32)))
|
||||
|
||||
(type (array i8))
|
||||
(type (array i16))
|
||||
(type (array i32))
|
||||
(type (array i64))
|
||||
(type (array f32))
|
||||
(type (array f64))
|
||||
(type (array anyref))
|
||||
(type (array (ref array)))
|
||||
(type (array (ref 0)))
|
||||
(type (array (ref null 1)))
|
||||
(type (array (mut i8)))
|
||||
(type (array (mut i16)))
|
||||
(type (array (mut i32)))
|
||||
(type (array (mut i64)))
|
||||
(type (array (mut i32)))
|
||||
(type (array (mut i64)))
|
||||
(type (array (mut anyref)))
|
||||
(type (array (mut (ref array))))
|
||||
(type (array (mut (ref 0))))
|
||||
(type (array (mut (ref null i31))))
|
||||
|
||||
(table 10 funcref)
|
||||
(table 20 externref)
|
||||
;; non-defaultable element type
|
||||
;; (table 30 (ref func))
|
||||
;; (table 40 (ref extern))
|
||||
(table 50 anyref)
|
||||
(table 60 eqref)
|
||||
(table 100 arrayref)
|
||||
(table 100 i31ref)
|
||||
(table 100 (ref null 0))
|
||||
(table 100 (ref null 2))
|
||||
(table 100 (ref null func))
|
||||
(table 100 (ref null extern))
|
||||
(table 100 (ref null any))
|
||||
(table 100 (ref null eq))
|
||||
(table 100 (ref null i31))
|
||||
(table 100 (ref null array))
|
||||
;; non-defaultable element type
|
||||
;; (table 100 (ref 0))
|
||||
;; (table 100 (ref $t0))
|
||||
;; (table 100 (ref 3))
|
||||
;; (table 100 (ref $t0))
|
||||
(table 100 (ref null func))
|
||||
(table 100 (ref null extern))
|
||||
(table 100 (ref null 5))
|
||||
(table 100 (ref null $t0))
|
||||
)
|
BIN
tests/unit/gc/wasm-apps/test1.wasm
Normal file
BIN
tests/unit/gc/wasm-apps/test1.wasm
Normal file
Binary file not shown.
117
tests/unit/gc/wasm-apps/test1.wast
Normal file
117
tests/unit/gc/wasm-apps/test1.wast
Normal file
|
@ -0,0 +1,117 @@
|
|||
(module
|
||||
(type $t (func))
|
||||
(type $t0 (func (param (ref null $t) (ref $t) (ref null 0) (ref 0) (ref null 1) (ref 1))))
|
||||
(type $t1 (func (param funcref externref anyref eqref
|
||||
i31ref structref arrayref
|
||||
nullref nullfuncref nullexternref
|
||||
(ref null func) (ref null extern) (ref null any) (ref null eq)
|
||||
(ref null i31) (ref null struct) (ref null array)
|
||||
(ref null none) (ref null nofunc) (ref null noextern)
|
||||
(ref func) (ref extern) (ref any) (ref eq)
|
||||
(ref i31) (ref struct) (ref array)
|
||||
(ref none) (ref nofunc) (ref noextern)
|
||||
|
||||
(ref null 0) (ref null $t0) (ref null $t1)
|
||||
(ref null func) (ref null extern) (ref null any) (ref null eq)
|
||||
(ref null i31) (ref null struct) (ref null array)
|
||||
(ref $t) (ref $t0) (ref $t1)
|
||||
(ref func) (ref extern) (ref any) (ref eq)
|
||||
(ref i31) (ref struct) (ref array))
|
||||
(result (ref null func) (ref null extern) (ref $t0))))
|
||||
(type $t2 (func (param i32 i32) (result (ref null $t1))))
|
||||
|
||||
;; Duplicated types
|
||||
(type $t3 (func))
|
||||
(type $t4 (func (param (ref null $t) (ref $t) (ref null 0) (ref 0) (ref null 1) (ref 1))))
|
||||
(type $t5 (func (param funcref externref anyref eqref
|
||||
i31ref structref arrayref
|
||||
nullref nullfuncref nullexternref
|
||||
(ref null func) (ref null extern) (ref null any) (ref null eq)
|
||||
(ref null i31) (ref null struct) (ref null array)
|
||||
(ref null none) (ref null nofunc) (ref null noextern)
|
||||
(ref func) (ref extern) (ref any) (ref eq)
|
||||
(ref i31) (ref struct) (ref array)
|
||||
(ref none) (ref nofunc) (ref noextern)
|
||||
|
||||
(ref null 0) (ref null $t0) (ref null $t1)
|
||||
(ref null func) (ref null extern) (ref null any) (ref null eq)
|
||||
(ref null i31) (ref null struct) (ref null array)
|
||||
(ref $t) (ref $t0) (ref $t1)
|
||||
(ref func) (ref extern) (ref any) (ref eq)
|
||||
(ref i31) (ref struct) (ref array))
|
||||
(result (ref null func) (ref null extern) (ref $t0))))
|
||||
(type $t6 (func (param i32 i32) (result (ref null $t1))))
|
||||
|
||||
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
|
||||
funcref externref (ref func) (ref extern)
|
||||
anyref eqref structref arrayref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null struct) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 5) (ref null $t0))))
|
||||
|
||||
(type (struct))
|
||||
(type (struct (field)))
|
||||
(type (struct (field i8)))
|
||||
(type (struct (field i8 i8 i8 i8)))
|
||||
(type (struct (field $x1 i32) (field $y1 i32)))
|
||||
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
|
||||
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
|
||||
(type (struct (field $x2 i32) (field f32 f64) (field $y2 i32)))
|
||||
|
||||
;; Duplicated types
|
||||
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
|
||||
funcref externref (ref func) (ref extern)
|
||||
anyref eqref structref arrayref i31ref
|
||||
(ref null 0) (ref null 2) (ref null func) (ref null extern)
|
||||
(ref null any) (ref null eq) (ref null i31) (ref null struct) (ref null array)
|
||||
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
|
||||
(ref null extern) (ref null 5) (ref null $t0))))
|
||||
(type (struct))
|
||||
(type (struct (field)))
|
||||
(type (struct (field i8)))
|
||||
(type (struct (field i8 i8 i8 i8)))
|
||||
(type (struct (field $x3 i32) (field $y3 i32)))
|
||||
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
|
||||
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
|
||||
(type (struct (field $x4 i32) (field f32 f64) (field $y4 i32)))
|
||||
|
||||
(type (array i8))
|
||||
(type (array i16))
|
||||
(type (array i32))
|
||||
(type (array i64))
|
||||
(type (array f32))
|
||||
(type (array f64))
|
||||
(type (array anyref))
|
||||
(type (array (ref struct)))
|
||||
(type (array (ref array)))
|
||||
(type (array (ref null struct)))
|
||||
(type (array (ref null array)))
|
||||
(type (array (ref 0)))
|
||||
(type (array (ref null 1)))
|
||||
(type (array (mut i8)))
|
||||
(type (array (mut i16)))
|
||||
(type (array (mut i32)))
|
||||
(type (array (mut i64)))
|
||||
(type (array (mut i32)))
|
||||
(type (array (mut i64)))
|
||||
(type (array (mut anyref)))
|
||||
(type (array (mut (ref struct))))
|
||||
(type (array (mut (ref array))))
|
||||
(type (array (mut (ref null struct))))
|
||||
(type (array (mut (ref null array))))
|
||||
(type (array (mut (ref 0))))
|
||||
(type (array (mut (ref null i31))))
|
||||
|
||||
;; sub types
|
||||
(type $e0 (sub (array i32)))
|
||||
(type $e1 (sub $e0 (array i32)))
|
||||
|
||||
(type $e2 (sub (array anyref)))
|
||||
(type $e3 (sub (array (ref null $e0))))
|
||||
(type $e4 (sub (array (ref $e1))))
|
||||
(type $e5 (sub $e1 (array i32)))
|
||||
|
||||
(type $m1 (sub (array (mut i32))))
|
||||
(type $m2 (sub $m1 (array (mut i32))))
|
||||
)
|
BIN
tests/unit/gc/wasm-apps/test2.wasm
Normal file
BIN
tests/unit/gc/wasm-apps/test2.wasm
Normal file
Binary file not shown.
104
tests/unit/gc/wasm-apps/test2.wast
Normal file
104
tests/unit/gc/wasm-apps/test2.wast
Normal file
|
@ -0,0 +1,104 @@
|
|||
(module
|
||||
(type $ft (func))
|
||||
(type $st (struct))
|
||||
(type $at (array i8))
|
||||
|
||||
(table $ta 10 anyref)
|
||||
(table $tf 10 funcref)
|
||||
(table $te 10 externref)
|
||||
|
||||
(elem declare func $f)
|
||||
(func $f)
|
||||
|
||||
(func (export "init") (param $x externref)
|
||||
(table.set $ta (i32.const 0) (ref.null any))
|
||||
(table.set $ta (i32.const 1) (ref.null struct))
|
||||
(table.set $ta (i32.const 2) (ref.null none))
|
||||
(table.set $ta (i32.const 3) (i31.new (i32.const 7)))
|
||||
(table.set $ta (i32.const 4) (struct.new_canon_default $st))
|
||||
(table.set $ta (i32.const 5) (array.new_canon_default $at (i32.const 0)))
|
||||
(table.set $ta (i32.const 6) (extern.internalize (local.get $x)))
|
||||
(table.set $ta (i32.const 7) (extern.internalize (ref.null extern)))
|
||||
|
||||
(table.set $tf (i32.const 0) (ref.null nofunc))
|
||||
(table.set $tf (i32.const 1) (ref.null func))
|
||||
(table.set $tf (i32.const 2) (ref.func $f))
|
||||
|
||||
(table.set $te (i32.const 0) (ref.null noextern))
|
||||
(table.set $te (i32.const 1) (ref.null extern))
|
||||
(table.set $te (i32.const 2) (local.get $x))
|
||||
(table.set $te (i32.const 3) (extern.externalize (i31.new (i32.const 8))))
|
||||
(table.set $te (i32.const 4) (extern.externalize (struct.new_canon_default $st)))
|
||||
(table.set $te (i32.const 5) (extern.externalize (ref.null any)))
|
||||
)
|
||||
|
||||
(func (export "ref_test_null_data") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.is_null (table.get $ta (local.get $i)))
|
||||
(ref.test null none (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "ref_test_any") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test any (table.get $ta (local.get $i)))
|
||||
(ref.test null any (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "ref_test_eq") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test eq (table.get $ta (local.get $i)))
|
||||
(ref.test null eq (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "ref_test_i31") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test i31 (table.get $ta (local.get $i)))
|
||||
(ref.test null i31 (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "ref_test_struct") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test struct (table.get $ta (local.get $i)))
|
||||
(ref.test null struct (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "ref_test_array") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test array (table.get $ta (local.get $i)))
|
||||
(ref.test null array (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "ref_test_null_func") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.is_null (table.get $tf (local.get $i)))
|
||||
(ref.test null nofunc (table.get $tf (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "ref_test_func") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test func (table.get $tf (local.get $i)))
|
||||
(ref.test null func (table.get $tf (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "ref_test_null_extern") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.is_null (table.get $te (local.get $i)))
|
||||
(ref.test null noextern (table.get $te (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "ref_test_extern") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test extern (table.get $te (local.get $i)))
|
||||
(ref.test null extern (table.get $te (local.get $i)))
|
||||
)
|
||||
)
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user