diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5a9c12d334..ad60706bcc 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -49,7 +49,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v3.26.11 with: languages: ${{ matrix.language }} @@ -66,7 +66,7 @@ jobs: - run: | ./.github/scripts/codeql_buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v3.26.11 with: category: "/language:${{matrix.language}}" upload: false @@ -95,14 +95,14 @@ jobs: output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif - name: Upload CodeQL results to code scanning - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@v3.26.11 with: sarif_file: ${{ steps.step1.outputs.sarif-output }} category: "/language:${{matrix.language}}" - name: Upload CodeQL results as an artifact if: success() || failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v4.4.0 with: name: codeql-results path: ${{ steps.step1.outputs.sarif-output }} diff --git a/.github/workflows/spec_test_on_nuttx.yml b/.github/workflows/spec_test_on_nuttx.yml index 712bd06bcb..dfabad103a 100644 --- a/.github/workflows/spec_test_on_nuttx.yml +++ b/.github/workflows/spec_test_on_nuttx.yml @@ -341,7 +341,7 @@ jobs: - name: upload the log if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v4.4.0 with: name: spec-test-log-${{ github.run_id }}-${{ strategy.job-index }}-${{ matrix.target_config.target }} path: log diff --git a/.github/workflows/supply_chain.yml b/.github/workflows/supply_chain.yml new file mode 100644 index 0000000000..28b464e48e --- /dev/null +++ b/.github/workflows/supply_chain.yml @@ -0,0 +1,65 @@ +# This workflow uses actions that are not certified by GitHub. They are provided +# by a third-party and are governed by separate terms of service, privacy +# policy, and support documentation. + +# Check current WASM Micro Runtime results here: https://securityscorecards.dev/viewer/?uri=github.com/bytecodealliance/wasm-micro-runtime + +name: Scorecard supply-chain security +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + # midnight UTC + schedule: + - cron: "0 0 * * *" + # allow to be triggered manually + workflow_dispatch: + +# Declare default permissions as read only. +permissions: + contents: read + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + if: github.repository == 'bytecodealliance/wasm-micro-runtime' + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + + steps: + - name: "Checkout code" + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + with: + results_file: results.sarif + results_format: sarif + + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@3eadd8b791cabf7cd572f194da82158c24125bd8 # v3.1.0 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@56d197570aa047eae7fe04401603196e2f68521d # v2.2.4 + with: + sarif_file: results.sarif diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000000..d8ec4c1b38 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,29 @@ +# In this project, we use CODEOWNERS to identify people who are likely to know +# who should review a pull request. +# +# People listed in this file are committing to respond in a timely fashion to +# PRs in the selected areas. However, that response doesn't have to be a full +# code review; it could also take any of these forms: +# +# - "I intend to review this but I can't yet. Please leave me a message if I +# haven't responded by (a specific date in the near future)." +# +# - "I think (a specific other contributor) should review this." (Note that the +# best reviewer for a PR may not necessarily be listed in this file.) +# +# People must only be added to this file if they've agreed to provide one of +# the above responses in a reasonable amount of time for every PR to which +# they're assigned. +# +# We only ask for this commitment from people who are employed full-time to +# work on this project. We gratefully welcome reviews from other contributors, +# but we don't believe it's fair to ask volunteers to respond quickly. + +# If none of the later patterns match, assign to anyone. This team is the +# parent of all the other teams and automatically includes everyone on those +# teams. +* @loganek @lum1n0us @no1wudi @wenyongh @xujuntwt95329 @yamt + +# Some parts of the project require more specialized knowledge. In those areas +# we designate smaller groups who are more likely to be aware of who's working +# in specific areas. diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 5c81318332..1a4a6d1e10 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -1382,6 +1382,12 @@ load_table_list(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module, for (i = 0; i < module->table_count; i++, table++) { read_uint8(buf, buf_end, table->table_type.elem_type); read_uint8(buf, buf_end, table->table_type.flags); + + if (!wasm_table_check_flags(table->table_type.flags, error_buf, + error_buf_size, true)) { + return false; + } + read_uint8(buf, buf_end, table->table_type.possible_grow); #if WASM_ENABLE_GC != 0 if (wasm_is_type_multi_byte_type(table->table_type.elem_type)) { @@ -2506,6 +2512,15 @@ try_merge_data_and_text(const uint8 **buf, const uint8 **buf_end, /* merge failed but may be not critical for some targets */ return false; } + +#ifdef BH_PLATFORM_WINDOWS + if (!os_mem_commit(sections, code_size, + MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC)) { + os_munmap(sections, (uint32)total_size); + return false; + } +#endif + /* change the code part to be executable */ if (os_mprotect(sections, code_size, MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC) @@ -2520,7 +2535,7 @@ try_merge_data_and_text(const uint8 **buf, const uint8 **buf_end, /* order not essential just as compiler does: .text section first */ *buf = sections; *buf_end = sections + code_size; - bh_memcpy_s(sections, code_size, old_buf, code_size); + bh_memcpy_s(sections, (uint32)code_size, old_buf, (uint32)code_size); os_munmap(old_buf, code_size); sections += align_uint((uint32)code_size, page_size); diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 63a3c83c90..ebef544106 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -737,18 +737,24 @@ tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module, #if WASM_ENABLE_REF_TYPES != 0 bh_assert( - table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST + table_seg->offset.init_expr_type + == (tbl_inst->is_table64 ? INIT_EXPR_TYPE_I64_CONST + : INIT_EXPR_TYPE_I32_CONST) || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_FUNCREF_CONST || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_REFNULL_CONST); #else - bh_assert(table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST + bh_assert(table_seg->offset.init_expr_type + == (tbl_inst->is_table64 ? INIT_EXPR_TYPE_I64_CONST + : INIT_EXPR_TYPE_I32_CONST) || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL); #endif /* Resolve table data base offset */ + /* TODO: The table64 current implementation assumes table max size + * UINT32_MAX, so the offset conversion here is safe */ if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) { global_index = table_seg->offset.u.global_index; @@ -1560,8 +1566,12 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, if (is_sub_inst) { bh_assert(exec_env_main); #ifdef OS_ENABLE_HW_BOUND_CHECK - bh_assert(exec_env_tls == exec_env_main); - (void)exec_env_tls; + /* May come from pthread_create_wrapper, thread_spawn_wrapper and + wasm_cluster_spawn_exec_env. If it comes from the former two, + the exec_env_tls must be not NULL and equal to exec_env_main, + else if it comes from the last one, it may be NULL. */ + if (exec_env_tls) + bh_assert(exec_env_tls == exec_env_main); #endif exec_env = exec_env_main; diff --git a/core/iwasm/aot/arch/aot_reloc_riscv.c b/core/iwasm/aot/arch/aot_reloc_riscv.c index 058ad0e10a..8df9f9f8ed 100644 --- a/core/iwasm/aot/arch/aot_reloc_riscv.c +++ b/core/iwasm/aot/arch/aot_reloc_riscv.c @@ -24,6 +24,7 @@ #undef NEED_SOFT_I32_DIV #undef NEED_SOFT_I64_MUL #undef NEED_SOFT_I64_DIV +#undef NEED_SOFT_ATOMIC #ifdef __riscv_flen #if __riscv_flen == 32 @@ -48,6 +49,10 @@ #define NEED_SOFT_I64_DIV #endif +#ifndef __riscv_atomic +#define NEED_SOFT_ATOMIC +#endif + /* clang-format off */ void __adddf3(void); void __addsf3(void); @@ -101,6 +106,9 @@ void __umoddi3(void); void __umodsi3(void); void __unorddf2(void); void __unordsf2(void); +bool __atomic_compare_exchange_4(volatile void *, void *, unsigned int, + bool, int, int); +void __atomic_store_4(volatile void *, unsigned int, int); /* clang-format on */ static SymbolMap target_sym_map[] = { @@ -127,6 +135,7 @@ static SymbolMap target_sym_map[] = { * to convert float and long long */ REG_SYM(__floatundisf), + REG_SYM(__floatdisf), #endif #ifdef NEED_SOFT_DP REG_SYM(__adddf3), @@ -175,6 +184,10 @@ static SymbolMap target_sym_map[] = { REG_SYM(__moddi3), REG_SYM(__udivdi3), REG_SYM(__umoddi3), +#endif +#ifdef NEED_SOFT_ATOMIC + REG_SYM(__atomic_compare_exchange_4), + REG_SYM(__atomic_store_4), #endif /* clang-format on */ }; diff --git a/core/iwasm/common/wasm_loader_common.c b/core/iwasm/common/wasm_loader_common.c index 6dd31be2c3..97ea5efd19 100644 --- a/core/iwasm/common/wasm_loader_common.c +++ b/core/iwasm/common/wasm_loader_common.c @@ -19,6 +19,37 @@ wasm_loader_set_error_buf(char *error_buf, uint32 error_buf_size, } } +#if WASM_ENABLE_MEMORY64 != 0 +bool +check_memory64_flags_consistency(WASMModule *module, char *error_buf, + uint32 error_buf_size, bool is_aot) +{ + uint32 i; + bool wasm64_flag, all_wasm64 = true, none_wasm64 = true; + + for (i = 0; i < module->import_memory_count; ++i) { + wasm64_flag = + module->import_memories[i].u.memory.mem_type.flags & MEMORY64_FLAG; + all_wasm64 &= wasm64_flag; + none_wasm64 &= !wasm64_flag; + } + + for (i = 0; i < module->memory_count; ++i) { + wasm64_flag = module->memories[i].flags & MEMORY64_FLAG; + all_wasm64 &= wasm64_flag; + none_wasm64 &= !wasm64_flag; + } + + if (!(all_wasm64 || none_wasm64)) { + wasm_loader_set_error_buf( + error_buf, error_buf_size, + "inconsistent limits wasm64 flags for memory sections", is_aot); + return false; + } + return true; +} +#endif + bool wasm_memory_check_flags(const uint8 mem_flag, char *error_buf, uint32 error_buf_size, bool is_aot) @@ -60,6 +91,37 @@ wasm_memory_check_flags(const uint8 mem_flag, char *error_buf, return true; } +bool +wasm_table_check_flags(const uint8 table_flag, char *error_buf, + uint32 error_buf_size, bool is_aot) +{ + /* Check whether certain features indicated by mem_flag are enabled in + * runtime */ + if (table_flag > MAX_TABLE_SIZE_FLAG) { + if (table_flag & SHARED_TABLE_FLAG) { + wasm_loader_set_error_buf(error_buf, error_buf_size, + "tables cannot be shared", is_aot); + } +#if WASM_ENABLE_MEMORY64 == 0 + if (table_flag & TABLE64_FLAG) { + wasm_loader_set_error_buf(error_buf, error_buf_size, + "invalid limits flags(table64 flag was " + "found, please enable memory64)", + is_aot); + return false; + } +#endif + } + + if (table_flag > MAX_TABLE_SIZE_FLAG + TABLE64_FLAG) { + wasm_loader_set_error_buf(error_buf, error_buf_size, + "invalid limits flags", is_aot); + return false; + } + + return true; +} + /* * compare with a bigger type set in `wasm_value_type_size_internal()`, * this function will only cover global value type, function's param diff --git a/core/iwasm/common/wasm_loader_common.h b/core/iwasm/common/wasm_loader_common.h index d574110ba0..81174fb264 100644 --- a/core/iwasm/common/wasm_loader_common.h +++ b/core/iwasm/common/wasm_loader_common.h @@ -13,10 +13,22 @@ extern "C" { #endif +#if WASM_ENABLE_MEMORY64 != 0 +/* check consistency of memory64 flags across all memories, + * they must be either all wasm64 or all wasm32 */ +bool +check_memory64_flags_consistency(WASMModule *module, char *error_buf, + uint32 error_buf_size, bool is_aot); +#endif + bool wasm_memory_check_flags(const uint8 mem_flag, char *error_buf, uint32 error_buf_size, bool is_aot); +bool +wasm_table_check_flags(const uint8 table_flag, char *error_buf, + uint32 error_buf_size, bool is_aot); + bool is_valid_value_type(uint8 value_tpye); diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 667cbba03f..453cf9e3c8 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -340,7 +340,6 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info) PEXCEPTION_RECORD ExceptionRecord = exce_info->ExceptionRecord; uint8 *sig_addr = (uint8 *)ExceptionRecord->ExceptionInformation[1]; WASMModuleInstance *module_inst; - WASMMemoryInstance *memory_inst; WASMJmpBuf *jmpbuf_node; uint8 *mapped_mem_start_addr = NULL; uint8 *mapped_mem_end_addr = NULL; diff --git a/core/iwasm/compilation/aot_compiler.c b/core/iwasm/compilation/aot_compiler.c index e560049725..07734b3b41 100644 --- a/core/iwasm/compilation/aot_compiler.c +++ b/core/iwasm/compilation/aot_compiler.c @@ -146,9 +146,20 @@ aot_validate_wasm(AOTCompContext *comp_ctx) } #if WASM_ENABLE_MEMORY64 != 0 - if (comp_ctx->pointer_size < sizeof(uint64) && IS_MEMORY64) { - aot_set_last_error("Compiling wasm64 to 32bit platform is not allowed"); - return false; + if (comp_ctx->pointer_size < sizeof(uint64)) { + if (IS_MEMORY64) { + aot_set_last_error("Compiling wasm64(contains i64 memory section) " + "to 32bit platform is not allowed"); + return false; + } + + for (uint32 i = 0; i < comp_ctx->comp_data->table_count; ++i) { + if (IS_TABLE64(i)) { + aot_set_last_error("Compiling wasm64(contains i64 table " + "section) to 32bit platform is not allowed"); + return false; + } + } } #endif diff --git a/core/iwasm/compilation/aot_compiler.h b/core/iwasm/compilation/aot_compiler.h index 895d2416b4..06d8e42bdb 100644 --- a/core/iwasm/compilation/aot_compiler.h +++ b/core/iwasm/compilation/aot_compiler.h @@ -532,8 +532,13 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type) #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) +#define IS_TABLE64(i) \ + (comp_ctx->comp_data->tables[i].table_type.flags & TABLE64_FLAG) +#define TABLE64_COND_VALUE(i, VAL_IF_ENABLED, VAL_IF_DISABLED) \ + (IS_TABLE64(i) ? VAL_IF_ENABLED : VAL_IF_DISABLED) #else #define MEMORY64_COND_VALUE(VAL_IF_ENABLED, VAL_IF_DISABLED) (VAL_IF_DISABLED) +#define TABLE64_COND_VALUE(i, VAL_IF_ENABLED, VAL_IF_DISABLED) (VAL_IF_DISABLED) #endif #define POP_I32(v) POP(v, VALUE_TYPE_I32) @@ -548,6 +553,9 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type) POP(v, MEMORY64_COND_VALUE(VALUE_TYPE_I64, VALUE_TYPE_I32)) #define POP_PAGE_COUNT(v) \ POP(v, MEMORY64_COND_VALUE(VALUE_TYPE_I64, VALUE_TYPE_I32)) +#define POP_TBL_ELEM_IDX(v) \ + POP(v, TABLE64_COND_VALUE(tbl_idx, VALUE_TYPE_I64, VALUE_TYPE_I32)) +#define POP_TBL_ELEM_LEN(v) POP_TBL_ELEM_IDX(v) #define POP_COND(llvm_value) \ do { \ @@ -613,6 +621,9 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type) #define PUSH_GC_REF(v) PUSH(v, VALUE_TYPE_GC_REF) #define PUSH_PAGE_COUNT(v) \ PUSH(v, MEMORY64_COND_VALUE(VALUE_TYPE_I64, VALUE_TYPE_I32)) +#define PUSH_TBL_ELEM_IDX(v) \ + PUSH(v, TABLE64_COND_VALUE(tbl_idx, VALUE_TYPE_I64, VALUE_TYPE_I32)) +#define PUSH_TBL_ELEM_LEN(v) PUSH_TBL_ELEM_IDX(v) #define SET_CONST(v) \ do { \ diff --git a/core/iwasm/compilation/aot_emit_function.c b/core/iwasm/compilation/aot_emit_function.c index 85a9239aa5..167acc62f2 100644 --- a/core/iwasm/compilation/aot_emit_function.c +++ b/core/iwasm/compilation/aot_emit_function.c @@ -2089,6 +2089,9 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMValueRef ext_ret_offset, ext_ret_ptr, ext_ret, res; LLVMValueRef *param_values = NULL, *value_rets = NULL; LLVMValueRef *result_phis = NULL, value_ret, import_func_count; +#if WASM_ENABLE_MEMORY64 != 0 + LLVMValueRef u32_max, u32_cmp_result; +#endif LLVMTypeRef *param_types = NULL, ret_type; LLVMTypeRef llvm_func_type, llvm_func_ptr_type; LLVMTypeRef ext_ret_ptr_type; @@ -2153,7 +2156,7 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, func_param_count = func_type->param_count; func_result_count = func_type->result_count; - POP_I32(elem_idx); + POP_TBL_ELEM_IDX(elem_idx); /* get the cur size of the table instance */ if (!(offset = I32_CONST(get_tbl_inst_offset(comp_ctx, func_ctx, tbl_idx) @@ -2182,6 +2185,27 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } +#if WASM_ENABLE_MEMORY64 != 0 + /* Check if elem index >= UINT32_MAX */ + if (IS_TABLE64(tbl_idx)) { + if (!(u32_max = I64_CONST(UINT32_MAX))) { + aot_set_last_error("llvm build const failed"); + goto fail; + } + if (!(u32_cmp_result = + LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, elem_idx, + u32_max, "cmp_elem_idx_u32_max"))) { + aot_set_last_error("llvm build icmp failed."); + goto fail; + } + if (!(elem_idx = LLVMBuildTrunc(comp_ctx->builder, elem_idx, I32_TYPE, + "elem_idx_i32"))) { + aot_set_last_error("llvm build trunc failed."); + goto fail; + } + } +#endif + /* Check if (uint32)elem index >= table size */ if (!(cmp_elem_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, elem_idx, table_size_const, "cmp_elem_idx"))) { @@ -2189,7 +2213,19 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - /* Throw exception if elem index >= table size */ +#if WASM_ENABLE_MEMORY64 != 0 + if (IS_TABLE64(tbl_idx)) { + if (!(cmp_elem_idx = + LLVMBuildOr(comp_ctx->builder, cmp_elem_idx, u32_cmp_result, + "larger_than_u32_max_or_cur_size"))) { + aot_set_last_error("llvm build or failed."); + goto fail; + } + } +#endif + + /* Throw exception if elem index >= table size or elem index >= UINT32_MAX + */ if (!(check_elem_idx_succ = LLVMAppendBasicBlockInContext( comp_ctx->context, func_ctx->func, "check_elem_idx_succ"))) { aot_set_last_error("llvm add basic block failed."); diff --git a/core/iwasm/compilation/aot_emit_table.c b/core/iwasm/compilation/aot_emit_table.c index f968bacddf..d65d2f4132 100644 --- a/core/iwasm/compilation/aot_emit_table.c +++ b/core/iwasm/compilation/aot_emit_table.c @@ -10,6 +10,72 @@ #include "aot_emit_gc.h" #endif +static bool +zero_extend_u64(AOTCompContext *comp_ctx, LLVMValueRef *value, const char *name) +{ + if (comp_ctx->pointer_size == sizeof(uint64)) { + /* zero extend to uint64 if the target is 64-bit */ + *value = LLVMBuildZExt(comp_ctx->builder, *value, I64_TYPE, name); + if (!*value) { + aot_set_last_error("llvm build zero extend failed."); + return false; + } + } + return true; +} + +/* check whether a table64 elem idx is greater than UINT32_MAX, if so, throw + * exception, otherwise trunc it to uint32 */ +static bool +check_tbl_elem_idx_and_trunc(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, + LLVMValueRef *elem_idx, uint32 tbl_idx) +{ + LLVMValueRef u32_max, u32_cmp_result; + LLVMBasicBlockRef check_elem_idx_succ; + +#if WASM_ENABLE_MEMORY64 != 0 + if (!IS_TABLE64(tbl_idx)) { + return true; + } + + /* Check if elem index >= UINT32_MAX */ + if (!(u32_max = I64_CONST(UINT32_MAX))) { + aot_set_last_error("llvm build const failed"); + goto fail; + } + if (!(u32_cmp_result = + LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, *elem_idx, u32_max, + "cmp_elem_idx_u32_max"))) { + aot_set_last_error("llvm build icmp failed."); + goto fail; + } + if (!(*elem_idx = LLVMBuildTrunc(comp_ctx->builder, *elem_idx, I32_TYPE, + "elem_idx_i32"))) { + aot_set_last_error("llvm build trunc failed."); + goto fail; + } + + /* Throw exception if elem index >= UINT32_MAX*/ + if (!(check_elem_idx_succ = LLVMAppendBasicBlockInContext( + comp_ctx->context, func_ctx->func, "check_elem_idx_succ"))) { + aot_set_last_error("llvm add basic block failed."); + goto fail; + } + + LLVMMoveBasicBlockAfter(check_elem_idx_succ, + LLVMGetInsertBlock(comp_ctx->builder)); + + if (!(aot_emit_exception(comp_ctx, func_ctx, + EXCE_OUT_OF_BOUNDS_TABLE_ACCESS, true, + u32_cmp_result, check_elem_idx_succ))) + goto fail; +#endif + + return true; +fail: + return false; +} + uint64 get_tbl_inst_offset(const AOTCompContext *comp_ctx, const AOTFuncContext *func_ctx, uint32 tbl_idx) @@ -158,6 +224,10 @@ aot_check_table_access(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, &elem_idx, tbl_idx)) { + goto fail; + } + /* Check if (uint32)elem index >= table size */ if (!(cmp_elem_idx = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, elem_idx, tbl_sz, "cmp_elem_idx"))) { @@ -192,7 +262,7 @@ aot_compile_op_table_get(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMValueRef elem_idx, offset, func_idx; LLVMValueRef table_elem_base, table_elem_addr, table_elem; - POP_I32(elem_idx); + POP_TBL_ELEM_IDX(elem_idx); if (!aot_check_table_access(comp_ctx, func_ctx, tbl_idx, elem_idx)) { goto fail; @@ -289,7 +359,7 @@ aot_compile_op_table_set(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } } - POP_I32(elem_idx); + POP_TBL_ELEM_IDX(elem_idx); if (!aot_check_table_access(comp_ctx, func_ctx, tbl_idx, elem_idx)) { goto fail; @@ -388,7 +458,11 @@ aot_compile_op_table_init(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, /* s */ POP_I32(param_values[4]); /* d */ - POP_I32(param_values[5]); + POP_TBL_ELEM_IDX(param_values[5]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[5], + tbl_idx)) { + goto fail; + } /* "" means return void */ if (!(LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, 6, @@ -408,6 +482,7 @@ aot_compile_op_table_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, { LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type; LLVMValueRef func, param_values[6], value; + uint32 tbl_idx; param_types[0] = INT8_PTR_TYPE; param_types[1] = I32_TYPE; @@ -434,12 +509,34 @@ aot_compile_op_table_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } + /* In table64, the length should be i32 type if any one of src/dst table + * is i32 type, set the table index to the lesser-or-equal table when + * popping length n */ + if (!(comp_ctx->comp_data->tables[src_tbl_idx].table_type.flags + & TABLE64_FLAG)) + tbl_idx = src_tbl_idx; + else + tbl_idx = dst_tbl_idx; /* n */ - POP_I32(param_values[3]); + POP_TBL_ELEM_LEN(param_values[3]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[3], + tbl_idx)) { + goto fail; + } /* s */ - POP_I32(param_values[4]); + tbl_idx = src_tbl_idx; + POP_TBL_ELEM_IDX(param_values[4]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[4], + tbl_idx)) { + goto fail; + } /* d */ - POP_I32(param_values[5]); + tbl_idx = dst_tbl_idx; + POP_TBL_ELEM_IDX(param_values[5]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[5], + tbl_idx)) { + goto fail; + } /* "" means return void */ if (!(LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, 6, @@ -484,7 +581,14 @@ aot_compile_op_table_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - PUSH_I32(tbl_sz); +#if WASM_ENABLE_MEMORY64 != 0 + if (IS_TABLE64(tbl_idx)) { + if (!zero_extend_u64(comp_ctx, &tbl_sz, "length64")) { + goto fail; + } + } +#endif + PUSH_TBL_ELEM_IDX(tbl_sz); return true; fail: @@ -517,7 +621,11 @@ aot_compile_op_table_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* n */ - POP_I32(param_values[2]); + POP_TBL_ELEM_LEN(param_values[2]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[2], + tbl_idx)) { + goto fail; + } /* v */ if (comp_ctx->enable_gc) { @@ -545,7 +653,14 @@ aot_compile_op_table_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, goto fail; } - PUSH_I32(ret); +#if WASM_ENABLE_MEMORY64 != 0 + if (IS_TABLE64(tbl_idx)) { + if (!zero_extend_u64(comp_ctx, &ret, "table_size64")) { + goto fail; + } + } +#endif + PUSH_TBL_ELEM_LEN(ret); return true; fail: @@ -579,7 +694,11 @@ aot_compile_op_table_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } /* n */ - POP_I32(param_values[2]); + POP_TBL_ELEM_LEN(param_values[2]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[2], + tbl_idx)) { + goto fail; + } /* v */ if (comp_ctx->enable_gc) { @@ -601,7 +720,11 @@ aot_compile_op_table_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } } /* i */ - POP_I32(param_values[4]); + POP_TBL_ELEM_IDX(param_values[4]); + if (!check_tbl_elem_idx_and_trunc(comp_ctx, func_ctx, ¶m_values[4], + tbl_idx)) { + goto fail; + } /* "" means return void */ if (!(LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values, 5, diff --git a/core/iwasm/include/aot_comp_option.h b/core/iwasm/include/aot_comp_option.h index 98f33a1608..bb612515ae 100644 --- a/core/iwasm/include/aot_comp_option.h +++ b/core/iwasm/include/aot_comp_option.h @@ -6,6 +6,8 @@ #ifndef __AOT_COMP_OPTION_H__ #define __AOT_COMP_OPTION_H__ +#include + typedef struct { /* Enables or disables bounds checks for stack frames. When enabled, the AOT * compiler generates code to check if the stack pointer is within the diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index e043465d44..6023b07020 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -93,6 +93,10 @@ extern "C" { #define MAX_PAGE_COUNT_FLAG 0x01 #define SHARED_MEMORY_FLAG 0x02 #define MEMORY64_FLAG 0x04 +#define MAX_TABLE_SIZE_FLAG 0x01 +/* the shared flag for table is not actual used now */ +#define SHARED_TABLE_FLAG 0x02 +#define TABLE64_FLAG 0x04 /** * In the multi-memory proposal, the memarg in loads and stores are @@ -494,6 +498,7 @@ typedef struct WASMTableType { * 0: no max size and not shared * 1: has max size * 2: shared + * 4: table64 */ uint8 flags; bool possible_grow; @@ -520,6 +525,7 @@ typedef uint64 mem_offset_t; typedef uint32 mem_offset_t; #define PR_MEM_OFFSET PRIu32 #endif +typedef mem_offset_t tbl_elem_idx_t; typedef struct WASMMemory { uint32 flags; @@ -976,8 +982,9 @@ struct WASMModule { uint64 buf_code_size; #endif -#if WASM_ENABLE_DEBUG_INTERP != 0 || WASM_ENABLE_FAST_JIT != 0 \ - || WASM_ENABLE_DUMP_CALL_STACK != 0 || WASM_ENABLE_JIT != 0 +#if WASM_ENABLE_DEBUG_INTERP != 0 || WASM_ENABLE_FAST_JIT != 0 \ + || WASM_ENABLE_DUMP_CALL_STACK != 0 || WASM_ENABLE_JIT != 0 \ + || WASM_ENABLE_WAMR_COMPILER != 0 uint8 *load_addr; uint64 load_size; #endif @@ -1238,6 +1245,9 @@ wasm_value_type_size_internal(uint8 value_type, uint8 pointer_size) else { bh_assert(0); } +#if WASM_ENABLE_GC == 0 + (void)pointer_size; +#endif return 0; } diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 67f8c2d455..faa97f35ce 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -511,9 +511,9 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) #endif #if WASM_ENABLE_MEMORY64 != 0 -#define PUSH_MEM_OFFSET(value) \ +#define COND_PUSH_TEMPLATE(cond, value) \ do { \ - if (is_memory64) { \ + if (cond) { \ PUT_I64_TO_ADDR(frame_sp, value); \ frame_sp += 2; \ } \ @@ -521,8 +521,11 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) *(int32 *)frame_sp++ = (int32)(value); \ } \ } while (0) +#define PUSH_MEM_OFFSET(value) COND_PUSH_TEMPLATE(is_memory64, value) +#define PUSH_TBL_ELEM_IDX(value) COND_PUSH_TEMPLATE(is_table64, value) #else #define PUSH_MEM_OFFSET(value) PUSH_I32(value) +#define PUSH_TBL_ELEM_IDX(value) PUSH_I32(value) #endif #define PUSH_PAGE_COUNT(value) PUSH_MEM_OFFSET(value) @@ -558,8 +561,10 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) #if WASM_ENABLE_MEMORY64 != 0 #define POP_MEM_OFFSET() (is_memory64 ? POP_I64() : POP_I32()) +#define POP_TBL_ELEM_IDX() (is_table64 ? POP_I64() : POP_I32()) #else #define POP_MEM_OFFSET() POP_I32() +#define POP_TBL_ELEM_IDX() POP_I32() #endif #define POP_PAGE_COUNT() POP_MEM_OFFSET() @@ -1562,7 +1567,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, uint8 opcode; uint32 i, depth, cond, count, fidx, tidx, lidx, frame_size = 0; uint32 all_cell_num = 0; - int32 val; + tbl_elem_idx_t val; uint8 *else_addr, *end_addr, *maddr = NULL; uint32 local_idx, local_offset, global_idx; uint8 local_type, *global_addr; @@ -1602,6 +1607,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, /* TODO: multi-memories for now assuming the memory idx type is consistent * across multi-memories */ bool is_memory64 = false; + bool is_table64 = false; if (memory) is_memory64 = memory->is_memory64; #endif @@ -2315,7 +2321,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, /** * type check. compiler will make sure all like - * (call_indirect (type $x) (i32.const 1)) + * (call_indirect (type $x) (it.const 1)) * the function type has to be defined in the module also * no matter it is used or not */ @@ -2334,9 +2340,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, /* clang-format on */ tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif - val = POP_I32(); - if ((uint32)val >= tbl_inst->cur_size) { + val = POP_TBL_ELEM_IDX(); + if (val >= tbl_inst->cur_size) { wasm_set_exception(module, "undefined element"); goto got_exception; } @@ -2482,15 +2491,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, HANDLE_OP(WASM_OP_TABLE_GET) { - uint32 tbl_idx, elem_idx; + uint32 tbl_idx; + tbl_elem_idx_t elem_idx; WASMTableInstance *tbl_inst; read_leb_uint32(frame_ip, frame_ip_end, tbl_idx); bh_assert(tbl_idx < module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif - elem_idx = POP_I32(); + elem_idx = POP_TBL_ELEM_IDX(); if (elem_idx >= tbl_inst->cur_size) { wasm_set_exception(module, "out of bounds table access"); goto got_exception; @@ -2507,20 +2520,24 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, HANDLE_OP(WASM_OP_TABLE_SET) { WASMTableInstance *tbl_inst; - uint32 tbl_idx, elem_idx; + uint32 tbl_idx; + tbl_elem_idx_t elem_idx; table_elem_type_t elem_val; read_leb_uint32(frame_ip, frame_ip_end, tbl_idx); bh_assert(tbl_idx < module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif #if WASM_ENABLE_GC == 0 elem_val = POP_I32(); #else elem_val = POP_REF(); #endif - elem_idx = POP_I32(); + elem_idx = POP_TBL_ELEM_IDX(); if (elem_idx >= tbl_inst->cur_size) { wasm_set_exception(module, "out of bounds table access"); goto got_exception; @@ -4616,13 +4633,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, HANDLE_OP(WASM_OP_MEMORY_GROW) { - uint32 mem_idx, delta, prev_page_count; + uint32 mem_idx, prev_page_count; + mem_offset_t delta; read_leb_memidx(frame_ip, frame_ip_end, mem_idx); prev_page_count = memory->cur_page_count; - delta = (uint32)POP_PAGE_COUNT(); + delta = POP_PAGE_COUNT(); - if (!wasm_enlarge_memory_with_idx(module, delta, mem_idx)) { + if ( +#if WASM_ENABLE_MEMORY64 != 0 + delta > UINT32_MAX || +#endif + !wasm_enlarge_memory_with_idx(module, (uint32)delta, + mem_idx)) { /* failed to memory.grow, return -1 */ PUSH_PAGE_COUNT(-1); } @@ -5778,8 +5801,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 case WASM_OP_TABLE_INIT: { - uint32 tbl_idx, elem_idx; - uint32 n, s, d; + uint32 tbl_idx; + tbl_elem_idx_t elem_idx, d; + uint32 n, s; WASMTableInstance *tbl_inst; table_elem_type_t *table_elems; InitializerExpression *tbl_seg_init_values = NULL, @@ -5793,10 +5817,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, bh_assert(tbl_idx < module->module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif n = (uint32)POP_I32(); s = (uint32)POP_I32(); - d = (uint32)POP_I32(); + d = (tbl_elem_idx_t)POP_TBL_ELEM_IDX(); if (!bh_bitmap_get_bit(module->e->common.elem_dropped, elem_idx)) { @@ -5809,8 +5836,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, .value_count; } - if (offset_len_out_of_bounds(s, n, tbl_seg_len) - || offset_len_out_of_bounds(d, n, + /* TODO: memory64 current implementation of table64 + * still assumes the max table size UINT32_MAX + */ + if ( +#if WASM_ENABLE_MEMORY64 != 0 + d > UINT32_MAX || +#endif + offset_len_out_of_bounds(s, n, tbl_seg_len) + || offset_len_out_of_bounds((uint32)d, n, tbl_inst->cur_size)) { wasm_set_exception(module, "out of bounds table access"); @@ -5864,7 +5898,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, case WASM_OP_TABLE_COPY: { uint32 src_tbl_idx, dst_tbl_idx; - uint32 n, s, d; + tbl_elem_idx_t n, s, d; WASMTableInstance *src_tbl_inst, *dst_tbl_inst; read_leb_uint32(frame_ip, frame_ip_end, dst_tbl_idx); @@ -5877,14 +5911,29 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, src_tbl_inst = wasm_get_table_inst(module, src_tbl_idx); - n = (uint32)POP_I32(); - s = (uint32)POP_I32(); - d = (uint32)POP_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = src_tbl_inst->is_table64 + && dst_tbl_inst->is_table64; +#endif + n = (tbl_elem_idx_t)POP_TBL_ELEM_IDX(); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = src_tbl_inst->is_table64; +#endif + s = (tbl_elem_idx_t)POP_TBL_ELEM_IDX(); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = dst_tbl_inst->is_table64; +#endif + d = (tbl_elem_idx_t)POP_TBL_ELEM_IDX(); - if (offset_len_out_of_bounds(d, n, + if ( +#if WASM_ENABLE_MEMORY64 != 0 + n > UINT32_MAX || s > UINT32_MAX || d > UINT32_MAX + || +#endif + offset_len_out_of_bounds((uint32)d, (uint32)n, dst_tbl_inst->cur_size) || offset_len_out_of_bounds( - s, n, src_tbl_inst->cur_size)) { + (uint32)s, (uint32)n, src_tbl_inst->cur_size)) { wasm_set_exception(module, "out of bounds table access"); goto got_exception; @@ -5907,28 +5956,37 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, case WASM_OP_TABLE_GROW: { WASMTableInstance *tbl_inst; - uint32 tbl_idx, n, orig_tbl_sz; + uint32 tbl_idx, orig_tbl_sz; + tbl_elem_idx_t n; table_elem_type_t init_val; read_leb_uint32(frame_ip, frame_ip_end, tbl_idx); bh_assert(tbl_idx < module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif orig_tbl_sz = tbl_inst->cur_size; - n = POP_I32(); + n = POP_TBL_ELEM_IDX(); #if WASM_ENABLE_GC == 0 init_val = POP_I32(); #else init_val = POP_REF(); #endif - if (!wasm_enlarge_table(module, tbl_idx, n, init_val)) { - PUSH_I32(-1); + if ( +#if WASM_ENABLE_MEMORY64 != 0 + n > UINT32_MAX || +#endif + !wasm_enlarge_table(module, tbl_idx, (uint32)n, + init_val)) { + PUSH_TBL_ELEM_IDX(-1); } else { - PUSH_I32(orig_tbl_sz); + PUSH_TBL_ELEM_IDX(orig_tbl_sz); } break; } @@ -5941,13 +5999,17 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, bh_assert(tbl_idx < module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif - PUSH_I32(tbl_inst->cur_size); + PUSH_TBL_ELEM_IDX(tbl_inst->cur_size); break; } case WASM_OP_TABLE_FILL: { - uint32 tbl_idx, n; + uint32 tbl_idx; + tbl_elem_idx_t n, elem_idx; WASMTableInstance *tbl_inst; table_elem_type_t fill_val; @@ -5955,24 +6017,32 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, bh_assert(tbl_idx < module->table_count); tbl_inst = wasm_get_table_inst(module, tbl_idx); +#if WASM_ENABLE_MEMORY64 != 0 + is_table64 = tbl_inst->is_table64; +#endif - n = POP_I32(); + n = POP_TBL_ELEM_IDX(); #if WASM_ENABLE_GC == 0 fill_val = POP_I32(); #else fill_val = POP_REF(); #endif - i = POP_I32(); + elem_idx = POP_TBL_ELEM_IDX(); - if (offset_len_out_of_bounds(i, n, + if ( +#if WASM_ENABLE_MEMORY64 != 0 + n > UINT32_MAX || elem_idx > UINT32_MAX || +#endif + offset_len_out_of_bounds((uint32)elem_idx, + (uint32)n, tbl_inst->cur_size)) { wasm_set_exception(module, "out of bounds table access"); goto got_exception; } - for (; n != 0; i++, n--) { - tbl_inst->elems[i] = fill_val; + for (; n != 0; elem_idx++, n--) { + tbl_inst->elems[elem_idx] = fill_val; } break; } diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index ff3501e3d0..e6b797f9b7 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -51,6 +51,18 @@ has_module_memory64(WASMModule *module) return false; } + +static bool +is_table_64bit(WASMModule *module, uint32 table_idx) +{ + if (table_idx < module->import_table_count) + return !!(module->import_tables[table_idx].u.table.table_type.flags + & TABLE64_FLAG); + else + return !!(module->tables[table_idx].table_type.flags & TABLE64_FLAG); + + return false; +} #endif static void @@ -2201,10 +2213,14 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } static void -adjust_table_max_size(uint32 init_size, uint32 max_size_flag, uint32 *max_size) +adjust_table_max_size(bool is_table64, uint32 init_size, uint32 max_size_flag, + uint32 *max_size) { uint32 default_max_size; + /* TODO: current still use UINT32_MAX as upper limit for table size to keep + * ABI unchanged */ + (void)is_table64; if (UINT32_MAX / 2 > init_size) default_max_size = init_size * 2; else @@ -2499,9 +2515,9 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, const char *table_name, WASMTableImport *table, char *error_buf, uint32 error_buf_size) { - const uint8 *p = *p_buf, *p_end = buf_end; - uint32 declare_elem_type = 0, declare_max_size_flag = 0, - declare_init_size = 0, declare_max_size = 0; + const uint8 *p = *p_buf, *p_end = buf_end, *p_org; + uint32 declare_elem_type = 0, table_flag = 0, declare_init_size = 0, + declare_max_size = 0; #if WASM_ENABLE_MULTI_MODULE != 0 WASMModule *sub_module = NULL; WASMTable *linked_table = NULL; @@ -2510,6 +2526,7 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, WASMRefType ref_type; bool need_ref_type_map; #endif + bool is_table64 = false; #if WASM_ENABLE_GC == 0 CHECK_BUF(p, p_end, 1); @@ -2548,23 +2565,29 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, #endif #endif /* end of WASM_ENABLE_GC == 0 */ - read_leb_uint32(p, p_end, declare_max_size_flag); - if (declare_max_size_flag > 1) { - set_error_buf(error_buf, error_buf_size, "integer too large"); + p_org = p; + read_leb_uint32(p, p_end, table_flag); + is_table64 = table_flag & TABLE64_FLAG; + if (p - p_org > 1) { + LOG_VERBOSE("integer representation too long(import table)"); + set_error_buf(error_buf, error_buf_size, "invalid limits flags"); return false; } - read_leb_uint32(p, p_end, declare_init_size); + if (!wasm_table_check_flags(table_flag, error_buf, error_buf_size, false)) { + return false; + } - if (declare_max_size_flag) { + read_leb_uint32(p, p_end, declare_init_size); + if (table_flag & MAX_TABLE_SIZE_FLAG) { read_leb_uint32(p, p_end, declare_max_size); if (!check_table_max_size(declare_init_size, declare_max_size, error_buf, error_buf_size)) return false; } - adjust_table_max_size(declare_init_size, declare_max_size_flag, - &declare_max_size); + adjust_table_max_size(is_table64, declare_init_size, + table_flag & MAX_TABLE_SIZE_FLAG, &declare_max_size); *p_buf = p; @@ -2582,7 +2605,7 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, declare_elem_type = linked_table->table_type.elem_type; declare_init_size = linked_table->table_type.init_size; declare_max_size = linked_table->table_type.max_size; - declare_max_size_flag = linked_table->table_type.flags; + table_flag = linked_table->table_type.flags; table->import_table_linked = linked_table; table->import_module = sub_module; } @@ -2591,12 +2614,17 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, #endif /* WASM_ENABLE_MULTI_MODULE != 0 */ /* (table (export "table") 10 20 funcref) */ + /* (table (export "table64") 10 20 funcref) */ /* we need this section working in wamrc */ if (!strcmp("spectest", sub_module_name)) { const uint32 spectest_table_init_size = 10; const uint32 spectest_table_max_size = 20; - if (strcmp("table", table_name)) { + if (strcmp("table", table_name) +#if WASM_ENABLE_MEMORY64 != 0 + && strcmp("table64", table_name) +#endif + ) { set_error_buf(error_buf, error_buf_size, "incompatible import type or unknown import"); return false; @@ -2616,7 +2644,7 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, /* now we believe all declaration are ok */ table->table_type.elem_type = declare_elem_type; table->table_type.init_size = declare_init_size; - table->table_type.flags = declare_max_size_flag; + table->table_type.flags = table_flag; table->table_type.max_size = declare_max_size; #if WASM_ENABLE_WAMR_COMPILER != 0 @@ -2709,7 +2737,7 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end, read_leb_uint32(p, p_end, mem_flag); is_memory64 = mem_flag & MEMORY64_FLAG; if (p - p_org > 1) { - LOG_VERBOSE("integer representation too long"); + LOG_VERBOSE("integer representation too long(import memory)"); set_error_buf(error_buf, error_buf_size, "invalid limits flags"); return false; } @@ -3024,6 +3052,7 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module, WASMRefType ref_type; bool need_ref_type_map; #endif + bool is_table64 = false; #if WASM_ENABLE_GC == 0 CHECK_BUF(p, p_end, 1); @@ -3061,34 +3090,20 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module, p_org = p; read_leb_uint32(p, p_end, table->table_type.flags); -#if WASM_ENABLE_SHARED_MEMORY == 0 - if (p - p_org > 1) { - set_error_buf(error_buf, error_buf_size, - "integer representation too long"); - return false; - } - if (table->table_type.flags > 1) { - set_error_buf(error_buf, error_buf_size, "integer too large"); - return false; - } -#else + is_table64 = table->table_type.flags & TABLE64_FLAG; if (p - p_org > 1) { + LOG_VERBOSE("integer representation too long(table)"); set_error_buf(error_buf, error_buf_size, "invalid limits flags"); return false; } - if (table->table_type.flags == 2) { - set_error_buf(error_buf, error_buf_size, "tables cannot be shared"); - return false; - } - if (table->table_type.flags > 1) { - set_error_buf(error_buf, error_buf_size, "invalid limits flags"); + + if (!wasm_table_check_flags(table->table_type.flags, error_buf, + error_buf_size, false)) { return false; } -#endif read_leb_uint32(p, p_end, table->table_type.init_size); - - if (table->table_type.flags) { + if (table->table_type.flags & MAX_TABLE_SIZE_FLAG) { read_leb_uint32(p, p_end, table->table_type.max_size); if (!check_table_max_size(table->table_type.init_size, table->table_type.max_size, error_buf, @@ -3096,7 +3111,8 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module, return false; } - adjust_table_max_size(table->table_type.init_size, table->table_type.flags, + adjust_table_max_size(is_table64, table->table_type.init_size, + table->table_type.flags & MAX_TABLE_SIZE_FLAG, &table->table_type.max_size); #if WASM_ENABLE_WAMR_COMPILER != 0 @@ -3128,7 +3144,7 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory, read_leb_uint32(p, p_end, memory->flags); is_memory64 = memory->flags & MEMORY64_FLAG; if (p - p_org > 1) { - LOG_VERBOSE("integer representation too long"); + LOG_VERBOSE("integer representation too long(memory)"); set_error_buf(error_buf, error_buf_size, "invalid limits flags"); return false; } @@ -4402,6 +4418,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, uint32 error_buf_size) { const uint8 *p = buf, *p_end = buf_end; + uint8 table_elem_idx_type; uint32 table_segment_count, i; uint64 total_size; WASMTableSeg *table_segment; @@ -4424,6 +4441,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, "invalid elements segment kind"); return false; } + table_elem_idx_type = VALUE_TYPE_I32; #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 read_leb_uint32(p, p_end, table_segment->mode); @@ -4459,9 +4477,17 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, if (!check_table_index(module, table_segment->table_index, error_buf, error_buf_size)) return false; - if (!load_init_expr( - module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, NULL, error_buf, error_buf_size)) + +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + if (!load_init_expr(module, &p, p_end, + &table_segment->base_offset, + table_elem_idx_type, NULL, error_buf, + error_buf_size)) return false; if (table_segment->mode == 0) { @@ -4509,9 +4535,16 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, &table_segment->table_index, error_buf, error_buf_size)) return false; - if (!load_init_expr( - module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, NULL, error_buf, error_buf_size)) +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + if (!load_init_expr(module, &p, p_end, + &table_segment->base_offset, + table_elem_idx_type, NULL, error_buf, + error_buf_size)) return false; if (!load_elem_type(module, &p, p_end, &table_segment->elem_type, @@ -4563,7 +4596,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, "unknown element segment kind"); return false; } -#else /* else of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */ +#else /* else of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */ /* * like: 00 41 05 0b 04 00 01 00 01 * for: (elem 0 (offset (i32.const 5)) $f1 $f2 $f1 $f2) @@ -4572,8 +4605,14 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, &table_segment->table_index, error_buf, error_buf_size)) return false; +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (!load_init_expr(module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, NULL, error_buf, + table_elem_idx_type, NULL, error_buf, error_buf_size)) return false; if (!load_func_index_vec(&p, p_end, module, table_segment, @@ -4588,6 +4627,16 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, return false; #endif /* end of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */ +#if WASM_ENABLE_MEMORY64 != 0 + if (table_elem_idx_type == VALUE_TYPE_I64 + && table_segment->base_offset.u.u64 > UINT32_MAX) { + set_error_buf(error_buf, error_buf_size, + "In table64, table base offset can't be " + "larger than UINT32_MAX"); + return false; + } +#endif + #if WASM_ENABLE_WAMR_COMPILER != 0 if (table_segment->elem_type == VALUE_TYPE_EXTERNREF) module->is_ref_types_used = true; @@ -6110,6 +6159,12 @@ load_from_sections(WASMModule *module, WASMSection *sections, #endif } +#if WASM_ENABLE_MEMORY64 != 0 + if (!check_memory64_flags_consistency(module, error_buf, error_buf_size, + false)) + return false; +#endif + calculate_global_data_offset(module); #if WASM_ENABLE_FAST_JIT != 0 @@ -9608,6 +9663,7 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, #define POP_REF(Type) TEMPLATE_POP_REF(Type) #define PUSH_MEM_OFFSET() TEMPLATE_PUSH_REF(mem_offset_type) #define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET() +#define PUSH_TBL_ELEM_IDX() TEMPLATE_PUSH_REF(table_elem_idx_type) #define POP_I32() TEMPLATE_POP(I32) #define POP_F32() TEMPLATE_POP(F32) @@ -9618,6 +9674,7 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, #define POP_EXTERNREF() TEMPLATE_POP(EXTERNREF) #define POP_STRINGREF() TEMPLATE_POP(STRINGREF) #define POP_MEM_OFFSET() TEMPLATE_POP_REF(mem_offset_type) +#define POP_TBL_ELEM_IDX() TEMPLATE_POP_REF(table_elem_idx_type) #if WASM_ENABLE_FAST_INTERP != 0 @@ -10803,7 +10860,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint8 *p = func->code, *p_end = func->code + func->code_size, *p_org; uint32 param_count, local_count, global_count; - uint8 *param_types, *local_types, local_type, global_type, mem_offset_type; + uint8 *param_types, *local_types, local_type, global_type, mem_offset_type, + table_elem_idx_type; BlockType func_block_type; uint16 *local_offsets, local_offset; uint32 type_idx, func_idx, local_idx, global_idx, table_idx; @@ -10838,6 +10896,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, mem_offset_type = is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32; #else mem_offset_type = VALUE_TYPE_I32; + table_elem_idx_type = VALUE_TYPE_I32; #endif uint32 memidx; @@ -11997,8 +12056,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif /* skip elem idx */ - POP_I32(); + POP_TBL_ELEM_IDX(); if (type_idx >= module->type_count) { set_error_buf(error_buf, error_buf_size, "unknown type"); @@ -12375,8 +12439,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; } - /* table.get x. tables[x]. [i32] -> [t] */ - /* table.set x. tables[x]. [i32 t] -> [] */ + /* table.get x. tables[x]. [it] -> [t] */ + /* table.set x. tables[x]. [it t] -> [] */ case WASM_OP_TABLE_GET: case WASM_OP_TABLE_SET: { @@ -12407,8 +12471,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (opcode == WASM_OP_TABLE_GET) { - POP_I32(); + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_FAST_INTERP != 0 PUSH_OFFSET_TYPE(decl_ref_type); #endif @@ -12419,7 +12488,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, POP_OFFSET_TYPE(decl_ref_type); #endif POP_TYPE(decl_ref_type); - POP_I32(); + POP_TBL_ELEM_IDX(); } #if WASM_ENABLE_WAMR_COMPILER != 0 @@ -14702,7 +14771,12 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #endif POP_I32(); POP_I32(); - POP_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_WAMR_COMPILER != 0 module->is_ref_types_used = true; @@ -14727,7 +14801,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } case WASM_OP_TABLE_COPY: { - uint8 src_type, dst_type; + uint8 src_type, dst_type, src_tbl_idx_type, + dst_tbl_idx_type, min_tbl_idx_type; #if WASM_ENABLE_GC != 0 WASMRefType *src_ref_type = NULL, *dst_ref_type = NULL; #endif @@ -14773,9 +14848,31 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, dst_tbl_idx); emit_uint32(loader_ctx, src_tbl_idx); #endif - POP_I32(); - POP_I32(); - POP_I32(); + +#if WASM_ENABLE_MEMORY64 != 0 + src_tbl_idx_type = is_table_64bit(module, src_tbl_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; + dst_tbl_idx_type = is_table_64bit(module, dst_tbl_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; + min_tbl_idx_type = + (src_tbl_idx_type == VALUE_TYPE_I32 + || dst_tbl_idx_type == VALUE_TYPE_I32) + ? VALUE_TYPE_I32 + : VALUE_TYPE_I64; +#else + src_tbl_idx_type = VALUE_TYPE_I32; + dst_tbl_idx_type = VALUE_TYPE_I32; + min_tbl_idx_type = VALUE_TYPE_I32; +#endif + + table_elem_idx_type = min_tbl_idx_type; + POP_TBL_ELEM_IDX(); + table_elem_idx_type = src_tbl_idx_type; + POP_TBL_ELEM_IDX(); + table_elem_idx_type = dst_tbl_idx_type; + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_WAMR_COMPILER != 0 module->is_ref_types_used = true; @@ -14795,7 +14892,12 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif - PUSH_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + PUSH_TBL_ELEM_IDX(); #if WASM_ENABLE_WAMR_COMPILER != 0 module->is_ref_types_used = true; @@ -14844,15 +14946,20 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif - POP_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_FAST_INTERP != 0 POP_OFFSET_TYPE(decl_type); #endif POP_TYPE(decl_type); if (opcode1 == WASM_OP_TABLE_GROW) - PUSH_I32(); + PUSH_TBL_ELEM_IDX(); else - POP_I32(); + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_WAMR_COMPILER != 0 module->is_ref_types_used = true; diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index 968eaf0096..0c29ef3ce0 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -33,12 +33,25 @@ 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.mem_type.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); return false; } + +static bool +is_table_64bit(WASMModule *module, uint32 table_idx) +{ + if (table_idx < module->import_table_count) + return !!(module->import_tables[table_idx].u.table.table_type.flags + & TABLE64_FLAG); + else + return !!(module->tables[table_idx].table_type.flags & TABLE64_FLAG); + + return false; +} #endif static void @@ -577,11 +590,15 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } static void -adjust_table_max_size(uint32 init_size, uint32 max_size_flag, uint32 *max_size) +adjust_table_max_size(bool is_table64, uint32 init_size, uint32 max_size_flag, + uint32 *max_size) { uint32 default_max_size = init_size * 2 > WASM_TABLE_MAX_SIZE ? init_size * 2 : WASM_TABLE_MAX_SIZE; + /* TODO: current still use UINT32_MAX as upper limit for table size to keep + * ABI unchanged */ + (void)is_table64; if (max_size_flag) { /* module defines the table limitation */ @@ -642,8 +659,8 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, char *error_buf, uint32 error_buf_size) { const uint8 *p = *p_buf, *p_end = buf_end; - uint32 declare_elem_type = 0, declare_max_size_flag = 0, - declare_init_size = 0, declare_max_size = 0; + uint32 declare_elem_type = 0, table_flag = 0, declare_init_size = 0, + declare_max_size = 0; CHECK_BUF(p, p_end, 1); /* 0x70 or 0x6F */ @@ -654,24 +671,29 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, #endif ); - read_leb_uint32(p, p_end, declare_max_size_flag); + read_leb_uint32(p, p_end, table_flag); + + if (!wasm_table_check_flags(table_flag, error_buf, error_buf_size, false)) { + return false; + } + read_leb_uint32(p, p_end, declare_init_size); - if (declare_max_size_flag & 1) { + if (table_flag & MAX_TABLE_SIZE_FLAG) { read_leb_uint32(p, p_end, declare_max_size); bh_assert(table->table_type.init_size <= table->table_type.max_size); } - adjust_table_max_size(declare_init_size, declare_max_size_flag, - &declare_max_size); + adjust_table_max_size(table_flag & TABLE64_FLAG, declare_init_size, + table_flag & MAX_TABLE_SIZE_FLAG, &declare_max_size); *p_buf = p; - bh_assert( - !((declare_max_size_flag & 1) && declare_init_size > declare_max_size)); + bh_assert(!((table_flag & MAX_TABLE_SIZE_FLAG) + && declare_init_size > declare_max_size)); /* now we believe all declaration are ok */ table->table_type.elem_type = declare_elem_type; table->table_type.init_size = declare_init_size; - table->table_type.flags = declare_max_size_flag; + table->table_type.flags = table_flag; table->table_type.max_size = declare_max_size; return true; } @@ -789,16 +811,22 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMTable *table, p_org = p; read_leb_uint32(p, p_end, table->table_type.flags); bh_assert(p - p_org <= 1); - bh_assert(table->table_type.flags <= 1); (void)p_org; + if (!wasm_table_check_flags(table->table_type.flags, error_buf, + error_buf_size, false)) { + return false; + } + read_leb_uint32(p, p_end, table->table_type.init_size); - if (table->table_type.flags == 1) { + if (table->table_type.flags == MAX_TABLE_SIZE_FLAG) { read_leb_uint32(p, p_end, table->table_type.max_size); bh_assert(table->table_type.init_size <= table->table_type.max_size); } - adjust_table_max_size(table->table_type.init_size, table->table_type.flags, + adjust_table_max_size(table->table_type.flags & TABLE64_FLAG, + table->table_type.init_size, + table->table_type.flags & MAX_TABLE_SIZE_FLAG, &table->table_type.max_size); *p_buf = p; @@ -1575,6 +1603,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, uint32 error_buf_size) { const uint8 *p = buf, *p_end = buf_end; + uint8 table_elem_idx_type; uint32 table_segment_count, i, table_index, function_count; uint64 total_size; WASMTableSeg *table_segment; @@ -1592,6 +1621,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, table_segment = module->table_segments; for (i = 0; i < table_segment_count; i++, table_segment++) { bh_assert(p < p_end); + table_elem_idx_type = VALUE_TYPE_I32; #if WASM_ENABLE_REF_TYPES != 0 read_leb_uint32(p, p_end, table_segment->mode); @@ -1608,9 +1638,15 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, error_buf, error_buf_size)) return false; +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (!load_init_expr( module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, error_buf, error_buf_size)) + table_elem_idx_type, error_buf, error_buf_size)) return false; if (table_segment->mode == 0) { @@ -1646,9 +1682,15 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, &table_segment->table_index, error_buf, error_buf_size)) return false; +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (!load_init_expr( module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, error_buf, error_buf_size)) + table_elem_idx_type, error_buf, error_buf_size)) return false; if (!load_elem_type(&p, p_end, &table_segment->elem_type, table_segment->mode == 2 ? true : false, @@ -1691,13 +1733,29 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, &table_segment->table_index, error_buf, error_buf_size)) return false; +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = + is_table_64bit(module, table_segment->table_index) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (!load_init_expr(module, &p, p_end, &table_segment->base_offset, - VALUE_TYPE_I32, error_buf, error_buf_size)) + table_elem_idx_type, error_buf, error_buf_size)) return false; if (!load_func_index_vec(&p, p_end, module, table_segment, error_buf, error_buf_size)) return false; #endif /* WASM_ENABLE_REF_TYPES != 0 */ + +#if WASM_ENABLE_MEMORY64 != 0 + if (table_elem_idx_type == VALUE_TYPE_I64 + && table_segment->base_offset.u.u64 > UINT32_MAX) { + set_error_buf(error_buf, error_buf_size, + "In table64, table base offset can't be " + "larger than UINT32_MAX"); + return false; + } +#endif } } @@ -1781,8 +1839,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.mem_type.flags; + memory_flag = module->import_memories[mem_index] + .u.memory.mem_type.flags; } else { memory_flag = @@ -2948,6 +3006,12 @@ load_from_sections(WASMModule *module, WASMSection *sections, } } +#if WASM_ENABLE_MEMORY64 != 0 + if (!check_memory64_flags_consistency(module, error_buf, error_buf_size, + false)) + return false; +#endif + calculate_global_data_offset(module); #if WASM_ENABLE_FAST_JIT != 0 @@ -5214,6 +5278,13 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, } while (0) #define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET() +#define PUSH_TBL_ELEM_IDX() \ + do { \ + if (!(wasm_loader_push_frame_ref(loader_ctx, table_elem_idx_type, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) + #define POP_MEM_OFFSET() \ do { \ if (!wasm_loader_pop_frame_ref_offset(loader_ctx, mem_offset_type, \ @@ -5221,6 +5292,13 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, goto fail; \ } while (0) +#define POP_TBL_ELEM_IDX() \ + do { \ + if (!(wasm_loader_pop_frame_ref(loader_ctx, table_elem_idx_type, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) + #define POP_AND_PUSH(type_pop, type_push) \ do { \ if (!(wasm_loader_push_pop_frame_ref_offset( \ @@ -5284,6 +5362,13 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, #define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET() +#define PUSH_TBL_ELEM_IDX() \ + do { \ + if (!(wasm_loader_push_frame_ref(loader_ctx, table_elem_idx_type, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) + #define POP_I32() \ do { \ if (!(wasm_loader_pop_frame_ref(loader_ctx, VALUE_TYPE_I32, error_buf, \ @@ -5326,6 +5411,13 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, void *value, goto fail; \ } while (0) +#define POP_TBL_ELEM_IDX() \ + do { \ + if (!(wasm_loader_pop_frame_ref(loader_ctx, table_elem_idx_type, \ + error_buf, error_buf_size))) \ + goto fail; \ + } while (0) + #define POP_AND_PUSH(type_pop, type_push) \ do { \ if (!(wasm_loader_push_pop_frame_ref(loader_ctx, 1, type_push, \ @@ -5945,7 +6037,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint8 *p = func->code, *p_end = func->code + func->code_size, *p_org; uint32 param_count, local_count, global_count; - uint8 *param_types, *local_types, local_type, global_type, mem_offset_type; + uint8 *param_types, *local_types, local_type, global_type, mem_offset_type, + table_elem_idx_type; BlockType func_block_type; uint16 *local_offsets, local_offset; uint32 count, local_idx, global_idx, u32, align, i, memidx; @@ -5976,6 +6069,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, mem_offset_type = is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32; #else mem_offset_type = VALUE_TYPE_I32; + table_elem_idx_type = VALUE_TYPE_I32; #endif global_count = module->import_global_count + module->global_count; @@ -6588,8 +6682,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif /* skip elem idx */ - POP_I32(); + POP_TBL_ELEM_IDX(); bh_assert(type_idx < module->type_count); @@ -6865,8 +6964,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; } - /* table.get x. tables[x]. [i32] -> [t] */ - /* table.set x. tables[x]. [i32 t] -> [] */ + /* table.get x. tables[x]. [it] -> [t] */ + /* table.set x. tables[x]. [it t] -> [] */ case WASM_OP_TABLE_GET: case WASM_OP_TABLE_SET: { @@ -6882,8 +6981,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif if (opcode == WASM_OP_TABLE_GET) { - POP_I32(); + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_FAST_INTERP != 0 PUSH_OFFSET_TYPE(decl_ref_type); #endif @@ -6894,7 +6998,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, POP_OFFSET_TYPE(decl_ref_type); #endif POP_TYPE(decl_ref_type); - POP_I32(); + POP_TBL_ELEM_IDX(); } break; } @@ -7819,7 +7923,12 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #endif POP_I32(); POP_I32(); - POP_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + POP_TBL_ELEM_IDX(); break; } case WASM_OP_ELEM_DROP: @@ -7838,7 +7947,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_TABLE_COPY: { uint8 src_ref_type, dst_ref_type; - uint32 src_tbl_idx, dst_tbl_idx; + uint32 src_tbl_idx, dst_tbl_idx, src_tbl_idx_type, + dst_tbl_idx_type, min_tbl_idx_type; read_leb_uint32(p, p_end, src_tbl_idx); if (!get_table_elem_type(module, src_tbl_idx, @@ -7862,9 +7972,31 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, src_tbl_idx); emit_uint32(loader_ctx, dst_tbl_idx); #endif - POP_I32(); - POP_I32(); - POP_I32(); + +#if WASM_ENABLE_MEMORY64 != 0 + src_tbl_idx_type = is_table_64bit(module, src_tbl_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; + dst_tbl_idx_type = is_table_64bit(module, dst_tbl_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; + min_tbl_idx_type = + (src_tbl_idx_type == VALUE_TYPE_I32 + || dst_tbl_idx_type == VALUE_TYPE_I32) + ? VALUE_TYPE_I32 + : VALUE_TYPE_I64; +#else + src_tbl_idx_type = VALUE_TYPE_I32; + dst_tbl_idx_type = VALUE_TYPE_I32; + min_tbl_idx_type = VALUE_TYPE_I32; +#endif + + table_elem_idx_type = min_tbl_idx_type; + POP_TBL_ELEM_IDX(); + table_elem_idx_type = src_tbl_idx_type; + POP_TBL_ELEM_IDX(); + table_elem_idx_type = dst_tbl_idx_type; + POP_TBL_ELEM_IDX(); break; } case WASM_OP_TABLE_SIZE: @@ -7882,7 +8014,12 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif - PUSH_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + PUSH_TBL_ELEM_IDX(); break; } case WASM_OP_TABLE_GROW: @@ -7914,15 +8051,20 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, emit_uint32(loader_ctx, table_idx); #endif - POP_I32(); +#if WASM_ENABLE_MEMORY64 != 0 + table_elem_idx_type = is_table_64bit(module, table_idx) + ? VALUE_TYPE_I64 + : VALUE_TYPE_I32; +#endif + POP_TBL_ELEM_IDX(); #if WASM_ENABLE_FAST_INTERP != 0 POP_OFFSET_TYPE(decl_ref_type); #endif POP_TYPE(decl_ref_type); if (opcode1 == WASM_OP_TABLE_GROW) - PUSH_I32(); + PUSH_TBL_ELEM_IDX(); else - POP_I32(); + PUSH_TBL_ELEM_IDX(); break; } #endif /* WASM_ENABLE_REF_TYPES */ diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index e4142ab88c..06ac2dafdf 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -678,6 +678,8 @@ tables_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, uninitialized elements */ #endif + table->is_table64 = import->u.table.table_type.flags & TABLE64_FLAG; + #if WASM_ENABLE_MULTI_MODULE != 0 *table_linked = table_inst_linked; if (table_inst_linked != NULL) { @@ -736,6 +738,7 @@ tables_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, /* For GC, all elements have already been set to NULL_REF (0) as uninitialized elements */ #endif + table->is_table64 = module->tables[i].table_type.flags & TABLE64_FLAG; table->elem_type = module->tables[i].table_type.elem_type; #if WASM_ENABLE_GC != 0 table->elem_ref_type.elem_ref_type = @@ -1594,8 +1597,12 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, if (is_sub_inst) { bh_assert(exec_env_main); #ifdef OS_ENABLE_HW_BOUND_CHECK - bh_assert(exec_env_tls == exec_env_main); - (void)exec_env_tls; + /* May come from pthread_create_wrapper, thread_spawn_wrapper and + wasm_cluster_spawn_exec_env. If it comes from the former two, + the exec_env_tls must be not NULL and equal to exec_env_main, + else if it comes from the last one, it may be NULL. */ + if (exec_env_tls) + bh_assert(exec_env_tls == exec_env_main); #endif exec_env = exec_env_main; diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index e46b63cda1..c5d09cb605 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -157,7 +157,8 @@ struct WASMMemoryInstance { struct WASMTableInstance { /* The element type */ uint8 elem_type; - uint8 __padding__[7]; + uint8 is_table64; + uint8 __padding__[6]; union { #if WASM_ENABLE_GC != 0 WASMRefType *elem_ref_type; diff --git a/core/iwasm/libraries/libc-emcc/libc_emcc_wrapper.c b/core/iwasm/libraries/libc-emcc/libc_emcc_wrapper.c index 427bfd6569..3bb6bc6b76 100644 --- a/core/iwasm/libraries/libc-emcc/libc_emcc_wrapper.c +++ b/core/iwasm/libraries/libc-emcc/libc_emcc_wrapper.c @@ -7,8 +7,13 @@ #include "bh_log.h" #include "wasm_export.h" #include "../interpreter/wasm.h" -#if !defined(_DEFAULT_SOURCE) && !defined(BH_PLATFORM_LINUX_SGX) -#include "sys/syscall.h" + +#if defined(__linux__) +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) +#define HAVE_SYSCALL_GETRANDOM +#include +#endif #endif /* clang-format off */ @@ -168,12 +173,21 @@ statbuf_native2app(const struct stat *statbuf_native, statbuf_app->st_blksize = (unsigned)statbuf_native->st_blksize; statbuf_app->st_blocks = (unsigned)statbuf_native->st_blocks; statbuf_app->st_ino = (int64)statbuf_native->st_ino; +#if defined(__APPLE__) + statbuf_app->st_atim.tv_sec = (int)statbuf_native->st_atimespec.tv_sec; + statbuf_app->st_atim.tv_nsec = (int)statbuf_native->st_atimespec.tv_nsec; + statbuf_app->st_mtim.tv_sec = (int)statbuf_native->st_mtimespec.tv_sec; + statbuf_app->st_mtim.tv_nsec = (int)statbuf_native->st_mtimespec.tv_nsec; + statbuf_app->st_ctim.tv_sec = (int)statbuf_native->st_ctimespec.tv_sec; + statbuf_app->st_ctim.tv_nsec = (int)statbuf_native->st_ctimespec.tv_nsec; +#else statbuf_app->st_atim.tv_sec = (int)statbuf_native->st_atim.tv_sec; statbuf_app->st_atim.tv_nsec = (int)statbuf_native->st_atim.tv_nsec; statbuf_app->st_mtim.tv_sec = (int)statbuf_native->st_mtim.tv_sec; statbuf_app->st_mtim.tv_nsec = (int)statbuf_native->st_mtim.tv_nsec; statbuf_app->st_ctim.tv_sec = (int)statbuf_native->st_ctim.tv_sec; statbuf_app->st_ctim.tv_nsec = (int)statbuf_native->st_ctim.tv_nsec; +#endif } static int @@ -261,10 +275,10 @@ getentropy_wrapper(wasm_exec_env_t exec_env, void *buffer, uint32 length) { if (buffer == NULL) return -1; -#if defined(_DEFAULT_SOURCE) || defined(BH_PLATFORM_LINUX_SGX) - return getentropy(buffer, length); -#else +#if defined(HAVE_SYSCALL_GETRANDOM) return syscall(SYS_getrandom, buffer, length, 0); +#else + return getentropy(buffer, length); #endif } diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/refcount.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/refcount.h index 03b4b87ac3..79b16cc175 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/refcount.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/refcount.h @@ -132,6 +132,35 @@ refcount_release(struct refcount *r) #error "Reference counter isn't implemented" #endif /* end of __GNUC_PREREQ (4.7) */ +#elif defined(_MSC_VER) + +/* Simple reference counter. */ +struct LOCKABLE refcount { + LONG count; +}; + +/* Initialize the reference counter. */ +static inline void +refcount_init(struct refcount *r, unsigned int count) +{ + InterlockedExchange(&r->count, (LONG)count); +} + +/* Increment the reference counter. */ +static inline void +refcount_acquire(struct refcount *r) +{ + InterlockedIncrement(&r->count); +} + +/* Decrement the reference counter, returning whether the reference + dropped to zero. */ +static inline bool +refcount_release(struct refcount *r) +{ + return InterlockedDecrement(&r->count) == 0 ? true : false; +} + #else /* else of CONFIG_HAS_STD_ATOMIC */ #error "Reference counter isn't implemented" #endif /* end of CONFIG_HAS_STD_ATOMIC */ diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h index 4ef29ccdbd..8296772131 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h @@ -70,9 +70,11 @@ #endif #if !defined(BH_PLATFORM_LINUX_SGX) + /* Clang's __GNUC_PREREQ macro has a different meaning than GCC one, so we have to handle this case specially */ #if defined(__clang__) + /* Clang provides stdatomic.h since 3.6.0 See https://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html */ #if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6) @@ -80,7 +82,9 @@ See https://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html */ #else #define CONFIG_HAS_STD_ATOMIC 0 #endif + #elif defined(__GNUC_PREREQ) + /* Even though older versions of GCC support C11, atomics were not implemented until 4.9. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58016 */ @@ -89,11 +93,21 @@ not implemented until 4.9. See #else /* else of __GNUC_PREREQ(4, 9) */ #define CONFIG_HAS_STD_ATOMIC 0 #endif /* end of __GNUC_PREREQ(4, 9) */ -#else /* else of defined(__GNUC_PREREQ) */ + +#elif defined(_MSC_VER) + +#define CONFIG_HAS_STD_ATOMIC 0 + +#else + #define CONFIG_HAS_STD_ATOMIC 1 -#endif /* end of defined(__GNUC_PREREQ) */ -#else /* else of !defined(BH_PLATFORM_LINUX_SGX) */ + +#endif /* end of defined(__clang__) */ + +#else /* else of !defined(BH_PLATFORM_LINUX_SGX) */ + #define CONFIG_HAS_STD_ATOMIC 0 + #endif /* end of !defined(BH_PLATFORM_LINUX_SGX) */ -#endif +#endif /* end of SSP_CONFIG_H */ diff --git a/core/iwasm/libraries/wasi-nn/README.md b/core/iwasm/libraries/wasi-nn/README.md index 5536f6d57b..99a7664676 100644 --- a/core/iwasm/libraries/wasi-nn/README.md +++ b/core/iwasm/libraries/wasi-nn/README.md @@ -103,7 +103,6 @@ docker run \ wasi-nn-cpu \ --dir=/ \ --env="TARGET=cpu" \ - --native-lib=/lib/libwasi-nn-tflite.so \ /assets/test_tensorflow.wasm ``` @@ -119,7 +118,6 @@ docker run \ wasi-nn-nvidia-gpu \ --dir=/ \ --env="TARGET=gpu" \ - --native-lib=/lib/libwasi-nn-tflite.so \ /assets/test_tensorflow.wasm ``` @@ -131,7 +129,6 @@ docker run \ wasi-nn-vx-delegate \ --dir=/ \ --env="TARGET=gpu" \ - --native-lib=/lib/libwasi-nn-tflite.so \ /assets/test_tensorflow_quantized.wasm ``` @@ -147,7 +144,6 @@ docker run \ wasi-nn-tpu \ --dir=/ \ --env="TARGET=tpu" \ - --native-lib=/lib/libwasi-nn-tflite.so \ /assets/test_tensorflow_quantized.wasm ``` @@ -155,8 +151,8 @@ docker run \ Supported: -- Graph encoding: `tensorflowlite`. -- Execution target: `cpu`, `gpu` and `tpu`. +- Graph encoding: `tensorflowlite`, `openvino` and `ggml` +- Execution target: `cpu` for all. `gpu` and `tpu` for `tensorflowlite`. - Tensor type: `fp32`. ## Smoke test diff --git a/core/iwasm/libraries/wasi-nn/cmake/Findcjson.cmake b/core/iwasm/libraries/wasi-nn/cmake/Findcjson.cmake index 1136f41adc..6c921bbc93 100644 --- a/core/iwasm/libraries/wasi-nn/cmake/Findcjson.cmake +++ b/core/iwasm/libraries/wasi-nn/cmake/Findcjson.cmake @@ -4,13 +4,21 @@ include(FetchContent) set(CJSON_SOURCE_DIR "${WAMR_ROOT_DIR}/core/deps/cjson") - -FetchContent_Declare( - cjson - GIT_REPOSITORY https://github.com/DaveGamble/cJSON.git - GIT_TAG v1.7.18 - SOURCE_DIR ${CJSON_SOURCE_DIR} -) +if(EXISTS ${CJSON_SOURCE_DIR}) + message("Use existed source code under ${CJSON_SOURCE_DIR}") + FetchContent_Declare( + cjson + SOURCE_DIR ${CJSON_SOURCE_DIR} + ) +else() + message("download source code and store it at ${CJSON_SOURCE_DIR}") + FetchContent_Declare( + cjson + GIT_REPOSITORY https://github.com/DaveGamble/cJSON.git + GIT_TAG v1.7.18 + SOURCE_DIR ${CJSON_SOURCE_DIR} + ) +endif() set(ENABLE_CJSON_TEST OFF CACHE INTERNAL "Turn off tests") set(ENABLE_CJSON_UNINSTALL OFF CACHE INTERNAL "Turn off uninstall to avoid targets conflict") diff --git a/core/iwasm/libraries/wasi-nn/cmake/Findllamacpp.cmake b/core/iwasm/libraries/wasi-nn/cmake/Findllamacpp.cmake index 431e15db59..8f4f8d1aa7 100644 --- a/core/iwasm/libraries/wasi-nn/cmake/Findllamacpp.cmake +++ b/core/iwasm/libraries/wasi-nn/cmake/Findllamacpp.cmake @@ -4,13 +4,21 @@ include(FetchContent) set(LLAMA_SOURCE_DIR "${WAMR_ROOT_DIR}/core/deps/llama.cpp") - -FetchContent_Declare( - llamacpp - GIT_REPOSITORY https://github.com/ggerganov/llama.cpp.git - GIT_TAG b3573 - SOURCE_DIR ${LLAMA_SOURCE_DIR} -) +if(EXISTS ${LLAMA_SOURCE_DIR}) + message("Use existed source code under ${LLAMA_SOURCE_DIR}") + FetchContent_Declare( + llamacpp + SOURCE_DIR ${LLAMA_SOURCE_DIR} + ) +else() + message("download source code and store it at ${LLAMA_SOURCE_DIR}") + FetchContent_Declare( + llamacpp + GIT_REPOSITORY https://github.com/ggerganov/llama.cpp.git + GIT_TAG b3573 + SOURCE_DIR ${LLAMA_SOURCE_DIR} + ) +endif() set(LLAMA_BUILD_TESTS OFF) set(LLAMA_BUILD_EXAMPLES OFF) diff --git a/core/iwasm/libraries/wasi-nn/cmake/Findtensorflow_lite.cmake b/core/iwasm/libraries/wasi-nn/cmake/Findtensorflow_lite.cmake index 39480741d3..d2b3f74e04 100644 --- a/core/iwasm/libraries/wasi-nn/cmake/Findtensorflow_lite.cmake +++ b/core/iwasm/libraries/wasi-nn/cmake/Findtensorflow_lite.cmake @@ -4,20 +4,32 @@ include(FetchContent) set(TFLITE_SOURCE_DIR "${WAMR_ROOT_DIR}/core/deps/tensorflow-src") +if(EXISTS ${TFLITE_SOURCE_DIR}) + message("Use existed source code under ${TFLITE_SOURCE_DIR}") + FetchContent_Declare( + tensorflow_lite + SOURCE_DIR ${TFLITE_SOURCE_DIR} + SOURCE_SUBDIR tensorflow/lite + ) +else() + message("download source code and store it at ${TFLITE_SOURCE_DIR}") + FetchContent_Declare( + tensorflow_lite + GIT_REPOSITORY https://github.com/tensorflow/tensorflow.git + GIT_TAG v2.12.0 + GIT_SHALLOW ON + GIT_PROGRESS ON + SOURCE_DIR ${TFLITE_SOURCE_DIR} + SOURCE_SUBDIR tensorflow/lite + PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/add_telemetry.patch + ) +endif() -FetchContent_Declare( - tensorflow_lite - GIT_REPOSITORY https://github.com/tensorflow/tensorflow.git - GIT_TAG v2.12.0 - GIT_SHALLOW ON - GIT_PROGRESS ON - SOURCE_DIR ${TFLITE_SOURCE_DIR} - SOURCE_SUBDIR tensorflow/lite -) if(WAMR_BUILD_WASI_NN_ENABLE_GPU EQUAL 1) set(TFLITE_ENABLE_GPU ON) endif() + if (CMAKE_SIZEOF_VOID_P EQUAL 4) set(TFLITE_ENABLE_XNNPACK OFF) endif() diff --git a/core/iwasm/libraries/wasi-nn/cmake/add_telemetry.patch b/core/iwasm/libraries/wasi-nn/cmake/add_telemetry.patch new file mode 100644 index 0000000000..8dbf5c355c --- /dev/null +++ b/core/iwasm/libraries/wasi-nn/cmake/add_telemetry.patch @@ -0,0 +1,12 @@ +diff --git a/tensorflow/lite/CMakeLists.txt b/tensorflow/lite/CMakeLists.txt +index c71a3925ac..39591a3bd7 100644 +--- a/tensorflow/lite/CMakeLists.txt ++++ b/tensorflow/lite/CMakeLists.txt +@@ -493,6 +493,7 @@ set(TFLITE_PROFILER_SRCS + ${TFLITE_SOURCE_DIR}/profiling/root_profiler.h + ${TFLITE_SOURCE_DIR}/profiling/root_profiler.cc + ${TFLITE_SOURCE_DIR}/profiling/telemetry/profiler.cc ++ ${TFLITE_SOURCE_DIR}/profiling/telemetry/telemetry.cc + ) + if(CMAKE_SYSTEM_NAME MATCHES "Android") + list(APPEND TFLITE_PROFILER_SRCS diff --git a/core/iwasm/libraries/wasi-nn/test/Dockerfile.cpu b/core/iwasm/libraries/wasi-nn/test/Dockerfile.cpu index a33bebff51..67bfbfe0e5 100644 --- a/core/iwasm/libraries/wasi-nn/test/Dockerfile.cpu +++ b/core/iwasm/libraries/wasi-nn/test/Dockerfile.cpu @@ -14,19 +14,32 @@ WORKDIR /usr/local/share/ca-certificates/cacert.org RUN wget -qP /usr/local/share/ca-certificates/cacert.org http://www.cacert.org/certs/root.crt http://www.cacert.org/certs/class3.crt \ && update-ca-certificates +# need a newer cmake +RUN apt-get purge -y cmake + +ARG CMAKE_VER=3.27.0 +RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VER}/cmake-${CMAKE_VER}-Linux-x86_64.sh \ + -q -O /tmp/cmake-install.sh \ + && chmod u+x /tmp/cmake-install.sh \ + && mkdir /opt/cmake-${CMAKE_VER} \ + && /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-${CMAKE_VER} \ + && rm /tmp/cmake-install.sh \ + && ln -s /opt/cmake-${CMAKE_VER}/bin/* /usr/local/bin + WORKDIR /home/wamr COPY . . RUN git config --global http.sslCAinfo /etc/ssl/certs/ca-certificates.crt WORKDIR /home/wamr/product-mini/platforms/linux RUN rm -rf build \ - && cmake -S . -B build -DWAMR_BUILD_WASI_NN=1 \ + && cmake -S . -B build\ + -DWAMR_BUILD_WASI_NN=1 -DWAMR_BUILD_WASI_NN_TFLITE=1\ && cmake --build build -j "$(grep -c ^processor /proc/cpuinfo)" FROM ubuntu:22.04 -COPY --from=base /home/wamr/product-mini/platforms/linux/build/iwasm /usr/bin/iwasm -COPY --from=base /home/wamr/product-mini/platforms/linux/build/libiwasm.so /lib/libiwasm.so -COPY --from=base /home/wamr/product-mini/platforms/linux/build/libwasi-nn-*.so /lib/ +COPY --from=base /home/wamr/product-mini/platforms/linux/build/iwasm /usr/bin +COPY --from=base /home/wamr/product-mini/platforms/linux/build/lib*.so /usr/lib +ENV LD_LIBRARY_PATH=/usr/lib ENTRYPOINT [ "iwasm" ] diff --git a/core/iwasm/libraries/wasi-nn/test/Dockerfile.nvidia-gpu b/core/iwasm/libraries/wasi-nn/test/Dockerfile.nvidia-gpu index 49ee51a15e..8fe82510a6 100644 --- a/core/iwasm/libraries/wasi-nn/test/Dockerfile.nvidia-gpu +++ b/core/iwasm/libraries/wasi-nn/test/Dockerfile.nvidia-gpu @@ -14,14 +14,26 @@ WORKDIR /usr/local/share/ca-certificates/cacert.org RUN wget -qP /usr/local/share/ca-certificates/cacert.org http://www.cacert.org/certs/root.crt http://www.cacert.org/certs/class3.crt \ && update-ca-certificates +# need a newer cmake +RUN apt-get purge -y cmake + +ARG CMAKE_VER=3.27.0 +RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VER}/cmake-${CMAKE_VER}-Linux-x86_64.sh \ + -q -O /tmp/cmake-install.sh \ + && chmod u+x /tmp/cmake-install.sh \ + && mkdir /opt/cmake-${CMAKE_VER} \ + && /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-${CMAKE_VER} \ + && rm /tmp/cmake-install.sh \ + && ln -s /opt/cmake-${CMAKE_VER}/bin/* /usr/local/bin + WORKDIR /home/wamr COPY . . RUN git config --global http.sslCAinfo /etc/ssl/certs/ca-certificates.crt -WORKDIR /home/wamr/product-mini/platforms/linux/build +WORKDIR /home/wamr/product-mini/platforms/linux RUN rm -rf build \ && cmake -S . -B build \ - -DWAMR_BUILD_WASI_NN=1 \ + -DWAMR_BUILD_WASI_NN=1 -DWAMR_BUILD_WASI_NN_TFLITE=1\ -DWAMR_BUILD_WASI_NN_ENABLE_GPU=1 \ && cmake --build build -j "$(grep -c ^processor /proc/cpuinfo)" @@ -40,8 +52,8 @@ RUN mkdir -p /etc/OpenCL/vendors && \ ENV NVIDIA_VISIBLE_DEVICES=all ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility -COPY --from=base /home/wamr/product-mini/platforms/linux/build/iwasm /usr/bin/iwasm -COPY --from=base /home/wamr/product-mini/platforms/linux/build/libiwasm.so /lib/libiwasm.so -COPY --from=base /home/wamr/product-mini/platforms/linux/build/libwasi-nn-*.so /lib/ +COPY --from=base /home/wamr/product-mini/platforms/linux/build/iwasm /usr/bin +COPY --from=base /home/wamr/product-mini/platforms/linux/build/lib*.so /usr/lib +ENV LD_LIBRARY_PATH=/usr/lib ENTRYPOINT [ "iwasm" ] diff --git a/core/iwasm/libraries/wasi-nn/test/Dockerfile.tpu b/core/iwasm/libraries/wasi-nn/test/Dockerfile.tpu index a0ae29a63f..6a7dc15341 100644 --- a/core/iwasm/libraries/wasi-nn/test/Dockerfile.tpu +++ b/core/iwasm/libraries/wasi-nn/test/Dockerfile.tpu @@ -14,22 +14,35 @@ WORKDIR /usr/local/share/ca-certificates/cacert.org RUN wget -qP /usr/local/share/ca-certificates/cacert.org http://www.cacert.org/certs/root.crt http://www.cacert.org/certs/class3.crt \ && update-ca-certificates +# need a newer cmake +RUN apt-get purge -y cmake + +ARG CMAKE_VER=3.27.0 +RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VER}/cmake-${CMAKE_VER}-Linux-x86_64.sh \ + -q -O /tmp/cmake-install.sh \ + && chmod u+x /tmp/cmake-install.sh \ + && mkdir /opt/cmake-${CMAKE_VER} \ + && /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-${CMAKE_VER} \ + && rm /tmp/cmake-install.sh \ + && ln -s /opt/cmake-${CMAKE_VER}/bin/* /usr/local/bin + WORKDIR /home/wamr COPY . . RUN git config --global http.sslCAinfo /etc/ssl/certs/ca-certificates.crt WORKDIR /home/wamr/product-mini/platforms/linux RUN rm -rf build \ - && cmake -S . -B build -DWAMR_BUILD_WASI_NN=1 \ - -DWAMR_BUILD_WASI_NN=1 \ + && cmake -S . -B build\ + -DWAMR_BUILD_WASI_NN=1\ + -DWAMR_BUILD_WASI_NN_TFLITE=1\ -DWAMR_BUILD_WASI_NN_ENABLE_EXTERNAL_DELEGATE=1 \ -DWAMR_BUILD_WASI_NN_EXTERNAL_DELEGATE_PATH="libedgetpu.so.1.0" \ -DWAMR_BUILD_WASI_NN_ENABLE_GPU=1 \ && cmake --build build -j "$(grep -c ^processor /proc/cpuinfo)" -RUN cp /home/wamr/product-mini/platforms/linux/build/iwasm /usr/bin/iwasm \ - && cp /home/wamr/product-mini/platforms/linux/build/libiwasm.so /lib/libiwasm.so \ - && cp /home/wamr/product-mini/platforms/linux/build/libwasi-nn-*.so /lib/ +RUN cp /home/wamr/core/iwasm/libraries/wasi-nn/test/build/iwasm /run/iwasm \ + && cp /home/wamr/product-mini/platforms/linux/build/lib*.so /usr/lib +ENV LD_LIBRARY_PATH=/usr/lib WORKDIR /assets ENTRYPOINT [ "iwasm" ] diff --git a/core/iwasm/libraries/wasi-nn/test/Dockerfile.vx-delegate b/core/iwasm/libraries/wasi-nn/test/Dockerfile.vx-delegate index f078045b94..e05b30119d 100644 --- a/core/iwasm/libraries/wasi-nn/test/Dockerfile.vx-delegate +++ b/core/iwasm/libraries/wasi-nn/test/Dockerfile.vx-delegate @@ -21,6 +21,18 @@ RUN apt-get update && apt-get install -y wget ca-certificates --no-install-recom && update-ca-certificates \ && git config --global http.sslCAinfo /etc/ssl/certs/ca-certificates.crt +# need a newer cmake +RUN apt-get purge -y cmake + +ARG CMAKE_VER=3.27.0 +RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VER}/cmake-${CMAKE_VER}-Linux-x86_64.sh \ + -q -O /tmp/cmake-install.sh \ + && chmod u+x /tmp/cmake-install.sh \ + && mkdir /opt/cmake-${CMAKE_VER} \ + && /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-${CMAKE_VER} \ + && rm /tmp/cmake-install.sh \ + && ln -s /opt/cmake-${CMAKE_VER}/bin/* /usr/local/bin + # Build TensorFlow Lite VX delegate default built for x86-64 simulator WORKDIR /tmp RUN git clone https://github.com/VeriSilicon/TIM-VX.git tim-vx \ @@ -89,7 +101,6 @@ ENV VSIMULATOR_CONFIG=czl ENV LD_LIBRARY_PATH=/tmp/tim-vx/prebuilt-sdk/x86_64_linux/lib:/usr/local/lib:/lib/x86_64-linux-gnu/:/lib64/:/usr/lib:$LD_LIBRARY_PATH - # Build WASI-NN WORKDIR /home/wamr @@ -102,12 +113,14 @@ RUN cmake \ -DCMAKE_LIBRARY_PATH=${CMAKE_LIBRARY_PATH}:/usr/local/lib/ \ -DCMAKE_INCLUDE_PATH=${CMAKE_INCLUDE_PATH}:/usr/local/include/ \ -DWAMR_BUILD_WASI_NN=1 \ + -DWAMR_BUILD_WASI_NN_TFLITE=1\ -DWAMR_BUILD_WASI_NN_ENABLE_EXT=1 \ -DWASI_NN_EXT_DELEGATE_PATH="/usr/lib/libvx_delegate.so" \ .. RUN make -j "$(grep -c ^processor /proc/cpuinfo)" -RUN cp /home/wamr/core/iwasm/libraries/wasi-nn/test/build/iwasm /run/iwasm +RUN cp /home/wamr/core/iwasm/libraries/wasi-nn/test/build/iwasm /run/iwasm \ + && cp /home/wamr/product-mini/platforms/linux/build/lib*.so /usr/lib ENTRYPOINT [ "/run/iwasm" ] diff --git a/core/iwasm/libraries/wasi-nn/test/build.sh b/core/iwasm/libraries/wasi-nn/test/build.sh index da6cfa5f8e..dda400f161 100755 --- a/core/iwasm/libraries/wasi-nn/test/build.sh +++ b/core/iwasm/libraries/wasi-nn/test/build.sh @@ -8,9 +8,9 @@ CURR_PATH=$(cd $(dirname $0) && pwd -P) # WASM application that uses WASI-NN /opt/wasi-sdk/bin/clang \ + --target=wasm32-wasi \ + -DNN_LOG_LEVEL=1 \ -Wl,--allow-undefined \ - -Wl,--strip-all,--no-entry \ - --sysroot=/opt/wasi-sdk/share/wasi-sysroot \ -I../include -I../src/utils \ -o test_tensorflow.wasm \ test_tensorflow.c utils.c @@ -28,9 +28,9 @@ python3 sum.py cd ${CURR_PATH} /opt/wasi-sdk/bin/clang \ + --target=wasm32-wasi \ + -DNN_LOG_LEVEL=1 \ -Wl,--allow-undefined \ - -Wl,--strip-all,--no-entry \ - --sysroot=/opt/wasi-sdk/share/wasi-sysroot \ -I../include -I../src/utils \ -o test_tensorflow_quantized.wasm \ test_tensorflow_quantized.c utils.c diff --git a/core/iwasm/libraries/wasi-nn/test/requirements.txt b/core/iwasm/libraries/wasi-nn/test/requirements.txt index 177c22c19f..1643b91b00 100644 --- a/core/iwasm/libraries/wasi-nn/test/requirements.txt +++ b/core/iwasm/libraries/wasi-nn/test/requirements.txt @@ -1,2 +1,2 @@ tensorflow==2.12.1 -numpy==1.26.4 +numpy==1.24.4 diff --git a/core/iwasm/libraries/wasi-nn/test/utils.c b/core/iwasm/libraries/wasi-nn/test/utils.c index c499adc5b9..9e43ec9854 100644 --- a/core/iwasm/libraries/wasi-nn/test/utils.c +++ b/core/iwasm/libraries/wasi-nn/test/utils.c @@ -5,6 +5,7 @@ #include "utils.h" #include "logger.h" +#include "wasi_nn.h" #include #include @@ -57,7 +58,7 @@ wasm_load(char *model_name, graph *g, execution_target target) wasi_nn_error wasm_load_by_name(const char *model_name, graph *g) { - wasm_nn_error res = load_by_name(model_name, g); + wasi_nn_error res = load_by_name(model_name, g); return res; } diff --git a/core/shared/platform/windows/platform_internal.h b/core/shared/platform/windows/platform_internal.h index ed021a9aa1..8ff541016a 100644 --- a/core/shared/platform/windows/platform_internal.h +++ b/core/shared/platform/windows/platform_internal.h @@ -6,6 +6,12 @@ #ifndef _PLATFORM_INTERNAL_H #define _PLATFORM_INTERNAL_H +/* + * Suppress the noisy warnings: + * winbase.h: warning C5105: macro expansion producing 'defined' has + * undefined behavior + */ +#pragma warning(disable : 5105) #include #include #include @@ -168,12 +174,13 @@ typedef struct windows_dir_stream { windows_handle *handle; } windows_dir_stream; -typedef windows_handle *os_file_handle; typedef windows_dir_stream *os_dir_stream; -#if WASM_ENABLE_UVWASI != 1 +#if WASM_ENABLE_UVWASI == 0 +typedef windows_handle *os_file_handle; typedef HANDLE os_raw_file_handle; #else +typedef uint32_t os_file_handle; typedef uint32_t os_raw_file_handle; #endif @@ -190,7 +197,11 @@ typedef uint32_t os_raw_file_handle; static inline os_file_handle os_get_invalid_handle(void) { +#if WASM_ENABLE_UVWASI == 0 return NULL; +#else + return -1; +#endif } #ifdef __cplusplus diff --git a/core/shared/platform/windows/shared_platform.cmake b/core/shared/platform/windows/shared_platform.cmake index 502a8a2ed9..c2d74463fb 100644 --- a/core/shared/platform/windows/shared_platform.cmake +++ b/core/shared/platform/windows/shared_platform.cmake @@ -15,6 +15,9 @@ file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1) list(REMOVE_ITEM source_all ${PLATFORM_SHARED_DIR}/win_file.c) +elseif (WAMR_BUILD_LIBC_UVWASI EQUAL 1) + # uvwasi doesn't need to compile win_file.c + list(REMOVE_ITEM source_all ${PLATFORM_SHARED_DIR}/win_file.c) else() include (${CMAKE_CURRENT_LIST_DIR}/../common/libc-util/platform_common_libc_util.cmake) set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE}) diff --git a/core/shared/platform/windows/win_clock.c b/core/shared/platform/windows/win_clock.c index c96bdfb3b4..826004f7c0 100644 --- a/core/shared/platform/windows/win_clock.c +++ b/core/shared/platform/windows/win_clock.c @@ -10,6 +10,10 @@ #define NANOSECONDS_PER_SECOND 1000000000ULL #define NANOSECONDS_PER_TICK 100 +extern NTSTATUS +NtQueryTimerResolution(PULONG MinimumResolution, PULONG MaximumResolution, + PULONG CurrentResolution); + static __wasi_errno_t calculate_monotonic_clock_frequency(uint64 *out_frequency) { @@ -140,4 +144,4 @@ os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision, default: return __WASI_EINVAL; } -} \ No newline at end of file +} diff --git a/core/shared/platform/windows/win_socket.c b/core/shared/platform/windows/win_socket.c index b19e5b0976..8d61c45ccc 100644 --- a/core/shared/platform/windows/win_socket.c +++ b/core/shared/platform/windows/win_socket.c @@ -182,8 +182,8 @@ os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr, (*sock)->type = windows_handle_type_socket; (*sock)->access_mode = windows_access_mode_read | windows_access_mode_write; (*sock)->fdflags = 0; - (*sock)->raw.socket = - accept(server_sock->raw.socket, (struct sockaddr *)&addr_tmp, &len); + (*sock)->raw.socket = accept(server_sock->raw.socket, + (struct sockaddr *)&addr_tmp, (int *)&len); if ((*sock)->raw.socket == INVALID_SOCKET) { BH_FREE(*sock); diff --git a/core/shared/platform/windows/win_util.h b/core/shared/platform/windows/win_util.h index 033c393b59..7fda508c72 100644 --- a/core/shared/platform/windows/win_util.h +++ b/core/shared/platform/windows/win_util.h @@ -7,7 +7,13 @@ #define _WIN_UTIL_H #include "platform_wasi_types.h" -#include "windows.h" +/* + * Suppress the noisy warnings: + * winbase.h: warning C5105: macro expansion producing 'defined' has + * undefined behavior + */ +#pragma warning(disable : 5105) +#include __wasi_timestamp_t convert_filetime_to_wasi_timestamp(LPFILETIME filetime); @@ -23,4 +29,4 @@ convert_windows_error_code(DWORD windows_error_code); __wasi_errno_t convert_winsock_error_code(int error_code); -#endif /* end of _WIN_UTIL_H */ \ No newline at end of file +#endif /* end of _WIN_UTIL_H */ diff --git a/product-mini/platforms/windows/CMakeLists.txt b/product-mini/platforms/windows/CMakeLists.txt index 02aa3f31b4..40e925b16a 100644 --- a/product-mini/platforms/windows/CMakeLists.txt +++ b/product-mini/platforms/windows/CMakeLists.txt @@ -52,9 +52,9 @@ if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN) set (WAMR_BUILD_LIBC_BUILTIN 1) endif () -if (NOT DEFINED WAMR_BUILD_LIBC_UVWASI) - # Enable libc uvwasi support by default - set (WAMR_BUILD_LIBC_UVWASI 1) +if (NOT DEFINED WAMR_BUILD_LIBC_WASI) + # Enable libc wasi support by default + set (WAMR_BUILD_LIBC_WASI 1) endif () if (NOT DEFINED WAMR_BUILD_FAST_INTERP) diff --git a/tests/wamr-test-suites/spec-test-script/memory64_ignore_cases.patch b/tests/wamr-test-suites/spec-test-script/memory64_ignore_cases.patch index 5e7afd9d18..afd0536d9e 100644 --- a/tests/wamr-test-suites/spec-test-script/memory64_ignore_cases.patch +++ b/tests/wamr-test-suites/spec-test-script/memory64_ignore_cases.patch @@ -1,5 +1,5 @@ diff --git a/test/core/address.wast b/test/core/address.wast -index 8e52030..de0d0cb 100644 +index 8e52030e..de0d0cb9 100644 --- a/test/core/address.wast +++ b/test/core/address.wast @@ -210,7 +210,7 @@ @@ -12,7 +12,7 @@ index 8e52030..de0d0cb 100644 "(memory 1)" "(func (drop (i32.load offset=4294967296 (i32.const 0))))" diff --git a/test/core/binary.wast b/test/core/binary.wast -index 4090b2c..18f66b4 100644 +index 4090b2cd..18f66b42 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -206,7 +206,7 @@ @@ -70,7 +70,7 @@ index 4090b2c..18f66b4 100644 ;; Start section (module binary diff --git a/test/core/data.wast b/test/core/data.wast -index 4f339be..0b5b3e6 100644 +index 4f339bed..0b5b3e6b 100644 --- a/test/core/data.wast +++ b/test/core/data.wast @@ -306,9 +306,10 @@ @@ -124,7 +124,7 @@ index 4f339be..0b5b3e6 100644 ;; Invalid offsets diff --git a/test/core/elem.wast b/test/core/elem.wast -index 575ecef..dd1106c 100644 +index 575ecef8..dd1106c7 100644 --- a/test/core/elem.wast +++ b/test/core/elem.wast @@ -562,6 +562,7 @@ @@ -151,7 +151,7 @@ index 575ecef..dd1106c 100644 (assert_return (invoke $module1 "call-9") (i32.const 70)) +;) diff --git a/test/core/global.wast b/test/core/global.wast -index e40a305..8f8f25b 100644 +index e40a305f..8f8f25bb 100644 --- a/test/core/global.wast +++ b/test/core/global.wast @@ -328,10 +328,12 @@ @@ -168,7 +168,7 @@ index e40a305..8f8f25b 100644 (assert_invalid (module (global (import "test" "global-i32") i32) (global i32 (global.get 0) (global.get 0))) diff --git a/test/core/if.wast b/test/core/if.wast -index 2ea45f6..b6dd504 100644 +index 2ea45f6f..b6dd5044 100644 --- a/test/core/if.wast +++ b/test/core/if.wast @@ -527,11 +527,12 @@ @@ -199,7 +199,7 @@ index 2ea45f6..b6dd504 100644 (assert_malformed (module quote diff --git a/test/core/imports.wast b/test/core/imports.wast -index 69f76a0..a3844c6 100644 +index 69f76a0b..a3844c65 100644 --- a/test/core/imports.wast +++ b/test/core/imports.wast @@ -572,6 +572,7 @@ @@ -219,7 +219,7 @@ index 69f76a0..a3844c6 100644 ;; Syntax errors diff --git a/test/core/linking.wast b/test/core/linking.wast -index 994e0f4..d0bfb5f 100644 +index 994e0f49..d0bfb5f6 100644 --- a/test/core/linking.wast +++ b/test/core/linking.wast @@ -64,6 +64,7 @@ @@ -376,7 +376,7 @@ index 994e0f4..d0bfb5f 100644 (assert_return (invoke $Ms "get table[0]") (i32.const 0xdead)) +;) diff --git a/test/core/memory.wast b/test/core/memory.wast -index 1dd5b84..497b69f 100644 +index 1dd5b845..497b69fc 100644 --- a/test/core/memory.wast +++ b/test/core/memory.wast @@ -76,17 +76,17 @@ @@ -404,7 +404,7 @@ index 1dd5b84..497b69f 100644 (module diff --git a/test/core/ref_func.wast b/test/core/ref_func.wast -index adb5cb7..590f626 100644 +index adb5cb78..590f6262 100644 --- a/test/core/ref_func.wast +++ b/test/core/ref_func.wast @@ -4,7 +4,8 @@ @@ -417,8 +417,65 @@ index adb5cb7..590f626 100644 (func $g (param $x i32) (result i32) (i32.add (local.get $x) (i32.const 1)) ) +diff --git a/test/core/table.wast b/test/core/table.wast +index 1b6afe9b..45dd1145 100644 +--- a/test/core/table.wast ++++ b/test/core/table.wast +@@ -8,16 +8,20 @@ + (module (table 0 65536 funcref)) + (module (table 0 0xffff_ffff funcref)) + ++(; TODO: wabt not unsupported gc yet + (module (table 1 (ref null func))) + (module (table 1 (ref null extern))) + (module (table 1 (ref null $t)) (type $t (func))) ++;) + + (module (table 0 funcref) (table 0 funcref)) + (module (table (import "spectest" "table") 0 funcref) (table 0 funcref)) + ++(; TODO: wabt not unsupported gc yet + (module (table 0 funcref (ref.null func))) + (module (table 1 funcref (ref.null func))) + (module (table 1 (ref null func) (ref.null func))) ++;) + + (assert_invalid (module (elem (i32.const 0))) "unknown table") + (assert_invalid (module (elem (i32.const 0) $f) (func $f)) "unknown table") +@@ -31,6 +35,7 @@ + "size minimum must not be greater than maximum" + ) + ++(; TODO: wabt not unsupported gc yet + (assert_invalid + (module quote "(table 0x1_0000_0000 funcref)") + "table size must be at most 2^32-1" +@@ -43,6 +48,7 @@ + (module quote "(table 0 0x1_0000_0000 funcref)") + "table size must be at most 2^32-1" + ) ++;) + + ;; Same as above but with i64 index types + +@@ -71,6 +77,7 @@ + (assert_invalid (module (elem (i32.const 0))) "unknown table") + (assert_invalid (module (elem (i32.const 0) $f) (func $f)) "unknown table") + ++(; TODO: wabt not unsupported gc yet + (assert_invalid + (module (table 1 (ref null func) (i32.const 0))) + "type mismatch" +@@ -159,6 +166,7 @@ + ) + "type mismatch" + ) ++;) + + + ;; Duplicate table identifiers diff --git a/test/core/table_copy.wast b/test/core/table_copy.wast -index 380e84e..f37e745 100644 +index 613fc529..abeca22c 100644 --- a/test/core/table_copy.wast +++ b/test/core/table_copy.wast @@ -14,11 +14,12 @@ @@ -728,8 +785,46 @@ index 380e84e..f37e745 100644 (table $t0 30 30 funcref) (table $t1 30 30 funcref) (elem (table $t1) (i32.const 2) func 3 1 4 1) +diff --git a/test/core/table_grow.wast b/test/core/table_grow.wast +index e0872d78..6a84f239 100644 +--- a/test/core/table_grow.wast ++++ b/test/core/table_grow.wast +@@ -147,19 +147,20 @@ + ) + (register "grown-table" $Tgt) + (assert_return (invoke $Tgt "grow") (i32.const 1)) ;; now size is 2 +-(module $Tgit1 +- ;; imported table limits should match, because external table size is 2 now +- (table (export "table") (import "grown-table" "table") 2 funcref) +- (func (export "grow") (result i32) (table.grow (ref.null func) (i32.const 1))) +-) +-(register "grown-imported-table" $Tgit1) +-(assert_return (invoke $Tgit1 "grow") (i32.const 2)) ;; now size is 3 +-(module $Tgit2 +- ;; imported table limits should match, because external table size is 3 now +- (import "grown-imported-table" "table" (table 3 funcref)) +- (func (export "size") (result i32) (table.size)) +-) +-(assert_return (invoke $Tgit2 "size") (i32.const 3)) ++;; TODO: No dynnamic linking yet ++;; (module $Tgit1 ++;; ;; imported table limits should match, because external table size is 2 now ++;; (table (export "table") (import "grown-table" "table") 2 funcref) ++;; (func (export "grow") (result i32) (table.grow (ref.null func) (i32.const 1))) ++;; ) ++;; (register "grown-imported-table" $Tgit1) ++;; (assert_return (invoke $Tgit1 "grow") (i32.const 2)) ;; now size is 3 ++;; (module $Tgit2 ++;; ;; imported table limits should match, because external table size is 3 now ++;; (import "grown-imported-table" "table" (table 3 funcref)) ++;; (func (export "size") (result i32) (table.size)) ++;; ) ++;; (assert_return (invoke $Tgit2 "size") (i32.const 3)) + + + ;; Type errors diff --git a/test/core/table_init.wast b/test/core/table_init.wast -index 0b2d26f..bdab6a0 100644 +index 5c3679ab..76782794 100644 --- a/test/core/table_init.wast +++ b/test/core/table_init.wast @@ -14,11 +14,12 @@ @@ -749,8 +844,8 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) -@@ -72,11 +73,12 @@ + (table $t2 i64 30 30 funcref) +@@ -73,11 +74,12 @@ (module (type (func (result i32))) ;; type #0 @@ -767,8 +862,8 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) -@@ -130,11 +132,12 @@ + (table $t2 i64 30 30 funcref) +@@ -132,11 +134,12 @@ (module (type (func (result i32))) ;; type #0 @@ -785,8 +880,8 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) -@@ -196,11 +199,12 @@ + (table $t2 i64 30 30 funcref) +@@ -199,11 +202,12 @@ (module (type (func (result i32))) ;; type #0 @@ -803,8 +898,8 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) -@@ -254,11 +258,12 @@ + (table $t2 i64 30 30 funcref) +@@ -258,11 +262,12 @@ (module (type (func (result i32))) ;; type #0 @@ -821,8 +916,8 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) -@@ -312,11 +317,12 @@ + (table $t2 i64 30 30 funcref) +@@ -317,11 +322,12 @@ (module (type (func (result i32))) ;; type #0 @@ -839,9 +934,63 @@ index 0b2d26f..bdab6a0 100644 + (func (result i32) (i32.const 4)) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) + (table $t2 i64 30 30 funcref) +@@ -384,11 +390,12 @@ + + (module + (type (func (result i32))) ;; type #0 +- (import "a" "ef0" (func (result i32))) ;; index 0 +- (import "a" "ef1" (func (result i32))) +- (import "a" "ef2" (func (result i32))) +- (import "a" "ef3" (func (result i32))) +- (import "a" "ef4" (func (result i32))) ;; index 4 ++ ;; aot mode does not support module linking ++ (func (result i32) (i32.const 0)) ;; index 0 ++ (func (result i32) (i32.const 1)) ++ (func (result i32) (i32.const 2)) ++ (func (result i32) (i32.const 3)) ++ (func (result i32) (i32.const 4)) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) +@@ -443,11 +450,12 @@ + + (module + (type (func (result i32))) ;; type #0 +- (import "a" "ef0" (func (result i32))) ;; index 0 +- (import "a" "ef1" (func (result i32))) +- (import "a" "ef2" (func (result i32))) +- (import "a" "ef3" (func (result i32))) +- (import "a" "ef4" (func (result i32))) ;; index 4 ++ ;; aot mode does not support module linking ++ (func (result i32) (i32.const 0)) ;; index 0 ++ (func (result i32) (i32.const 1)) ++ (func (result i32) (i32.const 2)) ++ (func (result i32) (i32.const 3)) ++ (func (result i32) (i32.const 4)) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) +@@ -502,11 +510,12 @@ + + (module + (type (func (result i32))) ;; type #0 +- (import "a" "ef0" (func (result i32))) ;; index 0 +- (import "a" "ef1" (func (result i32))) +- (import "a" "ef2" (func (result i32))) +- (import "a" "ef3" (func (result i32))) +- (import "a" "ef4" (func (result i32))) ;; index 4 ++ ;; aot mode does not support module linking ++ (func (result i32) (i32.const 0)) ;; index 0 ++ (func (result i32) (i32.const 1)) ++ (func (result i32) (i32.const 2)) ++ (func (result i32) (i32.const 3)) ++ (func (result i32) (i32.const 4)) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) diff --git a/test/core/unreached-valid.wast b/test/core/unreached-valid.wast -index b7ebabf..4f2abfb 100644 +index b7ebabfd..4f2abfbf 100644 --- a/test/core/unreached-valid.wast +++ b/test/core/unreached-valid.wast @@ -46,6 +46,7 @@ diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index 87e1568658..4893bb65dd 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -375,7 +375,7 @@ function sightglass_test() function setup_wabt() { - WABT_VERSION=1.0.34 + WABT_VERSION=1.0.36 if [ ${WABT_BINARY_RELEASE} == "YES" ]; then echo "download a binary release and install" local WAT2WASM=${WORK_DIR}/wabt/out/gcc/Release/wat2wasm @@ -384,7 +384,7 @@ function setup_wabt() cosmopolitan) ;; linux) - WABT_PLATFORM=ubuntu + WABT_PLATFORM=ubuntu-20.04 ;; darwin) WABT_PLATFORM=macos-12 @@ -502,6 +502,8 @@ function spec_test() # Reset to commit: "Merge remote-tracking branch 'upstream/main' into merge2" git reset --hard 48e69f394869c55b7bbe14ac963c09f4605490b6 git checkout 044d0d2e77bdcbe891f7e0b9dd2ac01d56435f0b -- test/core/elem.wast test/core/data.wast + # Patch table64 extension + git checkout 940398cd4823522a9b36bec4984be4b153dedb81 -- test/core/call_indirect.wast test/core/table.wast test/core/table_copy.wast test/core/table_copy_mixed.wast test/core/table_fill.wast test/core/table_get.wast test/core/table_grow.wast test/core/table_init.wast test/core/table_set.wast test/core/table_size.wast git apply ../../spec-test-script/memory64_ignore_cases.patch || exit 1 elif [[ ${ENABLE_MULTI_MEMORY} == 1 ]]; then echo "checkout spec for multi memory proposal" diff --git a/wamr-compiler/CMakeLists.txt b/wamr-compiler/CMakeLists.txt index 2ab0462b20..34e920a3bc 100644 --- a/wamr-compiler/CMakeLists.txt +++ b/wamr-compiler/CMakeLists.txt @@ -223,24 +223,14 @@ include_directories (${SHARED_DIR}/include enable_language (ASM) -if (NOT MINGW AND NOT MSVC) - if ((NOT DEFINED WAMR_BUILD_LIBC_WASI) AND (NOT DEFINED WAMR_BUILD_LIBC_UVWASI)) - set (WAMR_BUILD_LIBC_WASI 1) - endif () - - if ((WAMR_BUILD_LIBC_WASI EQUAL 1) AND (WAMR_BUILD_LIBC_UVWASI EQUAL 1)) - message (WARNING "-- pick WAMR_BULID_LIBC_UVWASI when both are enabled") - set (WAMR_BUILD_LIBC_WASI 0) - endif () -else () - if (NOT DEFINED WAMR_BUILD_LIBC_UVWASI) - set (WAMR_BUILD_LIBC_UVWASI 1) - endif () +if ((NOT DEFINED WAMR_BUILD_LIBC_WASI) AND (NOT DEFINED WAMR_BUILD_LIBC_UVWASI)) + # Enable WAMR_BUILD_LIBC_WASI if both are not set + set (WAMR_BUILD_LIBC_WASI 1) +endif () - if (WAMR_BUILD_LIBC_WASI EQUAL 1) - message (WARNING "-- don't accept WAMR_BUILD_LIBC_WASI=1 on MINGW or MSVC") - set (WAMR_BUILD_LIBC_WASI 0) - endif () +if ((WAMR_BUILD_LIBC_WASI EQUAL 1) AND (WAMR_BUILD_LIBC_UVWASI EQUAL 1)) + message (WARNING "-- pick WAMR_BULID_LIBC_UVWASI when both are enabled") + set (WAMR_BUILD_LIBC_WASI 0) endif () if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN) @@ -308,6 +298,16 @@ if (WAMR_BUILD_LIBC_WASI EQUAL 1) include (${IWASM_DIR}/libraries/libc-wasi/libc_wasi.cmake) endif () +if (WAMR_BUILD_LIBC_WASI EQUAL 1) + # Enable _Static_assert + set (CMAKE_C_STANDARD 11) + if (MSVC) + add_compile_options(/experimental:c11atomics) + endif() +else() + set (CMAKE_C_STANDARD 99) +endif() + if (WAMR_BUILD_LIB_PTHREAD EQUAL 1) include (${IWASM_DIR}/libraries/lib-pthread/lib_pthread.cmake) endif ()