Merge branch main into dev/memory64

This commit is contained in:
Wenyong Huang 2024-04-02 14:46:49 +08:00
commit fb927ab831
29 changed files with 878 additions and 468 deletions

View File

@ -33,10 +33,16 @@ jobs:
- name: checkout - name: checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: install dependencies - name: install dependencies for non macos-14
if: inputs.os != 'macos-14'
run: /usr/bin/env python3 -m pip install -r requirements.txt run: /usr/bin/env python3 -m pip install -r requirements.txt
working-directory: build-scripts working-directory: build-scripts
- name: install dependencies for macos-14
if: inputs.os == 'macos-14'
run: /usr/bin/env python3 -m pip install -r requirements.txt --break-system-packages
working-directory: build-scripts
- name: retrive the last commit ID - name: retrive the last commit ID
id: get_last_commit id: get_last_commit
run: echo "last_commit=$(GH_TOKEN=${{ secrets.GITHUB_TOKEN }} /usr/bin/env python3 ./build_llvm.py --llvm-ver)" >> $GITHUB_OUTPUT run: echo "last_commit=$(GH_TOKEN=${{ secrets.GITHUB_TOKEN }} /usr/bin/env python3 ./build_llvm.py --llvm-ver)" >> $GITHUB_OUTPUT

View File

@ -21,6 +21,7 @@ on:
jobs: jobs:
analyze: analyze:
if: github.repository == 'bytecodealliance/wasm-micro-runtime'
name: Analyze name: Analyze
# Runner size impacts CodeQL analysis time. To learn more, please see: # Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql # - https://gh.io/recommended-hardware-resources-for-running-codeql

View File

@ -538,3 +538,19 @@ else ()
# Disable quick aot/jit entries for interp and fast-jit # Disable quick aot/jit entries for interp and fast-jit
add_definitions (-DWASM_ENABLE_QUICK_AOT_ENTRY=0) add_definitions (-DWASM_ENABLE_QUICK_AOT_ENTRY=0)
endif () endif ()
if (WAMR_BUILD_AOT EQUAL 1)
if (NOT DEFINED WAMR_BUILD_AOT_INTRINSICS)
# Enable aot intrinsics by default
set (WAMR_BUILD_AOT_INTRINSICS 1)
endif ()
if (WAMR_BUILD_AOT_INTRINSICS EQUAL 1)
add_definitions (-DWASM_ENABLE_AOT_INTRINSICS=1)
message (" AOT intrinsics enabled")
else ()
add_definitions (-DWASM_ENABLE_AOT_INTRINSICS=0)
message (" AOT intrinsics disabled")
endif ()
else ()
# Disable aot intrinsics for interp, fast-jit and llvm-jit
add_definitions (-DWASM_ENABLE_AOT_INTRINSICS=0)
endif ()

View File

@ -570,6 +570,14 @@
#define WASM_ENABLE_QUICK_AOT_ENTRY 1 #define WASM_ENABLE_QUICK_AOT_ENTRY 1
#endif #endif
/* Support AOT intrinsic functions which can be called from the AOT code
when `--disable-llvm-intrinsics` flag or
`--enable-builtin-intrinsics=<intr1,intr2,...>` is used by wamrc to
generate the AOT file */
#ifndef WASM_ENABLE_AOT_INTRINSICS
#define WASM_ENABLE_AOT_INTRINSICS 1
#endif
/* Disable memory64 by default */ /* Disable memory64 by default */
#ifndef WASM_ENABLE_MEMORY64 #ifndef WASM_ENABLE_MEMORY64
#define WASM_ENABLE_MEMORY64 0 #define WASM_ENABLE_MEMORY64 0

View File

@ -5,86 +5,6 @@
#include "aot_intrinsic.h" #include "aot_intrinsic.h"
typedef struct {
const char *llvm_intrinsic;
const char *native_intrinsic;
uint64 flag;
} aot_intrinsic;
/* clang-format off */
static const aot_intrinsic g_intrinsic_mapping[] = {
{ "llvm.experimental.constrained.fadd.f32", "aot_intrinsic_fadd_f32", AOT_INTRINSIC_FLAG_F32_FADD },
{ "llvm.experimental.constrained.fadd.f64", "aot_intrinsic_fadd_f64", AOT_INTRINSIC_FLAG_F64_FADD },
{ "llvm.experimental.constrained.fsub.f32", "aot_intrinsic_fsub_f32", AOT_INTRINSIC_FLAG_F32_FSUB },
{ "llvm.experimental.constrained.fsub.f64", "aot_intrinsic_fsub_f64", AOT_INTRINSIC_FLAG_F64_FSUB },
{ "llvm.experimental.constrained.fmul.f32", "aot_intrinsic_fmul_f32", AOT_INTRINSIC_FLAG_F32_FMUL },
{ "llvm.experimental.constrained.fmul.f64", "aot_intrinsic_fmul_f64", AOT_INTRINSIC_FLAG_F64_FMUL },
{ "llvm.experimental.constrained.fdiv.f32", "aot_intrinsic_fdiv_f32", AOT_INTRINSIC_FLAG_F32_FDIV },
{ "llvm.experimental.constrained.fdiv.f64", "aot_intrinsic_fdiv_f64", AOT_INTRINSIC_FLAG_F64_FDIV },
{ "llvm.fabs.f32", "aot_intrinsic_fabs_f32", AOT_INTRINSIC_FLAG_F32_FABS },
{ "llvm.fabs.f64", "aot_intrinsic_fabs_f64", AOT_INTRINSIC_FLAG_F64_FABS },
{ "llvm.ceil.f32", "aot_intrinsic_ceil_f32", AOT_INTRINSIC_FLAG_F32_CEIL },
{ "llvm.ceil.f64", "aot_intrinsic_ceil_f64", AOT_INTRINSIC_FLAG_F64_CEIL },
{ "llvm.floor.f32", "aot_intrinsic_floor_f32", AOT_INTRINSIC_FLAG_F32_FLOOR },
{ "llvm.floor.f64", "aot_intrinsic_floor_f64", AOT_INTRINSIC_FLAG_F64_FLOOR },
{ "llvm.trunc.f32", "aot_intrinsic_trunc_f32", AOT_INTRINSIC_FLAG_F32_TRUNC },
{ "llvm.trunc.f64", "aot_intrinsic_trunc_f64", AOT_INTRINSIC_FLAG_F64_TRUNC },
{ "llvm.rint.f32", "aot_intrinsic_rint_f32", AOT_INTRINSIC_FLAG_F32_RINT },
{ "llvm.rint.f64", "aot_intrinsic_rint_f64", AOT_INTRINSIC_FLAG_F64_RINT },
{ "llvm.sqrt.f32", "aot_intrinsic_sqrt_f32", AOT_INTRINSIC_FLAG_F32_SQRT },
{ "llvm.sqrt.f64", "aot_intrinsic_sqrt_f64", AOT_INTRINSIC_FLAG_F64_SQRT },
{ "llvm.copysign.f32", "aot_intrinsic_copysign_f32", AOT_INTRINSIC_FLAG_F32_COPYSIGN },
{ "llvm.copysign.f64", "aot_intrinsic_copysign_f64", AOT_INTRINSIC_FLAG_F64_COPYSIGN },
{ "llvm.minnum.f32", "aot_intrinsic_fmin_f32", AOT_INTRINSIC_FLAG_F32_MIN },
{ "llvm.minnum.f64", "aot_intrinsic_fmin_f64", AOT_INTRINSIC_FLAG_F64_MIN },
{ "llvm.maxnum.f32", "aot_intrinsic_fmax_f32", AOT_INTRINSIC_FLAG_F32_MAX },
{ "llvm.maxnum.f64", "aot_intrinsic_fmax_f64", AOT_INTRINSIC_FLAG_F64_MAX },
{ "llvm.ctlz.i32", "aot_intrinsic_clz_i32", AOT_INTRINSIC_FLAG_I32_CLZ },
{ "llvm.ctlz.i64", "aot_intrinsic_clz_i64", AOT_INTRINSIC_FLAG_I64_CLZ },
{ "llvm.cttz.i32", "aot_intrinsic_ctz_i32", AOT_INTRINSIC_FLAG_I32_CTZ },
{ "llvm.cttz.i64", "aot_intrinsic_ctz_i64", AOT_INTRINSIC_FLAG_I64_CTZ },
{ "llvm.ctpop.i32", "aot_intrinsic_popcnt_i32", AOT_INTRINSIC_FLAG_I32_POPCNT },
{ "llvm.ctpop.i64", "aot_intrinsic_popcnt_i64", AOT_INTRINSIC_FLAG_I64_POPCNT },
{ "f64_convert_i32_s", "aot_intrinsic_i32_to_f64", AOT_INTRINSIC_FLAG_I32_TO_F64 },
{ "f64_convert_i32_u", "aot_intrinsic_u32_to_f64", AOT_INTRINSIC_FLAG_U32_TO_F64 },
{ "f32_convert_i32_s", "aot_intrinsic_i32_to_f32", AOT_INTRINSIC_FLAG_I32_TO_F32 },
{ "f32_convert_i32_u", "aot_intrinsic_u32_to_f32", AOT_INTRINSIC_FLAG_U32_TO_F32 },
{ "f64_convert_i64_s", "aot_intrinsic_i64_to_f64", AOT_INTRINSIC_FLAG_I32_TO_F64 },
{ "f64_convert_i64_u", "aot_intrinsic_u64_to_f64", AOT_INTRINSIC_FLAG_U64_TO_F64 },
{ "f32_convert_i64_s", "aot_intrinsic_i64_to_f32", AOT_INTRINSIC_FLAG_I64_TO_F32 },
{ "f32_convert_i64_u", "aot_intrinsic_u64_to_f32", AOT_INTRINSIC_FLAG_U64_TO_F32 },
{ "i32_trunc_f32_u", "aot_intrinsic_f32_to_u32", AOT_INTRINSIC_FLAG_F32_TO_U32 },
{ "i32_trunc_f32_s", "aot_intrinsic_f32_to_i32", AOT_INTRINSIC_FLAG_F32_TO_I32 },
{ "i32_trunc_f64_u", "aot_intrinsic_f64_to_u32", AOT_INTRINSIC_FLAG_F64_TO_U32 },
{ "i32_trunc_f64_s", "aot_intrinsic_f64_to_i32", AOT_INTRINSIC_FLAG_F64_TO_I32 },
{ "i64_trunc_f64_u", "aot_intrinsic_f64_to_u64", AOT_INTRINSIC_FLAG_F64_TO_U64 },
{ "i64_trunc_f32_s", "aot_intrinsic_f32_to_i64", AOT_INTRINSIC_FLAG_F32_TO_I64 },
{ "i64_trunc_f32_u", "aot_intrinsic_f32_to_u64", AOT_INTRINSIC_FLAG_F32_TO_U64 },
{ "i64_trunc_f64_s", "aot_intrinsic_f64_to_i64", AOT_INTRINSIC_FLAG_F64_TO_I64 },
{ "f32_demote_f64", "aot_intrinsic_f64_to_f32", AOT_INTRINSIC_FLAG_F64_TO_F32 },
{ "f64_promote_f32", "aot_intrinsic_f32_to_f64", AOT_INTRINSIC_FLAG_F32_TO_F64 },
{ "f32_cmp", "aot_intrinsic_f32_cmp", AOT_INTRINSIC_FLAG_F32_CMP },
{ "f64_cmp", "aot_intrinsic_f64_cmp", AOT_INTRINSIC_FLAG_F64_CMP },
{ "i32.const", NULL, AOT_INTRINSIC_FLAG_I32_CONST },
{ "i64.const", NULL, AOT_INTRINSIC_FLAG_I64_CONST },
{ "f32.const", NULL, AOT_INTRINSIC_FLAG_F32_CONST },
{ "f64.const", NULL, AOT_INTRINSIC_FLAG_F64_CONST },
{ "i64.div_s", "aot_intrinsic_i64_div_s", AOT_INTRINSIC_FLAG_I64_DIV_S},
{ "i32.div_s", "aot_intrinsic_i32_div_s", AOT_INTRINSIC_FLAG_I32_DIV_S},
{ "i32.div_u", "aot_intrinsic_i32_div_u", AOT_INTRINSIC_FLAG_I32_DIV_U},
{ "i32.rem_s", "aot_intrinsic_i32_rem_s", AOT_INTRINSIC_FLAG_I32_REM_S},
{ "i32.rem_u", "aot_intrinsic_i32_rem_u", AOT_INTRINSIC_FLAG_I32_REM_U},
{ "i64.div_u", "aot_intrinsic_i64_div_u", AOT_INTRINSIC_FLAG_I64_DIV_U},
{ "i64.rem_s", "aot_intrinsic_i64_rem_s", AOT_INTRINSIC_FLAG_I64_REM_S},
{ "i64.rem_u", "aot_intrinsic_i64_rem_u", AOT_INTRINSIC_FLAG_I64_REM_U},
{ "i64.or", "aot_intrinsic_i64_bit_or", AOT_INTRINSIC_FLAG_I64_BIT_OR},
{ "i64.and", "aot_intrinsic_i64_bit_and", AOT_INTRINSIC_FLAG_I64_BIT_AND},
};
/* clang-format on */
static const uint32 g_intrinsic_count =
sizeof(g_intrinsic_mapping) / sizeof(aot_intrinsic);
float32 float32
aot_intrinsic_fadd_f32(float32 a, float32 b) aot_intrinsic_fadd_f32(float32 a, float32 b)
{ {
@ -565,6 +485,88 @@ aot_intrinsic_i64_bit_and(uint64 l, uint64 r)
return l & r; return l & r;
} }
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
typedef struct {
const char *llvm_intrinsic;
const char *native_intrinsic;
uint64 flag;
} aot_intrinsic;
/* clang-format off */
static const aot_intrinsic g_intrinsic_mapping[] = {
{ "llvm.experimental.constrained.fadd.f32", "aot_intrinsic_fadd_f32", AOT_INTRINSIC_FLAG_F32_FADD },
{ "llvm.experimental.constrained.fadd.f64", "aot_intrinsic_fadd_f64", AOT_INTRINSIC_FLAG_F64_FADD },
{ "llvm.experimental.constrained.fsub.f32", "aot_intrinsic_fsub_f32", AOT_INTRINSIC_FLAG_F32_FSUB },
{ "llvm.experimental.constrained.fsub.f64", "aot_intrinsic_fsub_f64", AOT_INTRINSIC_FLAG_F64_FSUB },
{ "llvm.experimental.constrained.fmul.f32", "aot_intrinsic_fmul_f32", AOT_INTRINSIC_FLAG_F32_FMUL },
{ "llvm.experimental.constrained.fmul.f64", "aot_intrinsic_fmul_f64", AOT_INTRINSIC_FLAG_F64_FMUL },
{ "llvm.experimental.constrained.fdiv.f32", "aot_intrinsic_fdiv_f32", AOT_INTRINSIC_FLAG_F32_FDIV },
{ "llvm.experimental.constrained.fdiv.f64", "aot_intrinsic_fdiv_f64", AOT_INTRINSIC_FLAG_F64_FDIV },
{ "llvm.fabs.f32", "aot_intrinsic_fabs_f32", AOT_INTRINSIC_FLAG_F32_FABS },
{ "llvm.fabs.f64", "aot_intrinsic_fabs_f64", AOT_INTRINSIC_FLAG_F64_FABS },
{ "llvm.ceil.f32", "aot_intrinsic_ceil_f32", AOT_INTRINSIC_FLAG_F32_CEIL },
{ "llvm.ceil.f64", "aot_intrinsic_ceil_f64", AOT_INTRINSIC_FLAG_F64_CEIL },
{ "llvm.floor.f32", "aot_intrinsic_floor_f32", AOT_INTRINSIC_FLAG_F32_FLOOR },
{ "llvm.floor.f64", "aot_intrinsic_floor_f64", AOT_INTRINSIC_FLAG_F64_FLOOR },
{ "llvm.trunc.f32", "aot_intrinsic_trunc_f32", AOT_INTRINSIC_FLAG_F32_TRUNC },
{ "llvm.trunc.f64", "aot_intrinsic_trunc_f64", AOT_INTRINSIC_FLAG_F64_TRUNC },
{ "llvm.rint.f32", "aot_intrinsic_rint_f32", AOT_INTRINSIC_FLAG_F32_RINT },
{ "llvm.rint.f64", "aot_intrinsic_rint_f64", AOT_INTRINSIC_FLAG_F64_RINT },
{ "llvm.sqrt.f32", "aot_intrinsic_sqrt_f32", AOT_INTRINSIC_FLAG_F32_SQRT },
{ "llvm.sqrt.f64", "aot_intrinsic_sqrt_f64", AOT_INTRINSIC_FLAG_F64_SQRT },
{ "llvm.copysign.f32", "aot_intrinsic_copysign_f32", AOT_INTRINSIC_FLAG_F32_COPYSIGN },
{ "llvm.copysign.f64", "aot_intrinsic_copysign_f64", AOT_INTRINSIC_FLAG_F64_COPYSIGN },
{ "llvm.minnum.f32", "aot_intrinsic_fmin_f32", AOT_INTRINSIC_FLAG_F32_MIN },
{ "llvm.minnum.f64", "aot_intrinsic_fmin_f64", AOT_INTRINSIC_FLAG_F64_MIN },
{ "llvm.maxnum.f32", "aot_intrinsic_fmax_f32", AOT_INTRINSIC_FLAG_F32_MAX },
{ "llvm.maxnum.f64", "aot_intrinsic_fmax_f64", AOT_INTRINSIC_FLAG_F64_MAX },
{ "llvm.ctlz.i32", "aot_intrinsic_clz_i32", AOT_INTRINSIC_FLAG_I32_CLZ },
{ "llvm.ctlz.i64", "aot_intrinsic_clz_i64", AOT_INTRINSIC_FLAG_I64_CLZ },
{ "llvm.cttz.i32", "aot_intrinsic_ctz_i32", AOT_INTRINSIC_FLAG_I32_CTZ },
{ "llvm.cttz.i64", "aot_intrinsic_ctz_i64", AOT_INTRINSIC_FLAG_I64_CTZ },
{ "llvm.ctpop.i32", "aot_intrinsic_popcnt_i32", AOT_INTRINSIC_FLAG_I32_POPCNT },
{ "llvm.ctpop.i64", "aot_intrinsic_popcnt_i64", AOT_INTRINSIC_FLAG_I64_POPCNT },
{ "f64_convert_i32_s", "aot_intrinsic_i32_to_f64", AOT_INTRINSIC_FLAG_I32_TO_F64 },
{ "f64_convert_i32_u", "aot_intrinsic_u32_to_f64", AOT_INTRINSIC_FLAG_U32_TO_F64 },
{ "f32_convert_i32_s", "aot_intrinsic_i32_to_f32", AOT_INTRINSIC_FLAG_I32_TO_F32 },
{ "f32_convert_i32_u", "aot_intrinsic_u32_to_f32", AOT_INTRINSIC_FLAG_U32_TO_F32 },
{ "f64_convert_i64_s", "aot_intrinsic_i64_to_f64", AOT_INTRINSIC_FLAG_I32_TO_F64 },
{ "f64_convert_i64_u", "aot_intrinsic_u64_to_f64", AOT_INTRINSIC_FLAG_U64_TO_F64 },
{ "f32_convert_i64_s", "aot_intrinsic_i64_to_f32", AOT_INTRINSIC_FLAG_I64_TO_F32 },
{ "f32_convert_i64_u", "aot_intrinsic_u64_to_f32", AOT_INTRINSIC_FLAG_U64_TO_F32 },
{ "i32_trunc_f32_u", "aot_intrinsic_f32_to_u32", AOT_INTRINSIC_FLAG_F32_TO_U32 },
{ "i32_trunc_f32_s", "aot_intrinsic_f32_to_i32", AOT_INTRINSIC_FLAG_F32_TO_I32 },
{ "i32_trunc_f64_u", "aot_intrinsic_f64_to_u32", AOT_INTRINSIC_FLAG_F64_TO_U32 },
{ "i32_trunc_f64_s", "aot_intrinsic_f64_to_i32", AOT_INTRINSIC_FLAG_F64_TO_I32 },
{ "i64_trunc_f64_u", "aot_intrinsic_f64_to_u64", AOT_INTRINSIC_FLAG_F64_TO_U64 },
{ "i64_trunc_f32_s", "aot_intrinsic_f32_to_i64", AOT_INTRINSIC_FLAG_F32_TO_I64 },
{ "i64_trunc_f32_u", "aot_intrinsic_f32_to_u64", AOT_INTRINSIC_FLAG_F32_TO_U64 },
{ "i64_trunc_f64_s", "aot_intrinsic_f64_to_i64", AOT_INTRINSIC_FLAG_F64_TO_I64 },
{ "f32_demote_f64", "aot_intrinsic_f64_to_f32", AOT_INTRINSIC_FLAG_F64_TO_F32 },
{ "f64_promote_f32", "aot_intrinsic_f32_to_f64", AOT_INTRINSIC_FLAG_F32_TO_F64 },
{ "f32_cmp", "aot_intrinsic_f32_cmp", AOT_INTRINSIC_FLAG_F32_CMP },
{ "f64_cmp", "aot_intrinsic_f64_cmp", AOT_INTRINSIC_FLAG_F64_CMP },
{ "i32.const", NULL, AOT_INTRINSIC_FLAG_I32_CONST },
{ "i64.const", NULL, AOT_INTRINSIC_FLAG_I64_CONST },
{ "f32.const", NULL, AOT_INTRINSIC_FLAG_F32_CONST },
{ "f64.const", NULL, AOT_INTRINSIC_FLAG_F64_CONST },
{ "i64.div_s", "aot_intrinsic_i64_div_s", AOT_INTRINSIC_FLAG_I64_DIV_S},
{ "i32.div_s", "aot_intrinsic_i32_div_s", AOT_INTRINSIC_FLAG_I32_DIV_S},
{ "i32.div_u", "aot_intrinsic_i32_div_u", AOT_INTRINSIC_FLAG_I32_DIV_U},
{ "i32.rem_s", "aot_intrinsic_i32_rem_s", AOT_INTRINSIC_FLAG_I32_REM_S},
{ "i32.rem_u", "aot_intrinsic_i32_rem_u", AOT_INTRINSIC_FLAG_I32_REM_U},
{ "i64.div_u", "aot_intrinsic_i64_div_u", AOT_INTRINSIC_FLAG_I64_DIV_U},
{ "i64.rem_s", "aot_intrinsic_i64_rem_s", AOT_INTRINSIC_FLAG_I64_REM_S},
{ "i64.rem_u", "aot_intrinsic_i64_rem_u", AOT_INTRINSIC_FLAG_I64_REM_U},
{ "i64.or", "aot_intrinsic_i64_bit_or", AOT_INTRINSIC_FLAG_I64_BIT_OR},
{ "i64.and", "aot_intrinsic_i64_bit_and", AOT_INTRINSIC_FLAG_I64_BIT_AND},
};
/* clang-format on */
static const uint32 g_intrinsic_count =
sizeof(g_intrinsic_mapping) / sizeof(aot_intrinsic);
const char * const char *
aot_intrinsic_get_symbol(const char *llvm_intrinsic) aot_intrinsic_get_symbol(const char *llvm_intrinsic)
{ {
@ -577,8 +579,6 @@ aot_intrinsic_get_symbol(const char *llvm_intrinsic)
return NULL; return NULL;
} }
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
static void static void
add_intrinsic_capability(AOTCompContext *comp_ctx, uint64 flag) add_intrinsic_capability(AOTCompContext *comp_ctx, uint64 flag)
{ {

View File

@ -287,10 +287,10 @@ aot_intrinsic_i64_bit_or(uint64 l, uint64 r);
uint64 uint64
aot_intrinsic_i64_bit_and(uint64 l, uint64 r); aot_intrinsic_i64_bit_and(uint64 l, uint64 r);
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
const char * const char *
aot_intrinsic_get_symbol(const char *llvm_intrinsic); aot_intrinsic_get_symbol(const char *llvm_intrinsic);
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
bool bool
aot_intrinsic_check_capability(const AOTCompContext *comp_ctx, aot_intrinsic_check_capability(const AOTCompContext *comp_ctx,
const char *llvm_intrinsic); const char *llvm_intrinsic);

View File

@ -289,55 +289,6 @@ loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
return mem; return mem;
} }
static char *
const_str_set_insert(const uint8 *str, int32 len, AOTModule *module,
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
bool is_vram_word_align,
#endif
char *error_buf, uint32 error_buf_size)
{
HashMap *set = module->const_str_set;
char *c_str, *value;
/* Create const string set if it isn't created */
if (!set
&& !(set = module->const_str_set = bh_hash_map_create(
32, false, (HashFunc)wasm_string_hash,
(KeyEqualFunc)wasm_string_equal, NULL, wasm_runtime_free))) {
set_error_buf(error_buf, error_buf_size,
"create const string set failed");
return NULL;
}
/* Lookup const string set, use the string if found */
if (!(c_str = loader_malloc((uint32)len, error_buf, error_buf_size))) {
return NULL;
}
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
if (is_vram_word_align) {
bh_memcpy_wa(c_str, (uint32)len, str, (uint32)len);
}
else
#endif
{
bh_memcpy_s(c_str, len, str, (uint32)len);
}
if ((value = bh_hash_map_find(set, c_str))) {
wasm_runtime_free(c_str);
return value;
}
if (!bh_hash_map_insert(set, c_str, c_str)) {
set_error_buf(error_buf, error_buf_size,
"insert string to hash map failed");
wasm_runtime_free(c_str);
return NULL;
}
return c_str;
}
static char * static char *
load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module, load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
bool is_load_from_file_buf, bool is_load_from_file_buf,
@ -359,9 +310,9 @@ load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
} }
#if (WASM_ENABLE_WORD_ALIGN_READ != 0) #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
else if (is_vram_word_align) { else if (is_vram_word_align) {
if (!(str = const_str_set_insert((uint8 *)p, str_len, module, if (!(str = aot_const_str_set_insert((uint8 *)p, str_len, module,
is_vram_word_align, error_buf, is_vram_word_align, error_buf,
error_buf_size))) { error_buf_size))) {
goto fail; goto fail;
} }
} }
@ -378,11 +329,11 @@ load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
after loading, we must create another string and insert it after loading, we must create another string and insert it
into const string set */ into const string set */
bh_assert(p[str_len - 1] == '\0'); bh_assert(p[str_len - 1] == '\0');
if (!(str = const_str_set_insert((uint8 *)p, str_len, module, if (!(str = aot_const_str_set_insert((uint8 *)p, str_len, module,
#if (WASM_ENABLE_WORD_ALIGN_READ != 0) #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
is_vram_word_align, is_vram_word_align,
#endif #endif
error_buf, error_buf_size))) { error_buf, error_buf_size))) {
goto fail; goto fail;
} }
} }
@ -3939,6 +3890,8 @@ create_module(char *error_buf, uint32 error_buf_size)
module->module_type = Wasm_Module_AoT; module->module_type = Wasm_Module_AoT;
module->name = "";
#if WASM_ENABLE_MULTI_MODULE != 0 #if WASM_ENABLE_MULTI_MODULE != 0
module->import_module_list = &module->import_module_list_head; module->import_module_list = &module->import_module_list_head;
ret = bh_list_init(module->import_module_list); ret = bh_list_init(module->import_module_list);

View File

@ -62,6 +62,7 @@ typedef struct {
#define REG_AOT_TRACE_SYM() #define REG_AOT_TRACE_SYM()
#endif #endif
#if WASM_ENABLE_AOT_INTRINSICS != 0
#define REG_INTRINSIC_SYM() \ #define REG_INTRINSIC_SYM() \
REG_SYM(aot_intrinsic_fabs_f32), \ REG_SYM(aot_intrinsic_fabs_f32), \
REG_SYM(aot_intrinsic_fabs_f64), \ REG_SYM(aot_intrinsic_fabs_f64), \
@ -124,7 +125,10 @@ typedef struct {
REG_SYM(aot_intrinsic_i32_div_s), \ REG_SYM(aot_intrinsic_i32_div_s), \
REG_SYM(aot_intrinsic_i32_div_u), \ REG_SYM(aot_intrinsic_i32_div_u), \
REG_SYM(aot_intrinsic_i32_rem_s), \ REG_SYM(aot_intrinsic_i32_rem_s), \
REG_SYM(aot_intrinsic_i32_rem_u), \ REG_SYM(aot_intrinsic_i32_rem_u),
#else
#define REG_INTRINSIC_SYM()
#endif
#if WASM_ENABLE_STATIC_PGO != 0 #if WASM_ENABLE_STATIC_PGO != 0
#define REG_LLVM_PGO_SYM() \ #define REG_LLVM_PGO_SYM() \

View File

@ -4664,3 +4664,74 @@ aot_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap)
return true; return true;
} }
#endif /* end of WASM_ENABLE_GC != 0 */ #endif /* end of WASM_ENABLE_GC != 0 */
char *
aot_const_str_set_insert(const uint8 *str, int32 len, AOTModule *module,
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
bool is_vram_word_align,
#endif
char *error_buf, uint32 error_buf_size)
{
HashMap *set = module->const_str_set;
char *c_str, *value;
/* Create const string set if it isn't created */
if (!set
&& !(set = module->const_str_set = bh_hash_map_create(
32, false, (HashFunc)wasm_string_hash,
(KeyEqualFunc)wasm_string_equal, NULL, wasm_runtime_free))) {
set_error_buf(error_buf, error_buf_size,
"create const string set failed");
return NULL;
}
/* Lookup const string set, use the string if found */
if (!(c_str = runtime_malloc((uint32)len, error_buf, error_buf_size))) {
return NULL;
}
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
if (is_vram_word_align) {
bh_memcpy_wa(c_str, (uint32)len, str, (uint32)len);
}
else
#endif
{
bh_memcpy_s(c_str, len, str, (uint32)len);
}
if ((value = bh_hash_map_find(set, c_str))) {
wasm_runtime_free(c_str);
return value;
}
if (!bh_hash_map_insert(set, c_str, c_str)) {
set_error_buf(error_buf, error_buf_size,
"insert string to hash map failed");
wasm_runtime_free(c_str);
return NULL;
}
return c_str;
}
bool
aot_set_module_name(AOTModule *module, const char *name, char *error_buf,
uint32_t error_buf_size)
{
if (!name)
return false;
module->name =
aot_const_str_set_insert((const uint8 *)name, strlen(name) + 1, module,
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
false,
#endif
error_buf, error_buf_size);
return module->name != NULL;
}
const char *
aot_get_module_name(AOTModule *module)
{
return module->name;
}

View File

@ -307,6 +307,9 @@ typedef struct AOTModule {
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
WASMCustomSection *custom_section_list; WASMCustomSection *custom_section_list;
#endif #endif
/* user defined name */
char *name;
} AOTModule; } AOTModule;
#define AOTMemoryInstance WASMMemoryInstance #define AOTMemoryInstance WASMMemoryInstance
@ -761,6 +764,20 @@ bool
aot_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap); aot_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap);
#endif /* end of WASM_ENABLE_GC != 0 */ #endif /* end of WASM_ENABLE_GC != 0 */
char *
aot_const_str_set_insert(const uint8 *str, int32 len, AOTModule *module,
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
bool is_vram_word_align,
#endif
char *error_buf, uint32 error_buf_size);
bool
aot_set_module_name(AOTModule *module, const char *name, char *error_buf,
uint32_t error_buf_size);
const char *
aot_get_module_name(AOTModule *module);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */
#endif #endif

View File

@ -2949,6 +2949,34 @@ wasm_shared_module_delete(own wasm_shared_module_t *shared_module)
wasm_module_delete_internal((wasm_module_t *)shared_module); wasm_module_delete_internal((wasm_module_t *)shared_module);
} }
bool
wasm_module_set_name(wasm_module_t *module, const char *name)
{
char error_buf[256] = { 0 };
wasm_module_ex_t *module_ex = NULL;
if (!module)
return false;
module_ex = module_to_module_ext(module);
bool ret = wasm_runtime_set_module_name(module_ex->module_comm_rt, name,
error_buf, sizeof(error_buf) - 1);
if (!ret)
LOG_WARNING("set module name failed: %s", error_buf);
return ret;
}
const char *
wasm_module_get_name(wasm_module_t *module)
{
wasm_module_ex_t *module_ex = NULL;
if (!module)
return "";
module_ex = module_to_module_ext(module);
return wasm_runtime_get_module_name(module_ex->module_comm_rt);
}
static wasm_func_t * static wasm_func_t *
wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type, wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type,
wasm_func_callback_t func_callback) wasm_func_callback_t func_callback)

View File

@ -564,8 +564,20 @@ wasm_runtime_exec_env_check(WASMExecEnv *exec_env)
&& exec_env->wasm_stack.top <= exec_env->wasm_stack.top_boundary; && exec_env->wasm_stack.top <= exec_env->wasm_stack.top_boundary;
} }
bool #if defined(OS_THREAD_MUTEX_INITIALIZER)
wasm_runtime_init() /**
* lock for wasm_runtime_init/wasm_runtime_full_init and runtime_ref_count
* Note: if the platform has mutex initializer, we use a global lock to
* lock the operations of runtime init/full_init, otherwise when there are
* operations happening simultaneously in multiple threads, developer
* must create the lock by himself, and use it to lock the operations
*/
static korp_mutex runtime_lock = OS_THREAD_MUTEX_INITIALIZER;
#endif
static int32 runtime_ref_count = 0;
static bool
wasm_runtime_init_internal()
{ {
if (!wasm_runtime_memory_init(Alloc_With_System_Allocator, NULL)) if (!wasm_runtime_memory_init(Alloc_With_System_Allocator, NULL))
return false; return false;
@ -578,8 +590,32 @@ wasm_runtime_init()
return true; return true;
} }
void bool
wasm_runtime_destroy() wasm_runtime_init()
{
bool ret = true;
#if defined(OS_THREAD_MUTEX_INITIALIZER)
os_mutex_lock(&runtime_lock);
#endif
bh_assert(runtime_ref_count >= 0);
if (runtime_ref_count == 0) {
ret = wasm_runtime_init_internal();
}
if (ret) {
runtime_ref_count++;
}
#if defined(OS_THREAD_MUTEX_INITIALIZER)
os_mutex_unlock(&runtime_lock);
#endif
return ret;
}
static void
wasm_runtime_destroy_internal()
{ {
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0 #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
wasm_externref_map_destroy(); wasm_externref_map_destroy();
@ -640,6 +676,24 @@ wasm_runtime_destroy()
wasm_runtime_memory_destroy(); wasm_runtime_memory_destroy();
} }
void
wasm_runtime_destroy()
{
#if defined(OS_THREAD_MUTEX_INITIALIZER)
os_mutex_lock(&runtime_lock);
#endif
bh_assert(runtime_ref_count > 0);
runtime_ref_count--;
if (runtime_ref_count == 0) {
wasm_runtime_destroy_internal();
}
#if defined(OS_THREAD_MUTEX_INITIALIZER)
os_mutex_unlock(&runtime_lock);
#endif
}
RunningMode RunningMode
wasm_runtime_get_default_running_mode(void) wasm_runtime_get_default_running_mode(void)
{ {
@ -662,8 +716,8 @@ wasm_runtime_get_gc_heap_size_default(void)
} }
#endif #endif
bool static bool
wasm_runtime_full_init(RuntimeInitArgs *init_args) wasm_runtime_full_init_internal(RuntimeInitArgs *init_args)
{ {
if (!wasm_runtime_memory_init(init_args->mem_alloc_type, if (!wasm_runtime_memory_init(init_args->mem_alloc_type,
&init_args->mem_alloc_option)) &init_args->mem_alloc_option))
@ -725,6 +779,30 @@ wasm_runtime_full_init(RuntimeInitArgs *init_args)
return true; return true;
} }
bool
wasm_runtime_full_init(RuntimeInitArgs *init_args)
{
bool ret = true;
#if defined(OS_THREAD_MUTEX_INITIALIZER)
os_mutex_lock(&runtime_lock);
#endif
bh_assert(runtime_ref_count >= 0);
if (runtime_ref_count == 0) {
ret = wasm_runtime_full_init_internal(init_args);
}
if (ret) {
runtime_ref_count++;
}
#if defined(OS_THREAD_MUTEX_INITIALIZER)
os_mutex_unlock(&runtime_lock);
#endif
return ret;
}
void void
wasm_runtime_set_log_level(log_level_t level) wasm_runtime_set_log_level(log_level_t level)
{ {
@ -6670,3 +6748,44 @@ wasm_runtime_set_linux_perf(bool flag)
enable_linux_perf = flag; enable_linux_perf = flag;
} }
#endif #endif
bool
wasm_runtime_set_module_name(wasm_module_t module, const char *name,
char *error_buf, uint32_t error_buf_size)
{
if (!module)
return false;
#if WASM_ENABLE_INTERP != 0
if (module->module_type == Wasm_Module_Bytecode)
return wasm_set_module_name((WASMModule *)module, name, error_buf,
error_buf_size);
#endif
#if WASM_ENABLE_AOT != 0
if (module->module_type == Wasm_Module_AoT)
return aot_set_module_name((AOTModule *)module, name, error_buf,
error_buf_size);
#endif
return false;
}
const char *
wasm_runtime_get_module_name(wasm_module_t module)
{
if (!module)
return "";
#if WASM_ENABLE_INTERP != 0
if (module->module_type == Wasm_Module_Bytecode)
return wasm_get_module_name((WASMModule *)module);
#endif
#if WASM_ENABLE_AOT != 0
if (module->module_type == Wasm_Module_AoT)
return aot_get_module_name((AOTModule *)module);
#endif
return "";
}

View File

@ -966,7 +966,9 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
location = dwarf_gen_location( location = dwarf_gen_location(
comp_ctx, func_ctx, comp_ctx, func_ctx,
(frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code); (frame_ip - 1) - comp_ctx->comp_data->wasm_module->buf_code);
LLVMSetCurrentDebugLocation2(comp_ctx->builder, location); if (location != NULL) {
LLVMSetCurrentDebugLocation2(comp_ctx->builder, location);
}
#endif #endif
switch (opcode) { switch (opcode) {

View File

@ -25,73 +25,6 @@
} \ } \
} while (0) } while (0)
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
static bool
check_utf8_str(const uint8 *str, uint32 len)
{
/* The valid ranges are taken from page 125, below link
https://www.unicode.org/versions/Unicode9.0.0/ch03.pdf */
const uint8 *p = str, *p_end = str + len;
uint8 chr;
while (p < p_end) {
chr = *p;
if (chr < 0x80) {
p++;
}
else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) {
if (p[1] < 0x80 || p[1] > 0xBF) {
return false;
}
p += 2;
}
else if (chr >= 0xE0 && chr <= 0xEF && p + 2 < p_end) {
if (chr == 0xE0) {
if (p[1] < 0xA0 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
return false;
}
}
else if (chr == 0xED) {
if (p[1] < 0x80 || p[1] > 0x9F || p[2] < 0x80 || p[2] > 0xBF) {
return false;
}
}
else if (chr >= 0xE1 && chr <= 0xEF) {
if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
return false;
}
}
p += 3;
}
else if (chr >= 0xF0 && chr <= 0xF4 && p + 3 < p_end) {
if (chr == 0xF0) {
if (p[1] < 0x90 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
|| p[3] < 0x80 || p[3] > 0xBF) {
return false;
}
}
else if (chr >= 0xF1 && chr <= 0xF3) {
if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
|| p[3] < 0x80 || p[3] > 0xBF) {
return false;
}
}
else if (chr == 0xF4) {
if (p[1] < 0x80 || p[1] > 0x8F || p[2] < 0x80 || p[2] > 0xBF
|| p[3] < 0x80 || p[3] > 0xBF) {
return false;
}
}
p += 4;
}
else {
return false;
}
}
return (p == p_end);
}
#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */
/* Internal function in object file */ /* Internal function in object file */
typedef struct AOTObjectFunc { typedef struct AOTObjectFunc {
char *func_name; char *func_name;
@ -1552,9 +1485,16 @@ fail_integer_too_large:
res = (uint32)res64; \ res = (uint32)res64; \
} while (0) } while (0)
/*
* - transfer .name section in .wasm (comp_data->name_section_buf) to
* aot buf (comp_data->aot_name_section_buf)
* - leb128 to u32
* - add `\0` at the end of every name, and adjust length(+1)
*/
static uint32 static uint32
get_name_section_size(AOTCompData *comp_data) get_name_section_size(AOTCompData *comp_data)
{ {
/* original name section content in .wasm */
const uint8 *p = comp_data->name_section_buf, const uint8 *p = comp_data->name_section_buf,
*p_end = comp_data->name_section_buf_end; *p_end = comp_data->name_section_buf_end;
uint8 *buf, *buf_end; uint8 *buf, *buf_end;
@ -1581,22 +1521,20 @@ get_name_section_size(AOTCompData *comp_data)
aot_set_last_error("allocate memory for custom name section failed."); aot_set_last_error("allocate memory for custom name section failed.");
return 0; return 0;
} }
memset(buf, 0, (uint32)max_aot_buf_size);
buf_end = buf + max_aot_buf_size; buf_end = buf + max_aot_buf_size;
/* the size of "name". it should be 4 */
read_leb_uint32(p, p_end, name_len); read_leb_uint32(p, p_end, name_len);
offset = align_uint(offset, 4); offset = align_uint(offset, 4);
EMIT_U32(name_len); EMIT_U32(name_len);
if (name_len == 0 || p + name_len > p_end) { if (name_len != 4 || p + name_len > p_end) {
aot_set_last_error("unexpected end"); aot_set_last_error("unexpected end");
return 0; return 0;
} }
if (!check_utf8_str(p, name_len)) { /* "name" */
aot_set_last_error("invalid UTF-8 encoding");
return 0;
}
if (memcmp(p, "name", 4) != 0) { if (memcmp(p, "name", 4) != 0) {
aot_set_last_error("invalid custom name section"); aot_set_last_error("invalid custom name section");
return 0; return 0;
@ -1645,9 +1583,18 @@ get_name_section_size(AOTCompData *comp_data)
previous_func_index = func_index; previous_func_index = func_index;
read_leb_uint32(p, p_end, func_name_len); read_leb_uint32(p, p_end, func_name_len);
offset = align_uint(offset, 2); offset = align_uint(offset, 2);
EMIT_U16(func_name_len);
/* emit a string ends with `\0` */
if (func_name_len + 1 > UINT16_MAX) {
aot_set_last_error(
"emit string failed: string too long");
goto fail;
}
/* extra 1 byte for \0 */
EMIT_U16(func_name_len + 1);
EMIT_BUF(p, func_name_len); EMIT_BUF(p, func_name_len);
p += func_name_len; p += func_name_len;
EMIT_U8(0);
} }
} }
break; break;

View File

@ -374,7 +374,9 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
} }
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
LLVMInstructionSetDebugLoc(ret, return_location); if (return_location != NULL) {
LLVMInstructionSetDebugLoc(ret, return_location);
}
#endif #endif
} }
else { else {
@ -383,7 +385,9 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
goto fail; goto fail;
} }
#if WASM_ENABLE_DEBUG_AOT != 0 #if WASM_ENABLE_DEBUG_AOT != 0
LLVMInstructionSetDebugLoc(ret, return_location); if (return_location != NULL) {
LLVMInstructionSetDebugLoc(ret, return_location);
}
#endif #endif
} }
} }

View File

@ -491,6 +491,8 @@ dwarf_gen_location(const AOTCompContext *comp_ctx,
dwarf_extractor *extractor; dwarf_extractor *extractor;
AOTFunc *func = func_ctx->aot_func; AOTFunc *func = func_ctx->aot_func;
if (func_ctx->debug_func == NULL)
return NULL;
if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor))) if (!(extractor = TO_EXTACTOR(comp_ctx->comp_data->extractor)))
return NULL; return NULL;

View File

@ -536,6 +536,9 @@ WASM_API_EXTERN own wasm_shared_module_t* wasm_module_share(wasm_module_t*);
WASM_API_EXTERN own wasm_module_t* wasm_module_obtain(wasm_store_t*, wasm_shared_module_t*); WASM_API_EXTERN own wasm_module_t* wasm_module_obtain(wasm_store_t*, wasm_shared_module_t*);
WASM_API_EXTERN void wasm_shared_module_delete(own wasm_shared_module_t*); WASM_API_EXTERN void wasm_shared_module_delete(own wasm_shared_module_t*);
WASM_API_EXTERN bool wasm_module_set_name(wasm_module_t*, const char* name);
WASM_API_EXTERN const char *wasm_module_get_name(wasm_module_t*);
// Function Instances // Function Instances

View File

@ -539,7 +539,7 @@ wasm_runtime_instantiate(const wasm_module_t module,
/** /**
* Instantiate a WASM module, with specified instantiation arguments * Instantiate a WASM module, with specified instantiation arguments
* *
* Same as wasm_runtime_instantiate, but it also allows overwriting maximum memory * Same as wasm_runtime_instantiate, but it also allows overwriting maximum memory
*/ */
WASM_RUNTIME_API_EXTERN wasm_module_inst_t WASM_RUNTIME_API_EXTERN wasm_module_inst_t
@ -1669,6 +1669,15 @@ wasm_runtime_begin_blocking_op(wasm_exec_env_t exec_env);
WASM_RUNTIME_API_EXTERN void WASM_RUNTIME_API_EXTERN void
wasm_runtime_end_blocking_op(wasm_exec_env_t exec_env); wasm_runtime_end_blocking_op(wasm_exec_env_t exec_env);
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_set_module_name(wasm_module_t module, const char *name,
char *error_buf, uint32_t error_buf_size);
/* return the most recently set module name or "" if never set before */
WASM_RUNTIME_API_EXTERN const char*
wasm_runtime_get_module_name(wasm_module_t module);
/* clang-format on */ /* clang-format on */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1065,6 +1065,9 @@ struct WASMModule {
bool is_ref_types_used; bool is_ref_types_used;
bool is_bulk_memory_used; bool is_bulk_memory_used;
#endif #endif
/* user defined name */
char *name;
}; };
typedef struct BlockType { typedef struct BlockType {

View File

@ -392,138 +392,6 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new, char *error_buf,
mem = mem_new; \ mem = mem_new; \
} while (0) } while (0)
static bool
check_utf8_str(const uint8 *str, uint32 len)
{
/* The valid ranges are taken from page 125, below link
https://www.unicode.org/versions/Unicode9.0.0/ch03.pdf */
const uint8 *p = str, *p_end = str + len;
uint8 chr;
while (p < p_end) {
chr = *p;
if (chr == 0) {
LOG_WARNING(
"LIMITATION: a string which contains '\\00' is unsupported");
return false;
}
else if (chr < 0x80) {
p++;
}
else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) {
if (p[1] < 0x80 || p[1] > 0xBF) {
return false;
}
p += 2;
}
else if (chr >= 0xE0 && chr <= 0xEF && p + 2 < p_end) {
if (chr == 0xE0) {
if (p[1] < 0xA0 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
return false;
}
}
else if (chr == 0xED) {
if (p[1] < 0x80 || p[1] > 0x9F || p[2] < 0x80 || p[2] > 0xBF) {
return false;
}
}
else { /* chr >= 0xE1 && chr <= 0xEF */
if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
return false;
}
}
p += 3;
}
else if (chr >= 0xF0 && chr <= 0xF4 && p + 3 < p_end) {
if (chr == 0xF0) {
if (p[1] < 0x90 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
|| p[3] < 0x80 || p[3] > 0xBF) {
return false;
}
}
else if (chr <= 0xF3) { /* and also chr >= 0xF1 */
if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
|| p[3] < 0x80 || p[3] > 0xBF) {
return false;
}
}
else { /* chr == 0xF4 */
if (p[1] < 0x80 || p[1] > 0x8F || p[2] < 0x80 || p[2] > 0xBF
|| p[3] < 0x80 || p[3] > 0xBF) {
return false;
}
}
p += 4;
}
else {
return false;
}
}
return (p == p_end);
}
static char *
const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module,
bool is_load_from_file_buf, char *error_buf,
uint32 error_buf_size)
{
StringNode *node, *node_next;
if (!check_utf8_str(str, len)) {
set_error_buf(error_buf, error_buf_size, "invalid UTF-8 encoding");
return NULL;
}
if (len == 0) {
return "";
}
else if (is_load_from_file_buf) {
/* As the file buffer can be referred to after loading, we use
the previous byte of leb encoded size to adjust the string:
move string 1 byte backward and then append '\0' */
char *c_str = (char *)str - 1;
bh_memmove_s(c_str, len + 1, c_str + 1, len);
c_str[len] = '\0';
return c_str;
}
/* Search const str list */
node = module->const_str_list;
while (node) {
node_next = node->next;
if (strlen(node->str) == len && !memcmp(node->str, str, len))
break;
node = node_next;
}
if (node) {
return node->str;
}
if (!(node = loader_malloc(sizeof(StringNode) + len + 1, error_buf,
error_buf_size))) {
return NULL;
}
node->str = ((char *)node) + sizeof(StringNode);
bh_memcpy_s(node->str, len + 1, str, len);
node->str[len] = '\0';
if (!module->const_str_list) {
/* set as head */
module->const_str_list = node;
node->next = NULL;
}
else {
/* insert it */
node->next = module->const_str_list;
module->const_str_list = node;
}
return node->str;
}
#if WASM_ENABLE_GC != 0 #if WASM_ENABLE_GC != 0
static bool static bool
check_type_index(const WASMModule *module, uint32 type_index, char *error_buf, check_type_index(const WASMModule *module, uint32 type_index, char *error_buf,
@ -3454,7 +3322,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
/* load module name */ /* load module name */
read_leb_uint32(p, p_end, name_len); read_leb_uint32(p, p_end, name_len);
CHECK_BUF(p, p_end, name_len); CHECK_BUF(p, p_end, name_len);
if (!(sub_module_name = const_str_list_insert( if (!(sub_module_name = wasm_const_str_list_insert(
p, name_len, module, is_load_from_file_buf, error_buf, p, name_len, module, is_load_from_file_buf, error_buf,
error_buf_size))) { error_buf_size))) {
return false; return false;
@ -3464,7 +3332,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
/* load field name */ /* load field name */
read_leb_uint32(p, p_end, name_len); read_leb_uint32(p, p_end, name_len);
CHECK_BUF(p, p_end, name_len); CHECK_BUF(p, p_end, name_len);
if (!(field_name = const_str_list_insert( if (!(field_name = wasm_const_str_list_insert(
p, name_len, module, is_load_from_file_buf, error_buf, p, name_len, module, is_load_from_file_buf, error_buf,
error_buf_size))) { error_buf_size))) {
return false; return false;
@ -4187,7 +4055,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
} }
} }
if (!(export->name = const_str_list_insert( if (!(export->name = wasm_const_str_list_insert(
p, str_len, module, is_load_from_file_buf, error_buf, p, str_len, module, is_load_from_file_buf, error_buf,
error_buf_size))) { error_buf_size))) {
return false; return false;
@ -5096,7 +4964,7 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
return false; return false;
} }
if (!(module->functions[func_index]->field_name = if (!(module->functions[func_index]->field_name =
const_str_list_insert( wasm_const_str_list_insert(
p, func_name_len, module, p, func_name_len, module,
#if WASM_ENABLE_WAMR_COMPILER != 0 #if WASM_ENABLE_WAMR_COMPILER != 0
false, false,
@ -5148,7 +5016,7 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
return false; return false;
} }
if (!check_utf8_str(p, name_len)) { if (!wasm_check_utf8_str(p, name_len)) {
set_error_buf(error_buf, error_buf_size, "invalid UTF-8 encoding"); set_error_buf(error_buf, error_buf_size, "invalid UTF-8 encoding");
return false; return false;
} }
@ -5164,7 +5032,7 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
} }
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0 #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
if (memcmp(p, "name", 4) == 0) { if (name_len == 4 && memcmp(p, "name", 4) == 0) {
module->name_section_buf = buf; module->name_section_buf = buf;
module->name_section_buf_end = buf_end; module->name_section_buf_end = buf_end;
p += name_len; p += name_len;
@ -6176,6 +6044,8 @@ create_module(char *error_buf, uint32 error_buf_size)
/* Set start_function to -1, means no start function */ /* Set start_function to -1, means no start function */
module->start_function = (uint32)-1; module->start_function = (uint32)-1;
module->name = "";
#if WASM_ENABLE_FAST_INTERP == 0 #if WASM_ENABLE_FAST_INTERP == 0
module->br_table_cache_list = &module->br_table_cache_list_head; module->br_table_cache_list = &module->br_table_cache_list_head;
ret = bh_list_init(module->br_table_cache_list); ret = bh_list_init(module->br_table_cache_list);
@ -8689,11 +8559,11 @@ fail:
wasm_loader_emit_ptr(loader_ctx, NULL); \ wasm_loader_emit_ptr(loader_ctx, NULL); \
} while (0) } while (0)
#define emit_br_info(frame_csp) \ #define emit_br_info(frame_csp, is_br) \
do { \ do { \
if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, error_buf, \ if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, is_br, error_buf, \
error_buf_size)) \ error_buf_size)) \
goto fail; \ goto fail; \
} while (0) } while (0)
#define LAST_OP_OUTPUT_I32() \ #define LAST_OP_OUTPUT_I32() \
@ -9087,7 +8957,7 @@ apply_label_patch(WASMLoaderContext *ctx, uint8 depth, uint8 patch_type)
static bool static bool
wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp, wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
char *error_buf, uint32 error_buf_size) bool is_br, char *error_buf, uint32 error_buf_size)
{ {
/* br info layout: /* br info layout:
* a) arity of target block * a) arity of target block
@ -9148,7 +9018,8 @@ wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
/* Part e */ /* Part e */
dynamic_offset = dynamic_offset =
frame_csp->dynamic_offset + wasm_get_cell_num(types, arity); frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
ctx->dynamic_offset = dynamic_offset; if (is_br)
ctx->dynamic_offset = dynamic_offset;
for (i = (int32)arity - 1; i >= 0; i--) { for (i = (int32)arity - 1; i >= 0; i--) {
cell = (uint8)wasm_value_type_cell_num(types[i]); cell = (uint8)wasm_value_type_cell_num(types[i]);
dynamic_offset -= cell; dynamic_offset -= cell;
@ -10019,8 +9890,8 @@ check_memory_align_equal(uint8 opcode, uint32 align, char *error_buf,
#endif /* end of WASM_ENABLE_SHARED_MEMORY */ #endif /* end of WASM_ENABLE_SHARED_MEMORY */
static bool static bool
wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth, wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth, uint8 opcode,
bool is_br_table, char *error_buf, uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
BranchBlock *target_block, *cur_block; BranchBlock *target_block, *cur_block;
BlockType *target_block_type; BlockType *target_block_type;
@ -10117,7 +9988,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
/* Backup stack data since it may be changed in the below /* Backup stack data since it may be changed in the below
push operations, and the stack data may be used when push operations, and the stack data may be used when
checking other target blocks of opcode br_table */ checking other target blocks of opcode br_table */
if (is_br_table) { if (opcode == WASM_OP_BR_TABLE) {
uint64 total_size; uint64 total_size;
frame_ref_after_popped = loader_ctx->frame_ref; frame_ref_after_popped = loader_ctx->frame_ref;
@ -10181,13 +10052,13 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
} }
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
emit_br_info(target_block); emit_br_info(target_block, opcode == WASM_OP_BR);
#endif #endif
/* Restore the stack data, note that frame_ref_bottom, /* Restore the stack data, note that frame_ref_bottom,
frame_reftype_map_bottom, frame_offset_bottom may be frame_reftype_map_bottom, frame_offset_bottom may be
re-allocated in the above push operations */ re-allocated in the above push operations */
if (is_br_table) { if (opcode == WASM_OP_BR_TABLE) {
uint32 total_size; uint32 total_size;
/* The stack operand num should not be smaller than before /* The stack operand num should not be smaller than before
@ -10278,7 +10149,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
} }
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
emit_br_info(target_block); emit_br_info(target_block, opcode == WASM_OP_BR);
#endif #endif
ret = true; ret = true;
@ -10301,14 +10172,14 @@ fail:
static BranchBlock * static BranchBlock *
check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end, check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end,
bool is_br_table, char *error_buf, uint32 error_buf_size) uint8 opcode, char *error_buf, uint32 error_buf_size)
{ {
uint8 *p = *p_buf, *p_end = buf_end; uint8 *p = *p_buf, *p_end = buf_end;
BranchBlock *frame_csp_tmp; BranchBlock *frame_csp_tmp;
uint32 depth; uint32 depth;
read_leb_uint32(p, p_end, depth); read_leb_uint32(p, p_end, depth);
if (!wasm_loader_check_br(loader_ctx, depth, is_br_table, error_buf, if (!wasm_loader_check_br(loader_ctx, depth, opcode, error_buf,
error_buf_size)) { error_buf_size)) {
goto fail; goto fail;
} }
@ -11239,7 +11110,7 @@ re_scan:
/* check the target catching block: LABEL_TYPE_CATCH */ /* check the target catching block: LABEL_TYPE_CATCH */
if (!(frame_csp_tmp = if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false, check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) error_buf, error_buf_size)))
goto fail; goto fail;
@ -11526,7 +11397,7 @@ re_scan:
case WASM_OP_BR: case WASM_OP_BR:
{ {
if (!(frame_csp_tmp = if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false, check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) error_buf, error_buf_size)))
goto fail; goto fail;
@ -11540,7 +11411,7 @@ re_scan:
POP_I32(); POP_I32();
if (!(frame_csp_tmp = if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false, check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) error_buf, error_buf_size)))
goto fail; goto fail;
@ -11610,7 +11481,7 @@ re_scan:
} }
if (!(frame_csp_tmp = if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, true, check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) { error_buf, error_buf_size))) {
goto fail; goto fail;
} }
@ -12515,7 +12386,7 @@ re_scan:
if (opcode == WASM_OP_BR_ON_NULL) { if (opcode == WASM_OP_BR_ON_NULL) {
if (!(frame_csp_tmp = if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false, check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) { error_buf, error_buf_size))) {
goto fail; goto fail;
} }
@ -12562,7 +12433,7 @@ re_scan:
PUSH_REF(type); PUSH_REF(type);
} }
if (!(frame_csp_tmp = if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false, check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) { error_buf, error_buf_size))) {
goto fail; goto fail;
} }
@ -14044,7 +13915,7 @@ re_scan:
} }
PUSH_REF(type_tmp); PUSH_REF(type_tmp);
if (!(frame_csp_tmp = check_branch_block( if (!(frame_csp_tmp = check_branch_block(
loader_ctx, &p, p_end, false, error_buf, loader_ctx, &p, p_end, opcode, error_buf,
error_buf_size))) { error_buf_size))) {
goto fail; goto fail;
} }

View File

@ -230,63 +230,6 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new, char *error_buf,
mem = mem_new; \ mem = mem_new; \
} while (0) } while (0)
static char *
const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module,
bool is_load_from_file_buf, char *error_buf,
uint32 error_buf_size)
{
StringNode *node, *node_next;
if (len == 0) {
return "";
}
else if (is_load_from_file_buf) {
/* As the file buffer can be referred to after loading, we use
the previous byte of leb encoded size to adjust the string:
move string 1 byte backward and then append '\0' */
char *c_str = (char *)str - 1;
bh_memmove_s(c_str, len + 1, c_str + 1, len);
c_str[len] = '\0';
return c_str;
}
/* Search const str list */
node = module->const_str_list;
while (node) {
node_next = node->next;
if (strlen(node->str) == len && !memcmp(node->str, str, len))
break;
node = node_next;
}
if (node) {
LOG_DEBUG("reuse %s", node->str);
return node->str;
}
if (!(node = loader_malloc(sizeof(StringNode) + len + 1, error_buf,
error_buf_size))) {
return NULL;
}
node->str = ((char *)node) + sizeof(StringNode);
bh_memcpy_s(node->str, len + 1, str, len);
node->str[len] = '\0';
if (!module->const_str_list) {
/* set as head */
module->const_str_list = node;
node->next = NULL;
}
else {
/* insert it */
node->next = module->const_str_list;
module->const_str_list = node;
}
return node->str;
}
static void static void
destroy_wasm_type(WASMFuncType *type) destroy_wasm_type(WASMFuncType *type)
{ {
@ -1065,7 +1008,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
/* load module name */ /* load module name */
read_leb_uint32(p, p_end, name_len); read_leb_uint32(p, p_end, name_len);
CHECK_BUF(p, p_end, name_len); CHECK_BUF(p, p_end, name_len);
if (!(sub_module_name = const_str_list_insert( if (!(sub_module_name = wasm_const_str_list_insert(
p, name_len, module, is_load_from_file_buf, error_buf, p, name_len, module, is_load_from_file_buf, error_buf,
error_buf_size))) { error_buf_size))) {
return false; return false;
@ -1075,7 +1018,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
/* load field name */ /* load field name */
read_leb_uint32(p, p_end, name_len); read_leb_uint32(p, p_end, name_len);
CHECK_BUF(p, p_end, name_len); CHECK_BUF(p, p_end, name_len);
if (!(field_name = const_str_list_insert( if (!(field_name = wasm_const_str_list_insert(
p, name_len, module, is_load_from_file_buf, error_buf, p, name_len, module, is_load_from_file_buf, error_buf,
error_buf_size))) { error_buf_size))) {
return false; return false;
@ -1483,7 +1426,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
&& memcmp(name, p, str_len) == 0)); && memcmp(name, p, str_len) == 0));
} }
if (!(export->name = const_str_list_insert( if (!(export->name = wasm_const_str_list_insert(
p, str_len, module, is_load_from_file_buf, error_buf, p, str_len, module, is_load_from_file_buf, error_buf,
error_buf_size))) { error_buf_size))) {
return false; return false;
@ -2039,7 +1982,7 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
func_index -= module->import_function_count; func_index -= module->import_function_count;
bh_assert(func_index < module->function_count); bh_assert(func_index < module->function_count);
if (!(module->functions[func_index]->field_name = if (!(module->functions[func_index]->field_name =
const_str_list_insert( wasm_const_str_list_insert(
p, func_name_len, module, p, func_name_len, module,
is_load_from_file_buf, error_buf, is_load_from_file_buf, error_buf,
error_buf_size))) { error_buf_size))) {
@ -2081,7 +2024,7 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
bh_assert(name_len > 0 && p + name_len <= p_end); bh_assert(name_len > 0 && p + name_len <= p_end);
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0 #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
if (memcmp(p, "name", 4) == 0) { if (name_len == 4 && memcmp(p, "name", 4) == 0) {
p += name_len; p += name_len;
handle_name_section(p, p_end, module, is_load_from_file_buf, error_buf, handle_name_section(p, p_end, module, is_load_from_file_buf, error_buf,
error_buf_size); error_buf_size);
@ -3065,6 +3008,8 @@ create_module(char *error_buf, uint32 error_buf_size)
/* Set start_function to -1, means no start function */ /* Set start_function to -1, means no start function */
module->start_function = (uint32)-1; module->start_function = (uint32)-1;
module->name = "";
#if WASM_ENABLE_FAST_INTERP == 0 #if WASM_ENABLE_FAST_INTERP == 0
module->br_table_cache_list = &module->br_table_cache_list_head; module->br_table_cache_list = &module->br_table_cache_list_head;
ret = bh_list_init(module->br_table_cache_list); ret = bh_list_init(module->br_table_cache_list);
@ -4398,11 +4343,11 @@ wasm_loader_pop_frame_csp(WASMLoaderContext *ctx, char *error_buf,
wasm_loader_emit_ptr(loader_ctx, NULL); \ wasm_loader_emit_ptr(loader_ctx, NULL); \
} while (0) } while (0)
#define emit_br_info(frame_csp) \ #define emit_br_info(frame_csp, is_br) \
do { \ do { \
if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, error_buf, \ if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, is_br, error_buf, \
error_buf_size)) \ error_buf_size)) \
goto fail; \ goto fail; \
} while (0) } while (0)
#define LAST_OP_OUTPUT_I32() \ #define LAST_OP_OUTPUT_I32() \
@ -4787,7 +4732,7 @@ apply_label_patch(WASMLoaderContext *ctx, uint8 depth, uint8 patch_type)
static bool static bool
wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp, wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
char *error_buf, uint32 error_buf_size) bool is_br, char *error_buf, uint32 error_buf_size)
{ {
/* br info layout: /* br info layout:
* a) arity of target block * a) arity of target block
@ -4836,7 +4781,8 @@ wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
/* Part e */ /* Part e */
dynamic_offset = dynamic_offset =
frame_csp->dynamic_offset + wasm_get_cell_num(types, arity); frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
ctx->dynamic_offset = dynamic_offset; if (is_br)
ctx->dynamic_offset = dynamic_offset;
for (i = (int32)arity - 1; i >= 0; i--) { for (i = (int32)arity - 1; i >= 0; i--) {
cell = (uint8)wasm_value_type_cell_num(types[i]); cell = (uint8)wasm_value_type_cell_num(types[i]);
dynamic_offset -= cell; dynamic_offset -= cell;
@ -5542,8 +5488,8 @@ fail:
} while (0) } while (0)
static bool static bool
wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth, wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth, uint8 opcode,
bool is_br_table, char *error_buf, uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
BranchBlock *target_block, *cur_block; BranchBlock *target_block, *cur_block;
BlockType *target_block_type; BlockType *target_block_type;
@ -5601,7 +5547,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
/* Backup stack data since it may be changed in the below /* Backup stack data since it may be changed in the below
push operations, and the stack data may be used when push operations, and the stack data may be used when
checking other target blocks of opcode br_table */ checking other target blocks of opcode br_table */
if (is_br_table) { if (opcode == WASM_OP_BR_TABLE) {
uint64 total_size; uint64 total_size;
frame_ref_after_popped = loader_ctx->frame_ref; frame_ref_after_popped = loader_ctx->frame_ref;
@ -5639,13 +5585,13 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
} }
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
emit_br_info(target_block); emit_br_info(target_block, opcode == WASM_OP_BR);
#endif #endif
/* Restore the stack data, note that frame_ref_bottom, /* Restore the stack data, note that frame_ref_bottom,
frame_reftype_map_bottom, frame_offset_bottom may be frame_reftype_map_bottom, frame_offset_bottom may be
re-allocated in the above push operations */ re-allocated in the above push operations */
if (is_br_table) { if (opcode == WASM_OP_BR_TABLE) {
uint32 total_size; uint32 total_size;
/* The stack operand num should not be smaller than before /* The stack operand num should not be smaller than before
@ -5689,7 +5635,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
} }
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
emit_br_info(target_block); emit_br_info(target_block, opcode == WASM_OP_BR);
#endif #endif
ret = true; ret = true;
@ -5708,14 +5654,14 @@ fail:
static BranchBlock * static BranchBlock *
check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end, check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end,
bool is_br_table, char *error_buf, uint32 error_buf_size) uint8 opcode, char *error_buf, uint32 error_buf_size)
{ {
uint8 *p = *p_buf, *p_end = buf_end; uint8 *p = *p_buf, *p_end = buf_end;
BranchBlock *frame_csp_tmp; BranchBlock *frame_csp_tmp;
uint32 depth; uint32 depth;
read_leb_uint32(p, p_end, depth); read_leb_uint32(p, p_end, depth);
if (!wasm_loader_check_br(loader_ctx, depth, is_br_table, error_buf, if (!wasm_loader_check_br(loader_ctx, depth, opcode, error_buf,
error_buf_size)) { error_buf_size)) {
goto fail; goto fail;
} }
@ -6353,7 +6299,7 @@ re_scan:
case WASM_OP_BR: case WASM_OP_BR:
{ {
if (!(frame_csp_tmp = if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false, check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) error_buf, error_buf_size)))
goto fail; goto fail;
@ -6367,7 +6313,7 @@ re_scan:
POP_I32(); POP_I32();
if (!(frame_csp_tmp = if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false, check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) error_buf, error_buf_size)))
goto fail; goto fail;
@ -6397,7 +6343,7 @@ re_scan:
#endif #endif
for (i = 0; i <= count; i++) { for (i = 0; i <= count; i++) {
if (!(frame_csp_tmp = if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, true, check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) error_buf, error_buf_size)))
goto fail; goto fail;

View File

@ -4445,3 +4445,154 @@ wasm_propagate_wasi_args(WASMModule *module)
} }
} }
#endif #endif
bool
wasm_check_utf8_str(const uint8 *str, uint32 len)
{
/* The valid ranges are taken from page 125, below link
https://www.unicode.org/versions/Unicode9.0.0/ch03.pdf */
const uint8 *p = str, *p_end = str + len;
uint8 chr;
while (p < p_end) {
chr = *p;
if (chr == 0) {
LOG_WARNING(
"LIMITATION: a string which contains '\\00' is unsupported");
return false;
}
else if (chr < 0x80) {
p++;
}
else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) {
if (p[1] < 0x80 || p[1] > 0xBF) {
return false;
}
p += 2;
}
else if (chr >= 0xE0 && chr <= 0xEF && p + 2 < p_end) {
if (chr == 0xE0) {
if (p[1] < 0xA0 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
return false;
}
}
else if (chr == 0xED) {
if (p[1] < 0x80 || p[1] > 0x9F || p[2] < 0x80 || p[2] > 0xBF) {
return false;
}
}
else { /* chr >= 0xE1 && chr <= 0xEF */
if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
return false;
}
}
p += 3;
}
else if (chr >= 0xF0 && chr <= 0xF4 && p + 3 < p_end) {
if (chr == 0xF0) {
if (p[1] < 0x90 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
|| p[3] < 0x80 || p[3] > 0xBF) {
return false;
}
}
else if (chr <= 0xF3) { /* and also chr >= 0xF1 */
if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
|| p[3] < 0x80 || p[3] > 0xBF) {
return false;
}
}
else { /* chr == 0xF4 */
if (p[1] < 0x80 || p[1] > 0x8F || p[2] < 0x80 || p[2] > 0xBF
|| p[3] < 0x80 || p[3] > 0xBF) {
return false;
}
}
p += 4;
}
else {
return false;
}
}
return (p == p_end);
}
char *
wasm_const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module,
bool is_load_from_file_buf, char *error_buf,
uint32 error_buf_size)
{
StringNode *node, *node_next;
if (!wasm_check_utf8_str(str, len)) {
set_error_buf(error_buf, error_buf_size, "invalid UTF-8 encoding");
return NULL;
}
if (len == 0) {
return "";
}
else if (is_load_from_file_buf) {
/* As the file buffer can be referred to after loading, we use
the previous byte of leb encoded size to adjust the string:
move string 1 byte backward and then append '\0' */
char *c_str = (char *)str - 1;
bh_memmove_s(c_str, len + 1, c_str + 1, len);
c_str[len] = '\0';
return c_str;
}
/* Search const str list */
node = module->const_str_list;
while (node) {
node_next = node->next;
if (strlen(node->str) == len && !memcmp(node->str, str, len))
break;
node = node_next;
}
if (node) {
return node->str;
}
if (!(node = runtime_malloc(sizeof(StringNode) + len + 1, error_buf,
error_buf_size))) {
return NULL;
}
node->str = ((char *)node) + sizeof(StringNode);
bh_memcpy_s(node->str, len + 1, str, len);
node->str[len] = '\0';
if (!module->const_str_list) {
/* set as head */
module->const_str_list = node;
node->next = NULL;
}
else {
/* insert it */
node->next = module->const_str_list;
module->const_str_list = node;
}
return node->str;
}
bool
wasm_set_module_name(WASMModule *module, const char *name, char *error_buf,
uint32_t error_buf_size)
{
if (!name)
return false;
module->name =
wasm_const_str_list_insert((const uint8 *)name, strlen(name), module,
false, error_buf, error_buf_size);
return module->name != NULL;
}
const char *
wasm_get_module_name(WASMModule *module)
{
return module->name;
}

View File

@ -836,6 +836,21 @@ exception_unlock(WASMModuleInstance *module_inst);
#define exception_unlock(module_inst) (void)(module_inst) #define exception_unlock(module_inst) (void)(module_inst)
#endif #endif
bool
wasm_check_utf8_str(const uint8 *str, uint32 len);
char *
wasm_const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module,
bool is_load_from_file_buf, char *error_buf,
uint32 error_buf_size);
bool
wasm_set_module_name(WASMModule *module, const char *name, char *error_buf,
uint32_t error_buf_size);
const char *
wasm_get_module_name(WASMModule *module);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -8,6 +8,10 @@ add_definitions(-DBH_PLATFORM_NUTTX)
include_directories(${PLATFORM_SHARED_DIR}) include_directories(${PLATFORM_SHARED_DIR})
include_directories(${PLATFORM_SHARED_DIR}/../include) include_directories(${PLATFORM_SHARED_DIR}/../include)
include (${CMAKE_CURRENT_LIST_DIR}/../common/posix/platform_api_posix.cmake)
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c) file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
if (WAMR_BUILD_LIBC_WASI EQUAL 1) if (WAMR_BUILD_LIBC_WASI EQUAL 1)
@ -16,6 +20,7 @@ if (WAMR_BUILD_LIBC_WASI EQUAL 1)
set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE}) set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
endif () endif ()
include (${CMAKE_CURRENT_LIST_DIR}/../common/memory/platform_api_memory.cmake) set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE} ${PLATFORM_COMMON_POSIX_SOURCE} ${UNCOMMON_SHARED_SOURCE})
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE} ${PLATFORM_COMMON_MEMORY_SOURCE}) # remove posix_memmap.c for NuttX
list(REMOVE_ITEM ${PLATFORM_SHARED_SOURCE} ${PLATFORM_COMMON_POSIX_DIR}/posix_memmap.c)

View File

@ -51,9 +51,7 @@
#endif /* end of KERNEL_VERSION_NUMBER < 0x030200 */ #endif /* end of KERNEL_VERSION_NUMBER < 0x030200 */
#if KERNEL_VERSION_NUMBER >= 0x030300 /* version 3.3.0 */ #if KERNEL_VERSION_NUMBER >= 0x030300 /* version 3.3.0 */
#if defined(CONFIG_CPU_CORTEX_M7) && defined(CONFIG_ARM_MPU)
#include <zephyr/cache.h> #include <zephyr/cache.h>
#endif
#endif /* end of KERNEL_VERSION_NUMBER > 0x030300 */ #endif /* end of KERNEL_VERSION_NUMBER > 0x030300 */
#ifdef CONFIG_ARM_MPU #ifdef CONFIG_ARM_MPU
@ -177,4 +175,15 @@ os_get_invalid_handle()
return -1; return -1;
} }
static inline int
os_getpagesize()
{
#ifdef CONFIG_MMU
return CONFIG_MMU_PAGE_SIZE;
#else
/* Return a default page size if the MMU is not enabled */
return 4096; /* 4KB */
#endif
}
#endif #endif

View File

@ -25,9 +25,11 @@ disable_mpu_rasr_xn(void)
would most likely be set at index 2. */ would most likely be set at index 2. */
for (index = 0U; index < 8; index++) { for (index = 0U; index < 8; index++) {
MPU->RNR = index; MPU->RNR = index;
#ifdef MPU_RASR_XN_Msk
if (MPU->RASR & MPU_RASR_XN_Msk) { if (MPU->RASR & MPU_RASR_XN_Msk) {
MPU->RASR |= ~MPU_RASR_XN_Msk; MPU->RASR |= ~MPU_RASR_XN_Msk;
} }
#endif
} }
} }
#endif /* end of CONFIG_ARM_MPU */ #endif /* end of CONFIG_ARM_MPU */
@ -185,6 +187,12 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
return BH_MALLOC(size); return BH_MALLOC(size);
} }
void *
os_mremap(void *old_addr, size_t old_size, size_t new_size)
{
return os_mremap_slow(old_addr, old_size, new_size);
}
void void
os_munmap(void *addr, size_t size) os_munmap(void *addr, size_t size)
{ {

View File

@ -264,6 +264,10 @@ Currently we only profile the memory consumption of module, module_instance and
- **WAMR_BUILD_QUICK_AOT_ENTRY**=1/0, enable registering quick call entries to speedup the aot/jit func call process, default to enable if not set - **WAMR_BUILD_QUICK_AOT_ENTRY**=1/0, enable registering quick call entries to speedup the aot/jit func call process, default to enable if not set
> Note: See [Refine callings to AOT/JIT functions from host native](./perf_tune.md#83-refine-callings-to-aotjit-functions-from-host-native) for more details. > Note: See [Refine callings to AOT/JIT functions from host native](./perf_tune.md#83-refine-callings-to-aotjit-functions-from-host-native) for more details.
#### **Enable AOT intrinsics**
- **WAMR_BUILD_AOT_INTRINSICS**=1/0, enable the AOT intrinsic functions, default to enable if not set. These functions can be called from the AOT code when `--disable-llvm-intrinsics` flag or `--enable-builtin-intrinsics=<intr1,intr2,...>` flag is used by wamrc to generate the AOT file.
> Note: See [Tuning the XIP intrinsic functions](./xip.md#tuning-the-xip-intrinsic-functions) for more details.
#### **Configurale memory access boundary check** #### **Configurale memory access boundary check**
- **WAMR_CONFIGUABLE_BOUNDS_CHECKS**=1/0, default to disable if not set - **WAMR_CONFIGUABLE_BOUNDS_CHECKS**=1/0, default to disable if not set
> Note: If it is enabled, allow to run `iwasm --disable-bounds-checks` to disable the memory access boundary checks for interpreter mode. > Note: If it is enabled, allow to run `iwasm --disable-bounds-checks` to disable the memory access boundary checks for interpreter mode.

View File

@ -0,0 +1,199 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
# select platform configuration setting WAMR_BUILD_TARGET
set(WAMR_BUILD_PLATFORM nuttx)
if(CONFIG_ARCH_ARMV6M)
set(WAMR_BUILD_TARGET THUMBV6M)
elseif(CONFIG_ARCH_ARMV7A)
set(WAMR_BUILD_TARGET THUMBV7)
elseif(CONFIG_ARCH_ARMV7M)
set(WAMR_BUILD_TARGET THUMBV7EM)
elseif(CONFIG_ARCH_ARMV8M)
set(WAMR_BUILD_TARGET THUMBV8M)
elseif(CONFIG_ARCH_X86)
set(WAMR_BUILD_TARGET X86_32)
elseif(CONFIG_ARCH_X86_64)
set(WAMR_BUILD_TARGET X86_64)
elseif(CONFIG_ARCH_XTENSA)
set(WAMR_BUILD_TARGET XTENSA)
elseif(CONFIG_ARCH_RV64GC OR CONFIG_ARCH_RV64)
set(WAMR_BUILD_TARGET RISCV64)
elseif(CONFIG_ARCH_RV32IM OR CONFIG_ARCH_RV32)
set(WAMR_BUILD_TARGET RISCV32)
elseif(CONFIG_ARCH_SIM)
if(CONFIG_SIM_M32 OR CONFIG_HOST_X86)
set(WAMR_BUILD_TARGET X86_32)
elseif(CONFIG_HOST_ARM)
set(WAMR_BUILD_TARGET ARM)
elseif(CONFIG_HOST_ARM64)
set(WAMR_BUILD_TARGET AARCH64)
else()
set(WAMR_BUILD_TARGET X86_64)
endif()
if(CONFIG_HOST_MACOS)
add_definitions(-DBH_PLATFORM_DARWIN)
endif()
endif()
if(CONFIG_INTERPRETERS_WAMR_LOG)
add_definitions(-DWASM_ENABLE_LOG=1)
else()
add_definitions(-DWASM_ENABLE_LOG=0)
endif()
if(CONFIG_INTERPRETERS_WAMR_AOT_WORD_ALIGN_READ)
add_definitions(-DWASM_ENABLE_WORD_ALIGN_READ=1)
else()
add_definitions(-DWASM_ENABLE_WORD_ALIGN_READ=0)
endif()
if(CONFIG_INTERPRETERS_WAMR_STACK_GUARD_SIZE)
add_definitions(-DWASM_STACK_GUARD_SIZE=0)
else()
add_definitions(
-DWASM_STACK_GUARD_SIZE=${CONFIG_INTERPRETERS_WAMR_STACK_GUARD_SIZE})
endif()
if(CONFIG_INTERPRETERS_WAMR_MEMORY_TRACING)
add_definitions(-DWASM_ENABLE_MEMORY_TRACING=1)
else()
add_definitions(-DWASM_ENABLE_MEMORY_TRACING=0)
endif()
if(CONFIG_INTERPRETERS_WAMR_SHARED_MEMORY)
set(WAMR_BUILD_SHARED_MEMORY 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_BULK_MEMORY)
set(WAMR_BUILD_BULK_MEMORY 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_AOT_STACK_FRAME)
set(WAMR_BUILD_AOT_STACK_FRAME 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_PERF_PROFILING)
set(WAMR_BUILD_PERF_PROFILING 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_GC)
set(WAMR_BUILD_GC 1)
set(WAMR_BUILD_STRINGREF 1)
set(WAMR_BUILD_REF_TYPES 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_GC_MANUALLY)
add_definitions(-DWASM_GC_MANUALLY=1)
else()
add_definitions(-DWASM_GC_MANUALLY=0)
endif()
if(CONFIG_INTERPRETERS_WAMR_GC_PERF_PROFILING)
set(WAMR_BUILD_GC_PERF_PROFILING 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_ENABLE_EXCE_HANDLING)
set(WAMR_BUILD_EXCE_HANDLING 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_TAIL_CALL)
set(WAMR_BUILD_TAIL_CALL 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_MEMORY_PROFILING)
set(WAMR_BUILD_MEMORY_PROFILING 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_MULTI_MODULE)
set(WAMR_BUILD_MULTI_MODULE 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_LIB_PTHREAD_SEMAPHORE)
set(WAMR_BUILD_LIB_PTHREAD_SEMAPHORE 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_DISABLE_HW_BOUND_CHECK)
set(WAMR_DISABLE_HW_BOUND_CHECK 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_CUSTOM_NAME_SECTIONS)
set(WAMR_BUILD_CUSTOM_NAME_SECTION 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_GLOBAL_HEAP_POOL)
set(WAMR_BUILD_GLOBAL_HEAP_POOL 1)
math(EXPR _HEAP_SIZE_
"${CONFIG_INTERPRETERS_WAMR_GLOBAL_HEAP_POOL_SIZE} * 1024")
set(WAMR_BUILD_GLOBAL_HEAP_SIZE ${_HEAP_SIZE_})
endif()
if(CONFIG_INTERPRETERS_WAMR_ENABLE_SPEC_TEST)
set(WAMR_BUILD_SPEC_TEST 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_REF_TYPES)
set(WAMR_BUILD_REF_TYPES 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_CLASSIC)
# include iwasm_interp.cmake
set(WAMR_BUILD_INTERP 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_FAST)
# enable iwasm_interp.cmake
set(WAMR_BUILD_FAST_INTERP 1)
endif()
if((CONFIG_INTERPRETERS_WAMR_FAST OR CONFIG_INTERPRETERS_WAMR_CLASSIC)
AND CONFIG_INTERPRETERS_WAMR_MINILOADER)
# enable iwasm_interp.cmake
set(WAMR_BUILD_MINI_LOADER 1)
else()
set(WAMR_BUILD_MINI_LOADER 0)
endif()
if(CONFIG_INTERPRETERS_WAMR_AOT)
# include iwasm_aot.cmake
set(WAMR_BUILD_AOT 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_DEBUG_INTERP)
# include debug_engine.cmake
set(WAMR_BUILD_DEBUG_INTERP 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_LIBC_BUILTIN)
# include libc_builtin.cmake
set(WAMR_BUILD_LIBC_BUILTIN 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_LIBC_WASI)
# include libc_wasi.cmake
set(WAMR_BUILD_LIBC_WASI 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_THREAD_MGR)
# include thread_mgr.cmake
set(WAMR_BUILD_THREAD_MGR 1)
endif()
if(CONFIG_INTERPRETERS_WAMR_LIB_PTHREAD)
# include lib_pthread.cmake
set(WAMR_BUILD_LIB_PTHREAD 1)
endif()
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..)
# enable WAMR build system
include(${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
# NuttX wamr lib complie required: `WAMR_SOURCES` `WAMR_CFLAGS` `WAMR_INCDIRS`
# `WAMR_DEFINITIONS`
set(WAMR_SOURCES ${WAMR_RUNTIME_LIB_SOURCE})
set(WAMR_CFLAGS -Wno-strict-prototypes -Wno-shadow -Wno-unused-variable
-Wno-int-conversion -Wno-implicit-function-declaration)
get_directory_property(WAMR_INCDIRS INCLUDE_DIRECTORIES)
get_directory_property(WAMR_DEFINITIONS COMPILE_DEFINITIONS)

View File

@ -1,3 +1,4 @@
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -81,6 +82,8 @@ int main(int argc, const char* argv[]) {
wasm_byte_vec_delete(&binary); wasm_byte_vec_delete(&binary);
assert(wasm_module_set_name(module, "hello"));
// Create external print functions. // Create external print functions.
printf("Creating callback...\n"); printf("Creating callback...\n");
own wasm_functype_t* hello_type = wasm_functype_new_0_0(); own wasm_functype_t* hello_type = wasm_functype_new_0_0();
@ -117,6 +120,12 @@ int main(int argc, const char* argv[]) {
return 1; return 1;
} }
{
const char* name = wasm_module_get_name(module);
assert(strncmp(name, "hello", 5) == 0);
printf("> removing module %s \n", name);
}
wasm_module_delete(module); wasm_module_delete(module);
wasm_instance_delete(instance); wasm_instance_delete(instance);