Merge branch main into dev/wasi-libc-windows

This commit is contained in:
Wenyong Huang
2023-08-23 17:05:19 +08:00
77 changed files with 1903 additions and 588 deletions

View File

@ -2290,8 +2290,10 @@ quit:
bool
wasm_module_validate(wasm_store_t *store, const wasm_byte_vec_t *binary)
{
wasm_byte_vec_t local_binary = { 0 };
struct WASMModuleCommon *module_rt;
char error_buf[128] = { 0 };
bool ret;
bh_assert(singleton_engine);
@ -2300,15 +2302,25 @@ wasm_module_validate(wasm_store_t *store, const wasm_byte_vec_t *binary)
return false;
}
if ((module_rt = wasm_runtime_load((uint8 *)binary->data,
(uint32)binary->size, error_buf, 128))) {
/* make a copy of binary */
wasm_byte_vec_copy(&local_binary, binary);
if (binary->size && !local_binary.data)
return false;
module_rt = wasm_runtime_load((uint8 *)local_binary.data,
(uint32)local_binary.size, error_buf, 128);
wasm_byte_vec_delete(&local_binary);
if (module_rt) {
wasm_runtime_unload(module_rt);
return true;
ret = true;
}
else {
ret = false;
LOG_VERBOSE(error_buf);
return false;
}
return ret;
}
static void
@ -4858,7 +4870,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
if (instance->inst_comm_rt->module_type == Wasm_Module_Bytecode) {
WASMModuleInstanceExtra *e =
((WASMModuleInstance *)instance->inst_comm_rt)->e;
p_func_imports = &(e->c_api_func_imports);
p_func_imports = &(e->common.c_api_func_imports);
import_func_count = MODULE_INTERP(module)->import_function_count;
}
#endif
@ -4868,7 +4880,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
(AOTModuleInstanceExtra *)((AOTModuleInstance *)
instance->inst_comm_rt)
->e;
p_func_imports = &(e->c_api_func_imports);
p_func_imports = &(e->common.c_api_func_imports);
import_func_count = MODULE_AOT(module)->import_func_count;
}
#endif

View File

@ -199,7 +199,90 @@ runtime_signal_handler(void *sig_addr)
}
}
}
#else
#else /* else of BH_PLATFORM_WINDOWS */
#if WASM_ENABLE_AOT != 0
#include <Zydis/Zydis.h>
static uint32
decode_insn(uint8 *insn)
{
uint8 *data = (uint8 *)insn;
uint32 length = 32; /* reserve enough size */
/* Initialize decoder context */
ZydisDecoder decoder;
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64,
ZYDIS_STACK_WIDTH_64);
/* Initialize formatter */
ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
/* Loop over the instructions in our buffer */
ZyanU64 runtime_address = (ZyanU64)(uintptr_t)data;
ZyanUSize offset = 0;
ZydisDecodedInstruction instruction;
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT_VISIBLE];
char buffer[256];
if (ZYAN_SUCCESS(ZydisDecoderDecodeFull(
&decoder, data + offset, length - offset, &instruction, operands,
ZYDIS_MAX_OPERAND_COUNT_VISIBLE,
ZYDIS_DFLAG_VISIBLE_OPERANDS_ONLY))) {
/* Format & print the binary instruction structure to
human readable format */
ZydisFormatterFormatInstruction(&formatter, &instruction, operands,
instruction.operand_count_visible,
buffer, sizeof(buffer),
runtime_address);
/* Print current instruction */
/*
os_printf("%012" PRIX64 " ", runtime_address);
puts(buffer);
*/
return instruction.length;
}
/* Decode failed */
return 0;
}
#endif /* end of WASM_ENABLE_AOT != 0 */
static LONG
next_action(WASMModuleInstance *module_inst, EXCEPTION_POINTERS *exce_info)
{
#if WASM_ENABLE_AOT != 0
uint32 insn_size;
#endif
if (module_inst->module_type == Wasm_Module_Bytecode
&& module_inst->e->running_mode == Mode_Interp) {
/* Continue to search next exception handler for
interpreter mode as it can be caught by
`__try { .. } __except { .. }` sentences in
wasm_runtime.c */
return EXCEPTION_CONTINUE_SEARCH;
}
#if WASM_ENABLE_AOT != 0
/* Skip current instruction and continue to run for AOT/JIT mode.
TODO: implement unwind support for AOT/JIT code in Windows platform */
insn_size = decode_insn((uint8 *)exce_info->ContextRecord->Rip);
if (insn_size > 0) {
exce_info->ContextRecord->Rip += insn_size;
return EXCEPTION_CONTINUE_EXECUTION;
}
#endif
/* return different value from EXCEPTION_CONTINUE_SEARCH (= 0)
and EXCEPTION_CONTINUE_EXECUTION (= -1) */
return -2;
}
static LONG
runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
{
@ -211,6 +294,7 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
uint8 *mapped_mem_start_addr = NULL;
uint8 *mapped_mem_end_addr = NULL;
uint32 page_size = os_getpagesize();
LONG ret;
if (exec_env_tls && exec_env_tls->handle == os_self_thread()
&& (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) {
@ -232,32 +316,19 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
the wasm func returns, the caller will check whether the
exception is thrown and return to runtime. */
wasm_set_exception(module_inst, "out of bounds memory access");
if (module_inst->module_type == Wasm_Module_Bytecode) {
/* Continue to search next exception handler for
interpreter mode as it can be caught by
`__try { .. } __except { .. }` sentences in
wasm_runtime.c */
return EXCEPTION_CONTINUE_SEARCH;
}
else {
/* Skip current instruction and continue to run for
AOT mode. TODO: implement unwind support for AOT
code in Windows platform */
exce_info->ContextRecord->Rip++;
return EXCEPTION_CONTINUE_EXECUTION;
}
ret = next_action(module_inst, exce_info);
if (ret == EXCEPTION_CONTINUE_SEARCH
|| ret == EXCEPTION_CONTINUE_EXECUTION)
return ret;
}
else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr
&& (uint8 *)sig_addr
< exec_env_tls->exce_check_guard_page + page_size) {
bh_assert(wasm_copy_exception(module_inst, NULL));
if (module_inst->module_type == Wasm_Module_Bytecode) {
return EXCEPTION_CONTINUE_SEARCH;
}
else {
exce_info->ContextRecord->Rip++;
return EXCEPTION_CONTINUE_EXECUTION;
}
ret = next_action(module_inst, exce_info);
if (ret == EXCEPTION_CONTINUE_SEARCH
|| ret == EXCEPTION_CONTINUE_EXECUTION)
return ret;
}
}
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
@ -267,12 +338,10 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
whether the exception is thrown and return to runtime, and
the damaged stack will be recovered by _resetstkoflw(). */
wasm_set_exception(module_inst, "native stack overflow");
if (module_inst->module_type == Wasm_Module_Bytecode) {
return EXCEPTION_CONTINUE_SEARCH;
}
else {
return EXCEPTION_CONTINUE_EXECUTION;
}
ret = next_action(module_inst, exce_info);
if (ret == EXCEPTION_CONTINUE_SEARCH
|| ret == EXCEPTION_CONTINUE_EXECUTION)
return ret;
}
#endif
}
@ -2491,14 +2560,14 @@ wasm_runtime_set_bounds_checks(WASMModuleInstanceCommon *module_inst,
#if WASM_ENABLE_INTERP != 0
if (module_inst->module_type == Wasm_Module_Bytecode) {
((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e)
->disable_bounds_checks = enable ? false : true;
->common.disable_bounds_checks = enable ? false : true;
}
#endif
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)
->disable_bounds_checks = enable ? false : true;
->common.disable_bounds_checks = enable ? false : true;
}
#endif
}
@ -2511,7 +2580,7 @@ wasm_runtime_is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst)
if (module_inst->module_type == Wasm_Module_Bytecode) {
return !((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)
->e)
->disable_bounds_checks;
->common.disable_bounds_checks;
}
#endif
@ -2519,7 +2588,7 @@ wasm_runtime_is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst)
if (module_inst->module_type == Wasm_Module_AoT) {
return !((AOTModuleInstanceExtra *)((WASMModuleInstance *)module_inst)
->e)
->disable_bounds_checks;
->common.disable_bounds_checks;
}
#endif
@ -4692,6 +4761,8 @@ typedef struct ExternRefMapNode {
bool retained;
/* Whether it is marked by runtime */
bool marked;
/* cleanup function called when the externref is freed */
void (*cleanup)(void *);
} ExternRefMapNode;
static uint32
@ -4754,6 +4825,81 @@ lookup_extobj_callback(void *key, void *value, void *user_data)
}
}
static void
delete_externref(void *key, ExternRefMapNode *node)
{
bh_hash_map_remove(externref_map, key, NULL, NULL);
if (node->cleanup) {
(*node->cleanup)(node->extern_obj);
}
wasm_runtime_free(node);
}
static void
delete_extobj_callback(void *key, void *value, void *user_data)
{
ExternRefMapNode *node = (ExternRefMapNode *)value;
LookupExtObj_UserData *lookup_user_data =
(LookupExtObj_UserData *)user_data;
if (node->extern_obj == lookup_user_data->node.extern_obj
&& node->module_inst == lookup_user_data->node.module_inst) {
lookup_user_data->found = true;
delete_externref(key, node);
}
}
bool
wasm_externref_objdel(WASMModuleInstanceCommon *module_inst, void *extern_obj)
{
LookupExtObj_UserData lookup_user_data = { 0 };
bool ok = false;
/* in a wrapper, extern_obj could be any value */
lookup_user_data.node.extern_obj = extern_obj;
lookup_user_data.node.module_inst = module_inst;
lookup_user_data.found = false;
os_mutex_lock(&externref_lock);
/* Lookup hashmap firstly */
bh_hash_map_traverse(externref_map, delete_extobj_callback,
(void *)&lookup_user_data);
if (lookup_user_data.found) {
ok = true;
}
os_mutex_unlock(&externref_lock);
return ok;
}
bool
wasm_externref_set_cleanup(WASMModuleInstanceCommon *module_inst,
void *extern_obj, void (*extern_obj_cleanup)(void *))
{
LookupExtObj_UserData lookup_user_data = { 0 };
bool ok = false;
/* in a wrapper, extern_obj could be any value */
lookup_user_data.node.extern_obj = extern_obj;
lookup_user_data.node.module_inst = module_inst;
lookup_user_data.found = false;
os_mutex_lock(&externref_lock);
/* Lookup hashmap firstly */
bh_hash_map_traverse(externref_map, lookup_extobj_callback,
(void *)&lookup_user_data);
if (lookup_user_data.found) {
void *key = (void *)(uintptr_t)lookup_user_data.externref_idx;
ExternRefMapNode *node = bh_hash_map_find(externref_map, key);
node->cleanup = extern_obj_cleanup;
ok = true;
}
os_mutex_unlock(&externref_lock);
return ok;
}
bool
wasm_externref_obj2ref(WASMModuleInstanceCommon *module_inst, void *extern_obj,
uint32 *p_externref_idx)
@ -4803,6 +4949,7 @@ wasm_externref_obj2ref(WASMModuleInstanceCommon *module_inst, void *extern_obj,
memset(node, 0, sizeof(ExternRefMapNode));
node->extern_obj = extern_obj;
node->module_inst = module_inst;
node->cleanup = NULL;
externref_idx = externref_global_id;
@ -4853,8 +5000,7 @@ reclaim_extobj_callback(void *key, void *value, void *user_data)
if (node->module_inst == module_inst) {
if (!node->marked && !node->retained) {
bh_hash_map_remove(externref_map, key, NULL, NULL);
wasm_runtime_free(value);
delete_externref(key, node);
}
else {
node->marked = false;
@ -4969,8 +5115,7 @@ cleanup_extobj_callback(void *key, void *value, void *user_data)
(WASMModuleInstanceCommon *)user_data;
if (node->module_inst == module_inst) {
bh_hash_map_remove(externref_map, key, NULL, NULL);
wasm_runtime_free(value);
delete_externref(key, node);
}
}