Merge pull request #3511 from bytecodealliance/main

Merge branch main into dev/checkpoint_and_restore
This commit is contained in:
Wenyong Huang 2024-06-07 11:14:08 +08:00 committed by GitHub
commit ac308c4fa9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
248 changed files with 15020 additions and 415 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1 +1 @@
requests==2.31.0
requests==2.32.3

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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
*/

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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));

View File

@ -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;

View File

@ -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
*

View File

@ -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;

View File

@ -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),

View File

@ -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 */

View File

@ -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) {

View File

@ -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);
}

View File

@ -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
```

View File

@ -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")));

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View 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

View File

@ -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)
{

View File

@ -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);

View File

@ -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()

View File

@ -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 */

View File

@ -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)
{

View File

@ -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

View File

@ -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")

View File

@ -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;
}

View File

@ -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");

View File

@ -1,6 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node16",
"target": "es6",
"outDir": "out",
"lib": ["es6"],

View File

@ -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)

View File

@ -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"

View File

@ -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)

View File

@ -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"
}
}
]
}

View File

@ -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)

View 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)

View 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);
}

View 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
)

View 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
)
)

View 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

File diff suppressed because it is too large Load Diff

View 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();
}
}

View 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_; }
};

View 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)

View 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)));
}

View 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));
}

View 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));
}
}

View 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));
}

View 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));
}

View 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

View 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));
}

View 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));
}

View 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));
}

View 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);
// }
}

View 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);
}

Binary file not shown.

View 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)

View 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);
}
}

View 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
)

View 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;
}

View 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
View 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"));
}

Binary file not shown.

View 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
)
)

Binary file not shown.

View 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))))
)

Binary file not shown.

View 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)
)

Binary file not shown.

View 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)))
)

Binary file not shown.

View 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))
)
)

Binary file not shown.

View 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))
)
)

Binary file not shown.

View 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))
)

Binary file not shown.

View 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))))
)

Binary file not shown.

View 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