Merge branch main into dev/wasi-libc-windows
This commit is contained in:
@ -312,7 +312,6 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name,
|
||||
#endif
|
||||
int32 i, p, module_type;
|
||||
uint64 total_size;
|
||||
const char *exception;
|
||||
char buf[128];
|
||||
|
||||
bh_assert(argc >= 0);
|
||||
@ -647,9 +646,7 @@ fail:
|
||||
if (argv1)
|
||||
wasm_runtime_free(argv1);
|
||||
|
||||
exception = wasm_runtime_get_exception(module_inst);
|
||||
bh_assert(exception);
|
||||
os_printf("%s\n", exception);
|
||||
bh_assert(wasm_runtime_get_exception(module_inst));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -298,10 +298,15 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_LOCK(memory_inst);
|
||||
|
||||
if (app_offset + size <= memory_inst->memory_data_size) {
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
|
||||
fail:
|
||||
wasm_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
@ -364,11 +369,16 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_LOCK(memory_inst);
|
||||
|
||||
if (memory_inst->memory_data <= addr
|
||||
&& addr + size <= memory_inst->memory_data_end) {
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
|
||||
fail:
|
||||
wasm_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
@ -393,20 +403,24 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_LOCK(memory_inst);
|
||||
|
||||
addr = memory_inst->memory_data + app_offset;
|
||||
|
||||
if (bounds_checks) {
|
||||
if (memory_inst->memory_data <= addr
|
||||
&& addr < memory_inst->memory_data_end) {
|
||||
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
/* If bounds checks is disabled, return the address directly */
|
||||
else if (app_offset != 0) {
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return addr;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -418,6 +432,7 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
|
||||
WASMMemoryInstance *memory_inst;
|
||||
uint8 *addr = (uint8 *)native_ptr;
|
||||
bool bounds_checks;
|
||||
uint32 ret;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
@ -429,16 +444,24 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_LOCK(memory_inst);
|
||||
|
||||
if (bounds_checks) {
|
||||
if (memory_inst->memory_data <= addr
|
||||
&& addr < memory_inst->memory_data_end)
|
||||
return (uint32)(addr - memory_inst->memory_data);
|
||||
&& addr < memory_inst->memory_data_end) {
|
||||
ret = (uint32)(addr - memory_inst->memory_data);
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
/* If bounds checks is disabled, return the offset directly */
|
||||
else if (addr != NULL) {
|
||||
return (uint32)(addr - memory_inst->memory_data);
|
||||
ret = (uint32)(addr - memory_inst->memory_data);
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -459,6 +482,8 @@ wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm,
|
||||
return false;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_LOCK(memory_inst);
|
||||
|
||||
memory_data_size = memory_inst->memory_data_size;
|
||||
|
||||
if (app_offset < memory_data_size) {
|
||||
@ -466,9 +491,11 @@ wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm,
|
||||
*p_app_start_offset = 0;
|
||||
if (p_app_end_offset)
|
||||
*p_app_end_offset = memory_data_size;
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -490,15 +517,19 @@ wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst_comm,
|
||||
return false;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_LOCK(memory_inst);
|
||||
|
||||
if (memory_inst->memory_data <= addr
|
||||
&& addr < memory_inst->memory_data_end) {
|
||||
if (p_native_start_addr)
|
||||
*p_native_start_addr = memory_inst->memory_data;
|
||||
if (p_native_end_addr)
|
||||
*p_native_end_addr = memory_inst->memory_data_end;
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -512,7 +543,8 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
|
||||
bool bounds_checks;
|
||||
|
||||
if (!memory_inst) {
|
||||
goto fail;
|
||||
wasm_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
}
|
||||
|
||||
native_addr = memory_inst->memory_data + app_buf_addr;
|
||||
@ -529,6 +561,8 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
|
||||
/* No need to check the app_offset and buf_size if memory access
|
||||
boundary check with hardware trap is enabled */
|
||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||
SHARED_MEMORY_LOCK(memory_inst);
|
||||
|
||||
if (app_buf_addr >= memory_inst->memory_data_size) {
|
||||
goto fail;
|
||||
}
|
||||
@ -549,14 +583,20 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
|
||||
if (str == str_end)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
#endif
|
||||
|
||||
success:
|
||||
*p_native_addr = (void *)native_addr;
|
||||
return true;
|
||||
|
||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||
fail:
|
||||
SHARED_MEMORY_UNLOCK(memory_inst);
|
||||
wasm_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
WASMMemoryInstance *
|
||||
@ -568,6 +608,27 @@ wasm_get_default_memory(WASMModuleInstance *module_inst)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory,
|
||||
uint64 memory_data_size)
|
||||
{
|
||||
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
memory->mem_bound_check_1byte.u64 = memory_data_size - 1;
|
||||
memory->mem_bound_check_2bytes.u64 = memory_data_size - 2;
|
||||
memory->mem_bound_check_4bytes.u64 = memory_data_size - 4;
|
||||
memory->mem_bound_check_8bytes.u64 = memory_data_size - 8;
|
||||
memory->mem_bound_check_16bytes.u64 = memory_data_size - 16;
|
||||
#else
|
||||
memory->mem_bound_check_1byte.u32[0] = (uint32)memory_data_size - 1;
|
||||
memory->mem_bound_check_2bytes.u32[0] = (uint32)memory_data_size - 2;
|
||||
memory->mem_bound_check_4bytes.u32[0] = (uint32)memory_data_size - 4;
|
||||
memory->mem_bound_check_8bytes.u32[0] = (uint32)memory_data_size - 8;
|
||||
memory->mem_bound_check_16bytes.u32[0] = (uint32)memory_data_size - 16;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||
bool
|
||||
wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
@ -625,9 +686,10 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
memory->num_bytes_per_page = num_bytes_per_page;
|
||||
memory->cur_page_count = total_page_count;
|
||||
memory->max_page_count = max_page_count;
|
||||
/* No need to update memory->memory_data_size as it is
|
||||
initialized with the maximum memory data size for
|
||||
shared memory */
|
||||
memory->memory_data_size = (uint32)total_size_new;
|
||||
memory->memory_data_end = memory->memory_data + (uint32)total_size_new;
|
||||
|
||||
wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -679,21 +741,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
memory->memory_data = memory_data_new;
|
||||
memory->memory_data_end = memory_data_new + (uint32)total_size_new;
|
||||
|
||||
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
memory->mem_bound_check_1byte.u64 = total_size_new - 1;
|
||||
memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
|
||||
memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
|
||||
memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
|
||||
memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
|
||||
#else
|
||||
memory->mem_bound_check_1byte.u32[0] = (uint32)total_size_new - 1;
|
||||
memory->mem_bound_check_2bytes.u32[0] = (uint32)total_size_new - 2;
|
||||
memory->mem_bound_check_4bytes.u32[0] = (uint32)total_size_new - 4;
|
||||
memory->mem_bound_check_8bytes.u32[0] = (uint32)total_size_new - 8;
|
||||
memory->mem_bound_check_16bytes.u32[0] = (uint32)total_size_new - 16;
|
||||
#endif
|
||||
#endif
|
||||
wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
|
||||
|
||||
#if defined(os_writegsbase)
|
||||
/* write base addr of linear memory to GS segment register */
|
||||
@ -799,13 +847,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
memory->memory_data_size = (uint32)total_size_new;
|
||||
memory->memory_data_end = memory->memory_data + (uint32)total_size_new;
|
||||
|
||||
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
|
||||
memory->mem_bound_check_1byte.u64 = total_size_new - 1;
|
||||
memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
|
||||
memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
|
||||
memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
|
||||
memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
|
||||
#endif
|
||||
wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
|
||||
|
||||
return_func:
|
||||
if (!ret && enlarge_memory_error_cb) {
|
||||
|
||||
@ -24,6 +24,10 @@ wasm_runtime_memory_destroy();
|
||||
unsigned
|
||||
wasm_runtime_memory_pool_size();
|
||||
|
||||
void
|
||||
wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory,
|
||||
uint64 memory_data_size);
|
||||
|
||||
void
|
||||
wasm_runtime_set_enlarge_mem_error_callback(
|
||||
const enlarge_memory_error_callback_t callback, void *user_data);
|
||||
|
||||
@ -542,8 +542,7 @@ void
|
||||
wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
|
||||
WASIContext *wasi_ctx)
|
||||
{
|
||||
return wasm_native_set_context(module_inst_comm, g_wasi_context_key,
|
||||
wasi_ctx);
|
||||
wasm_native_set_context(module_inst_comm, g_wasi_context_key, wasi_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -3037,6 +3037,74 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < map_dir_count; i++, wasm_fd++) {
|
||||
char mapping_copy_buf[256];
|
||||
char *mapping_copy = mapping_copy_buf;
|
||||
char *map_mapped = NULL, *map_host = NULL;
|
||||
const unsigned long max_len = strlen(map_dir_list[i]) * 2 + 3;
|
||||
|
||||
/* Allocation limit for runtime environments with reduced stack size */
|
||||
if (max_len > 256) {
|
||||
if (!(mapping_copy = wasm_runtime_malloc(max_len))) {
|
||||
snprintf(error_buf, error_buf_size,
|
||||
"error while allocating for directory mapping\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
bh_memcpy_s(mapping_copy, max_len, map_dir_list[i],
|
||||
(uint32)(strlen(map_dir_list[i]) + 1));
|
||||
map_mapped = strtok(mapping_copy, "::");
|
||||
map_host = strtok(NULL, "::");
|
||||
|
||||
if (!map_mapped || !map_host) {
|
||||
if (error_buf)
|
||||
snprintf(error_buf, error_buf_size,
|
||||
"error while pre-opening mapped directory: "
|
||||
"invalid map\n");
|
||||
if (mapping_copy != mapping_copy_buf)
|
||||
wasm_runtime_free(mapping_copy);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
path = os_realpath(map_host, resolved_path);
|
||||
if (!path) {
|
||||
if (error_buf)
|
||||
snprintf(error_buf, error_buf_size,
|
||||
"error while pre-opening mapped directory %s: %d\n",
|
||||
map_host, errno);
|
||||
if (mapping_copy != mapping_copy_buf)
|
||||
wasm_runtime_free(mapping_copy);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
__wasi_errno_t error = os_open_preopendir(path, &file_handle);
|
||||
if (error != __WASI_ESUCCESS) {
|
||||
if (error_buf)
|
||||
snprintf(error_buf, error_buf_size,
|
||||
"error while pre-opening mapped directory %s: %d\n",
|
||||
map_host, errno);
|
||||
if (mapping_copy != mapping_copy_buf)
|
||||
wasm_runtime_free(mapping_copy);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!fd_table_insert_existing(curfds, wasm_fd, file_handle, false)
|
||||
|| !fd_prestats_insert(prestats, map_mapped, wasm_fd)) {
|
||||
if (error_buf)
|
||||
snprintf(error_buf, error_buf_size,
|
||||
"error while pre-opening mapped directory %s: "
|
||||
"insertion failed\n",
|
||||
dir_list[i]);
|
||||
if (mapping_copy != mapping_copy_buf)
|
||||
wasm_runtime_free(mapping_copy);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (mapping_copy != mapping_copy_buf)
|
||||
wasm_runtime_free(mapping_copy);
|
||||
}
|
||||
|
||||
/* addr_pool(textual) -> apool */
|
||||
for (i = 0; i < addr_pool_size; i++) {
|
||||
char *cp, *address, *mask;
|
||||
@ -4361,10 +4429,12 @@ static V128FuncPtr invokeNative_V128 = (V128FuncPtr)(uintptr_t)invokeNative;
|
||||
|| defined(BUILD_TARGET_RISCV64_LP64) */
|
||||
#endif /* end of defined(_WIN32) || defined(_WIN32_) */
|
||||
|
||||
/* ASAN is not designed to work with custom stack unwind or other low-level \
|
||||
things. > Ignore a function that does some low-level magic. (e.g. walking \
|
||||
through the thread's stack bypassing the frame boundaries) */
|
||||
#if defined(__GNUC__)
|
||||
/*
|
||||
* ASAN is not designed to work with custom stack unwind or other low-level
|
||||
* things. Ignore a function that does some low-level magic. (e.g. walking
|
||||
* through the thread's stack bypassing the frame boundaries)
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__attribute__((no_sanitize_address))
|
||||
#endif
|
||||
bool
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "wasm_native.h"
|
||||
#include "../include/wasm_export.h"
|
||||
#include "../interpreter/wasm.h"
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
#if WASM_ENABLE_UVWASI == 0
|
||||
#include "posix.h"
|
||||
@ -43,15 +44,16 @@ extern "C" {
|
||||
|
||||
/* For STORE opcodes */
|
||||
#define STORE_I64 PUT_I64_TO_ADDR
|
||||
#define STORE_U32(addr, value) \
|
||||
do { \
|
||||
*(uint32 *)(addr) = (uint32)(value); \
|
||||
} while (0)
|
||||
#define STORE_U16(addr, value) \
|
||||
do { \
|
||||
*(uint16 *)(addr) = (uint16)(value); \
|
||||
} while (0)
|
||||
|
||||
static inline void
|
||||
STORE_U32(void *addr, uint32_t value)
|
||||
{
|
||||
*(uint32_t *)(addr) = (uint32_t)(value);
|
||||
}
|
||||
static inline void
|
||||
STORE_U16(void *addr, uint16_t value)
|
||||
{
|
||||
*(uint16_t *)(addr) = (uint16_t)(value);
|
||||
}
|
||||
/* For LOAD opcodes */
|
||||
#define LOAD_I64(addr) (*(int64 *)(addr))
|
||||
#define LOAD_F64(addr) (*(float64 *)(addr))
|
||||
@ -146,42 +148,42 @@ GET_F64_FROM_ADDR(uint32 *addr)
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STORE_U32(addr, value) \
|
||||
do { \
|
||||
uintptr_t addr_ = (uintptr_t)(addr); \
|
||||
union { \
|
||||
uint32 val; \
|
||||
uint16 u16[2]; \
|
||||
uint8 u8[4]; \
|
||||
} u; \
|
||||
if ((addr_ & (uintptr_t)3) == 0) \
|
||||
*(uint32 *)(addr) = (uint32)(value); \
|
||||
else { \
|
||||
u.val = (uint32)(value); \
|
||||
if ((addr_ & (uintptr_t)1) == 0) { \
|
||||
((uint16 *)(addr))[0] = u.u16[0]; \
|
||||
((uint16 *)(addr))[1] = u.u16[1]; \
|
||||
} \
|
||||
else { \
|
||||
((uint8 *)(addr))[0] = u.u8[0]; \
|
||||
((uint8 *)(addr))[1] = u.u8[1]; \
|
||||
((uint8 *)(addr))[2] = u.u8[2]; \
|
||||
((uint8 *)(addr))[3] = u.u8[3]; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STORE_U16(addr, value) \
|
||||
do { \
|
||||
union { \
|
||||
uint16 val; \
|
||||
uint8 u8[2]; \
|
||||
} u; \
|
||||
u.val = (uint16)(value); \
|
||||
((uint8 *)(addr))[0] = u.u8[0]; \
|
||||
((uint8 *)(addr))[1] = u.u8[1]; \
|
||||
} while (0)
|
||||
|
||||
static inline void
|
||||
STORE_U32(void *addr, uint32_t value)
|
||||
{
|
||||
uintptr_t addr_ = (uintptr_t)(addr);
|
||||
union {
|
||||
uint32_t val;
|
||||
uint16_t u16[2];
|
||||
uint8_t u8[4];
|
||||
} u;
|
||||
if ((addr_ & (uintptr_t)3) == 0)
|
||||
*(uint32_t *)(addr) = (uint32_t)(value);
|
||||
else {
|
||||
u.val = (uint32_t)(value);
|
||||
if ((addr_ & (uintptr_t)1) == 0) {
|
||||
((uint16_t *)(addr))[0] = u.u16[0];
|
||||
((uint16_t *)(addr))[1] = u.u16[1];
|
||||
}
|
||||
else {
|
||||
((uint8_t *)(addr))[0] = u.u8[0];
|
||||
((uint8_t *)(addr))[1] = u.u8[1];
|
||||
((uint8_t *)(addr))[2] = u.u8[2];
|
||||
((uint8_t *)(addr))[3] = u.u8[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
static inline void
|
||||
STORE_U16(void *addr, uint16_t value)
|
||||
{
|
||||
union {
|
||||
uint16_t val;
|
||||
uint8_t u8[2];
|
||||
} u;
|
||||
u.val = (uint16_t)(value);
|
||||
((uint8_t *)(addr))[0] = u.u8[0];
|
||||
((uint8_t *)(addr))[1] = u.u8[1];
|
||||
}
|
||||
/* For LOAD opcodes */
|
||||
static inline int64
|
||||
LOAD_I64(void *addr)
|
||||
@ -297,6 +299,14 @@ LOAD_I16(void *addr)
|
||||
|
||||
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
#define SHARED_MEMORY_LOCK(memory) shared_memory_lock(memory)
|
||||
#define SHARED_MEMORY_UNLOCK(memory) shared_memory_unlock(memory)
|
||||
#else
|
||||
#define SHARED_MEMORY_LOCK(memory) (void)0
|
||||
#define SHARED_MEMORY_UNLOCK(memory) (void)0
|
||||
#endif
|
||||
|
||||
typedef struct WASMModuleCommon {
|
||||
/* Module type, for module loaded from WASM bytecode binary,
|
||||
this field is Wasm_Module_Bytecode, and this structure should
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
* - If you care performance, it's better to make the interpreters
|
||||
* use atomic ops.
|
||||
*/
|
||||
static korp_mutex _shared_memory_lock;
|
||||
korp_mutex g_shared_memory_lock;
|
||||
|
||||
/* clang-format off */
|
||||
enum {
|
||||
@ -55,13 +55,13 @@ destroy_wait_info(void *wait_info);
|
||||
bool
|
||||
wasm_shared_memory_init()
|
||||
{
|
||||
if (os_mutex_init(&_shared_memory_lock) != 0)
|
||||
if (os_mutex_init(&g_shared_memory_lock) != 0)
|
||||
return false;
|
||||
/* wait map not exists, create new map */
|
||||
if (!(wait_map = bh_hash_map_create(32, true, (HashFunc)wait_address_hash,
|
||||
(KeyEqualFunc)wait_address_equal, NULL,
|
||||
destroy_wait_info))) {
|
||||
os_mutex_destroy(&_shared_memory_lock);
|
||||
os_mutex_destroy(&g_shared_memory_lock);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -71,79 +71,47 @@ void
|
||||
wasm_shared_memory_destroy()
|
||||
{
|
||||
bh_hash_map_destroy(wait_map);
|
||||
os_mutex_destroy(&_shared_memory_lock);
|
||||
os_mutex_destroy(&g_shared_memory_lock);
|
||||
}
|
||||
|
||||
uint32
|
||||
uint16
|
||||
shared_memory_inc_reference(WASMMemoryInstance *memory)
|
||||
{
|
||||
bh_assert(shared_memory_is_shared(memory));
|
||||
uint32 old;
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_lock(&_shared_memory_lock);
|
||||
uint16 old;
|
||||
#if BH_ATOMIC_16_IS_ATOMIC == 0
|
||||
os_mutex_lock(&g_shared_memory_lock);
|
||||
#endif
|
||||
old = BH_ATOMIC_32_FETCH_ADD(memory->ref_count, 1);
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_unlock(&_shared_memory_lock);
|
||||
old = BH_ATOMIC_16_FETCH_ADD(memory->ref_count, 1);
|
||||
#if BH_ATOMIC_16_IS_ATOMIC == 0
|
||||
os_mutex_unlock(&g_shared_memory_lock);
|
||||
#endif
|
||||
bh_assert(old >= 1);
|
||||
bh_assert(old < UINT32_MAX);
|
||||
bh_assert(old < UINT16_MAX);
|
||||
return old + 1;
|
||||
}
|
||||
|
||||
uint32
|
||||
uint16
|
||||
shared_memory_dec_reference(WASMMemoryInstance *memory)
|
||||
{
|
||||
bh_assert(shared_memory_is_shared(memory));
|
||||
uint32 old;
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_lock(&_shared_memory_lock);
|
||||
uint16 old;
|
||||
#if BH_ATOMIC_16_IS_ATOMIC == 0
|
||||
os_mutex_lock(&g_shared_memory_lock);
|
||||
#endif
|
||||
old = BH_ATOMIC_32_FETCH_SUB(memory->ref_count, 1);
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_unlock(&_shared_memory_lock);
|
||||
old = BH_ATOMIC_16_FETCH_SUB(memory->ref_count, 1);
|
||||
#if BH_ATOMIC_16_IS_ATOMIC == 0
|
||||
os_mutex_unlock(&g_shared_memory_lock);
|
||||
#endif
|
||||
bh_assert(old > 0);
|
||||
return old - 1;
|
||||
}
|
||||
|
||||
bool
|
||||
shared_memory_is_shared(WASMMemoryInstance *memory)
|
||||
{
|
||||
uint32 old;
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_lock(&_shared_memory_lock);
|
||||
#endif
|
||||
old = BH_ATOMIC_32_LOAD(memory->ref_count);
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_unlock(&_shared_memory_lock);
|
||||
#endif
|
||||
return old > 0;
|
||||
}
|
||||
|
||||
static korp_mutex *
|
||||
shared_memory_get_lock_pointer(WASMMemoryInstance *memory)
|
||||
{
|
||||
bh_assert(memory != NULL);
|
||||
return &_shared_memory_lock;
|
||||
}
|
||||
|
||||
void
|
||||
shared_memory_lock(WASMMemoryInstance *memory)
|
||||
{
|
||||
/*
|
||||
* Note: exception logic is currently abusing this lock.
|
||||
* cf. https://github.com/bytecodealliance/wasm-micro-runtime/issues/2407
|
||||
*/
|
||||
bh_assert(memory != NULL);
|
||||
os_mutex_lock(&_shared_memory_lock);
|
||||
}
|
||||
|
||||
void
|
||||
shared_memory_unlock(WASMMemoryInstance *memory)
|
||||
{
|
||||
bh_assert(memory != NULL);
|
||||
os_mutex_unlock(&_shared_memory_lock);
|
||||
return &g_shared_memory_lock;
|
||||
}
|
||||
|
||||
/* Atomics wait && notify APIs */
|
||||
@ -301,12 +269,15 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||
return -1;
|
||||
}
|
||||
|
||||
shared_memory_lock(module_inst->memories[0]);
|
||||
if ((uint8 *)address < module_inst->memories[0]->memory_data
|
||||
|| (uint8 *)address + (wait64 ? 8 : 4)
|
||||
> module_inst->memories[0]->memory_data_end) {
|
||||
shared_memory_unlock(module_inst->memories[0]);
|
||||
wasm_runtime_set_exception(module, "out of bounds memory access");
|
||||
return -1;
|
||||
}
|
||||
shared_memory_unlock(module_inst->memories[0]);
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
exec_env =
|
||||
@ -423,9 +394,11 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
|
||||
bh_assert(module->module_type == Wasm_Module_Bytecode
|
||||
|| module->module_type == Wasm_Module_AoT);
|
||||
|
||||
shared_memory_lock(module_inst->memories[0]);
|
||||
out_of_bounds =
|
||||
((uint8 *)address < module_inst->memories[0]->memory_data
|
||||
|| (uint8 *)address + 4 > module_inst->memories[0]->memory_data_end);
|
||||
shared_memory_unlock(module_inst->memories[0]);
|
||||
|
||||
if (out_of_bounds) {
|
||||
wasm_runtime_set_exception(module, "out of bounds memory access");
|
||||
|
||||
@ -14,26 +14,39 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern korp_mutex g_shared_memory_lock;
|
||||
|
||||
bool
|
||||
wasm_shared_memory_init();
|
||||
|
||||
void
|
||||
wasm_shared_memory_destroy();
|
||||
|
||||
uint32
|
||||
uint16
|
||||
shared_memory_inc_reference(WASMMemoryInstance *memory);
|
||||
|
||||
uint32
|
||||
uint16
|
||||
shared_memory_dec_reference(WASMMemoryInstance *memory);
|
||||
|
||||
bool
|
||||
shared_memory_is_shared(WASMMemoryInstance *memory);
|
||||
#define shared_memory_is_shared(memory) memory->is_shared_memory
|
||||
|
||||
void
|
||||
shared_memory_lock(WASMMemoryInstance *memory);
|
||||
#define shared_memory_lock(memory) \
|
||||
do { \
|
||||
/* \
|
||||
* Note: exception logic is currently abusing this lock. \
|
||||
* cf. \
|
||||
* https://github.com/bytecodealliance/wasm-micro-runtime/issues/2407 \
|
||||
*/ \
|
||||
bh_assert(memory != NULL); \
|
||||
if (memory->is_shared_memory) \
|
||||
os_mutex_lock(&g_shared_memory_lock); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
shared_memory_unlock(WASMMemoryInstance *memory);
|
||||
#define shared_memory_unlock(memory) \
|
||||
do { \
|
||||
if (memory->is_shared_memory) \
|
||||
os_mutex_unlock(&g_shared_memory_lock); \
|
||||
} while (0)
|
||||
|
||||
uint32
|
||||
wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||
|
||||
Reference in New Issue
Block a user