Merge branch main into dev/wasi-libc-windows
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user