From b40e79c160d41dbf51bbdab7d410380dfb8a2fb4 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Mon, 13 Apr 2020 10:49:40 +0800 Subject: [PATCH] Make heap and linear memory contiguous to refine compilation time and footprint (#233) Use FastISel for JIT mode Use united aot version in aot file and aot runtime Disable check signature failed warning for wamrc Fix fast interpreter x86_32 float issue Remove unused empty lvgl folder --- core/config.h | 10 +- core/iwasm/aot/aot_runtime.c | 306 +++++++++--------- core/iwasm/aot/aot_runtime.h | 21 +- core/iwasm/common/wasm_native.c | 2 + core/iwasm/common/wasm_runtime_common.c | 39 ++- core/iwasm/common/wasm_runtime_common.h | 10 +- core/iwasm/compilation/aot_emit_aot_file.c | 3 +- core/iwasm/compilation/aot_emit_function.c | 127 ++++---- core/iwasm/compilation/aot_emit_memory.c | 254 ++++++--------- core/iwasm/compilation/aot_emit_variable.c | 2 +- core/iwasm/compilation/aot_llvm.c | 172 +++++----- core/iwasm/compilation/aot_llvm.h | 19 +- core/iwasm/interpreter/wasm_interp_classic.c | 41 +-- core/iwasm/interpreter/wasm_interp_fast.c | 95 ++++-- core/iwasm/interpreter/wasm_loader.c | 50 +-- core/iwasm/interpreter/wasm_runtime.c | 206 ++++++------ core/iwasm/interpreter/wasm_runtime.h | 18 +- .../libraries/libc-wasi/libc_wasi_wrapper.c | 182 +++++++---- core/shared/mem-alloc/ems/ems_alloc.c | 31 +- core/shared/mem-alloc/ems/ems_gc.h | 29 ++ core/shared/mem-alloc/ems/ems_gc_internal.h | 1 - core/shared/mem-alloc/ems/ems_kfc.c | 64 +++- core/shared/mem-alloc/mem_alloc.c | 42 +++ core/shared/mem-alloc/mem_alloc.h | 10 + doc/build_wasm_app.md | 2 +- .../platforms/zephyr/simple/build_and_run.sh | 0 .../src/platform/linux/iwasm_main.c | 2 +- 27 files changed, 983 insertions(+), 755 deletions(-) mode change 100644 => 100755 product-mini/platforms/zephyr/simple/build_and_run.sh diff --git a/core/config.h b/core/config.h index be9a2418..29ebe27e 100644 --- a/core/config.h +++ b/core/config.h @@ -61,6 +61,9 @@ enum { #define WASM_ENABLE_AOT 0 #endif +#define AOT_MAGIC_NUMBER 0x746f6100 +#define AOT_CURRENT_VERSION 1 + #ifndef WASM_ENABLE_JIT #define WASM_ENABLE_JIT 0 #endif @@ -147,9 +150,6 @@ enum { /* Default watchdog interval in ms */ #define DEFAULT_WATCHDOG_INTERVAL (3 * 60 * 1000) -/* Support memory.grow opcode and enlargeMemory function */ -#define WASM_ENABLE_MEMORY_GROW 1 - /* The max percentage of global heap that app memory space can grow */ #define APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT 1 / 3 @@ -183,5 +183,9 @@ enum { #define BLOCK_ADDR_CACHE_SIZE 64 #define BLOCK_ADDR_CONFLICT_SIZE 2 +#ifndef WASM_ENABLE_SPEC_TEST +#define WASM_ENABLE_SPEC_TEST 0 +#endif + #endif /* end of _CONFIG_H_ */ diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index c9397460..09b1a38d 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -107,29 +107,64 @@ table_instantiate(AOTModuleInstance *module_inst, AOTModule *module, static bool memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module, - char *error_buf, uint32 error_buf_size) + uint32 heap_size, char *error_buf, uint32 error_buf_size) { uint32 i, global_index, global_data_offset, base_offset, length; AOTMemInitData *data_seg; - uint64 total_size = (uint64)module->num_bytes_per_page * module->mem_init_page_count; + void *heap_handle; + uint64 memory_data_size = (uint64)module->num_bytes_per_page + * module->mem_init_page_count; + uint64 total_size = heap_size + memory_data_size; + uint8 *p; /* Allocate memory */ if (total_size >= UINT32_MAX - || !(module_inst->memory_data.ptr = wasm_runtime_malloc((uint32)total_size))) { + || !(p = wasm_runtime_malloc((uint32)total_size))) { set_error_buf(error_buf, error_buf_size, "AOT module instantiate failed: allocate memory failed."); return false; } - memset(module_inst->memory_data.ptr, 0, (uint32)total_size); + memset(p, 0, (uint32)total_size); + + /* Initialize heap info */ + module_inst->heap_data.ptr = p; + p += heap_size; + module_inst->heap_data_end.ptr = p; + if (!(heap_handle = mem_allocator_create(module_inst->heap_data.ptr, + heap_size))) { + set_error_buf(error_buf, error_buf_size, + "AOT module instantiate failed: init app heap failed."); + goto fail1; + } + module_inst->heap_handle.ptr = heap_handle; + module_inst->heap_data_size = heap_size; +#if WASM_ENABLE_SPEC_TEST == 0 + module_inst->heap_base_offset = -(int32)heap_size; +#else + module_inst->heap_base_offset = 0; +#endif /* Init memory info */ - module_inst->memory_data_end.ptr = (uint8*)module_inst->memory_data.ptr - + total_size; - module_inst->memory_data_size = (uint32)total_size; + module_inst->memory_data.ptr = p; + p += (uint32)memory_data_size; + module_inst->memory_data_end.ptr = p; + module_inst->memory_data_size = (uint32)memory_data_size; +#if WASM_ENABLE_SPEC_TEST == 0 + module_inst->total_mem_size = (uint32)(heap_size + memory_data_size); +#else + module_inst->total_mem_size = (uint32)memory_data_size; +#endif module_inst->mem_cur_page_count = module->mem_init_page_count; module_inst->mem_max_page_count = module->mem_max_page_count; + if (module_inst->total_mem_size > 0) { + module_inst->mem_bound_check_1byte = module_inst->total_mem_size - 1; + module_inst->mem_bound_check_2bytes = module_inst->total_mem_size - 2; + module_inst->mem_bound_check_4bytes = module_inst->total_mem_size - 4; + module_inst->mem_bound_check_8bytes = module_inst->total_mem_size - 8; + } + if (module->mem_init_page_count > 0) { for (i = 0; i < module->mem_init_data_count; i++) { data_seg = module->mem_init_data_list[i]; @@ -165,11 +200,9 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module, if (length > 0 && (base_offset >= module_inst->memory_data_size || base_offset + length > module_inst->memory_data_size)) { - wasm_runtime_free(module_inst->memory_data.ptr); - module_inst->memory_data.ptr = NULL; set_error_buf(error_buf, error_buf_size, "AOT module instantiate failed: data segment out of range."); - return false; + goto fail2; } /* Copy memory data */ @@ -179,6 +212,14 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module, } return true; + +fail2: + mem_allocator_destroy(module_inst->heap_handle.ptr); + module_inst->heap_handle.ptr = NULL; +fail1: + wasm_runtime_free(module_inst->heap_data.ptr); + module_inst->heap_data.ptr = NULL; + return false; } static bool @@ -285,12 +326,11 @@ aot_instantiate(AOTModule *module, { AOTModuleInstance *module_inst; uint32 module_inst_struct_size = - offsetof(AOTModuleInstance, global_table_heap_data.bytes); + offsetof(AOTModuleInstance, global_table_data.bytes); uint64 table_data_size = (uint64)module->table_size * sizeof(uint32); uint64 total_size = (uint64)module_inst_struct_size + module->global_data_size - + table_data_size + heap_size; - void *heap_handle; + + table_data_size; uint8 *p; /* Check heap size */ @@ -330,27 +370,9 @@ aot_instantiate(AOTModule *module, if (!table_instantiate(module_inst, module, error_buf, error_buf_size)) goto fail; - /* Initialize heap info */ - p += (uint32)table_data_size; - module_inst->heap_data.ptr = p; - p += heap_size; - module_inst->heap_data_end.ptr = p; - module_inst->heap_data_size = heap_size; -#if WASM_ENABLE_MEMORY_GROW != 0 - module_inst->heap_base_offset = DEFAULT_APP_HEAP_BASE_OFFSET; -#else - module_inst->heap_base_offset = module_inst->memory_data_size; -#endif - if (!(heap_handle = mem_allocator_create(module_inst->heap_data.ptr, - heap_size))) { - set_error_buf(error_buf, error_buf_size, - "AOT module instantiate failed: init app heap failed."); - goto fail; - } - module_inst->heap_handle.ptr = heap_handle; - /* Initialize memory space */ - if (!memory_instantiate(module_inst, module, error_buf, error_buf_size)) + if (!memory_instantiate(module_inst, module, heap_size, + error_buf, error_buf_size)) goto fail; /* Initialize function pointers */ @@ -378,6 +400,10 @@ aot_instantiate(AOTModule *module, /* Initialize the thread related data */ if (stack_size == 0) stack_size = DEFAULT_WASM_STACK_SIZE; +#if WASM_ENABLE_SPEC_TEST != 0 + if (stack_size < 48 *1024) + stack_size = 48 * 1024; +#endif module_inst->default_wasm_stack_size = stack_size; /* Execute __post_instantiate function and start function*/ @@ -406,12 +432,12 @@ aot_deinstantiate(AOTModuleInstance *module_inst) wasm_runtime_destroy_wasi((WASMModuleInstanceCommon*)module_inst); #endif - if (module_inst->memory_data.ptr) - wasm_runtime_free(module_inst->memory_data.ptr); - if (module_inst->heap_handle.ptr) mem_allocator_destroy(module_inst->heap_handle.ptr); + if (module_inst->heap_data.ptr) + wasm_runtime_free(module_inst->heap_data.ptr); + if (module_inst->func_ptrs.ptr) wasm_runtime_free(module_inst->func_ptrs.ptr); @@ -554,27 +580,23 @@ int32 aot_module_malloc(AOTModuleInstance *module_inst, uint32 size, void **p_native_addr) { - uint8 *addr = - mem_allocator_malloc(module_inst->heap_handle.ptr, size); - - if (p_native_addr) - *p_native_addr = addr; + uint8 *addr = mem_allocator_malloc(module_inst->heap_handle.ptr, size); if (!addr) { aot_set_exception(module_inst, "out of memory"); return 0; } - return (int32)(module_inst->heap_base_offset - + (addr - (uint8*)module_inst->heap_data.ptr)); + if (p_native_addr) + *p_native_addr = addr; + return (int32)(addr - (uint8*)module_inst->memory_data.ptr); } void aot_module_free(AOTModuleInstance *module_inst, int32 ptr) { if (ptr) { - uint8 *addr = (uint8*)module_inst->heap_data.ptr - + (ptr - module_inst->heap_base_offset); + uint8 *addr = (uint8*)module_inst->memory_data.ptr + ptr; if ((uint8*)module_inst->heap_data.ptr < addr - && addr < (uint8*)module_inst->heap_data_end.ptr) + && addr < (uint8*)module_inst->memory_data.ptr) mem_allocator_free(module_inst->heap_handle.ptr, addr); } } @@ -598,34 +620,16 @@ bool aot_validate_app_addr(AOTModuleInstance *module_inst, int32 app_offset, uint32 size) { - uint8 *addr; - /* integer overflow check */ if(app_offset + (int32)size < app_offset) { goto fail; } - if (0 <= app_offset - && app_offset < (int32)module_inst->memory_data_size) { - addr = (uint8*)module_inst->memory_data.ptr + app_offset; - if (!((uint8*)module_inst->memory_data.ptr <= addr - && addr + size <= (uint8*)module_inst->memory_data_end.ptr)) - goto fail; - return true; + if (app_offset <= module_inst->heap_base_offset + || app_offset + (int32)size > (int32)module_inst->memory_data_size) { + goto fail; } - /* Currently heap_size is no more than 1G, and heap_base_offset is 1G, - heap_base_offset + heap_data_size will not be larger than INT32_MAX */ - else if (module_inst->heap_base_offset < app_offset - && app_offset < module_inst->heap_base_offset - + (int32)module_inst->heap_data_size) { - addr = (uint8*)module_inst->heap_data.ptr - + (app_offset - module_inst->heap_base_offset); - if (!((uint8*)module_inst->heap_data.ptr <= addr - && addr + size <= (uint8*)module_inst->heap_data_end.ptr)) - goto fail; - return true; - } - + return true; fail: aot_set_exception(module_inst, "out of bounds memory access"); return false; @@ -635,20 +639,20 @@ bool aot_validate_native_addr(AOTModuleInstance *module_inst, void *native_ptr, uint32 size) { - uint8 *addr = native_ptr; + uint8 *addr = (uint8*)native_ptr; + int32 memory_data_size = (int32)module_inst->memory_data_size; /* integer overflow check */ if (addr + size < addr) { goto fail; } - if (((uint8*)module_inst->memory_data.ptr <= addr - && addr + size <= (uint8*)module_inst->memory_data_end.ptr) - || ((uint8*)module_inst->heap_data.ptr <= addr - && addr + size <= (uint8*)module_inst->heap_data_end.ptr) - ) - return true; - + if (addr <= (uint8*)module_inst->heap_data.ptr + || addr + size > (uint8*)module_inst->memory_data.ptr + + memory_data_size) { + goto fail; + } + return true; fail: aot_set_exception(module_inst, "out of bounds memory access"); return false; @@ -657,30 +661,24 @@ fail: void * aot_addr_app_to_native(AOTModuleInstance *module_inst, int32 app_offset) { - if (0 <= app_offset && app_offset < module_inst->heap_base_offset) - return (uint8*)module_inst->memory_data.ptr + app_offset; + int32 memory_data_size = (int32)module_inst->memory_data_size; if (module_inst->heap_base_offset < app_offset - && app_offset < module_inst->heap_base_offset - + (int32)module_inst->heap_data_size) - return (uint8*)module_inst->heap_data.ptr - + (app_offset - module_inst->heap_base_offset); - + && app_offset < memory_data_size) + return (uint8*)module_inst->memory_data.ptr + app_offset; return NULL; } int32 aot_addr_native_to_app(AOTModuleInstance *module_inst, void *native_ptr) { - if ((uint8*)module_inst->memory_data.ptr <= (uint8*)native_ptr - && (uint8*)native_ptr < (uint8*)module_inst->memory_data_end.ptr) - return (int32)((uint8*)native_ptr - (uint8*)module_inst->memory_data.ptr); - - if ((uint8*)module_inst->heap_data.ptr <= (uint8*)native_ptr - && (uint8*)native_ptr < (uint8*)module_inst->heap_data_end.ptr) - return (int32)(module_inst->heap_base_offset - + ((uint8*)native_ptr - (uint8*)module_inst->heap_data.ptr)); + uint8 *addr = (uint8*)native_ptr; + int32 memory_data_size = (int32)module_inst->memory_data_size; + if ((uint8*)module_inst->heap_data.ptr < addr + && addr < (uint8*)module_inst->memory_data.ptr + + memory_data_size) + return (int32)(addr - (uint8*)module_inst->memory_data.ptr); return 0; } @@ -690,27 +688,17 @@ aot_get_app_addr_range(AOTModuleInstance *module_inst, int32 *p_app_start_offset, int32 *p_app_end_offset) { - int32 app_start_offset, app_end_offset; + int32 memory_data_size = (int32)module_inst->memory_data_size; - if (0 <= app_offset && app_offset < (int32)module_inst->memory_data_size) { - app_start_offset = 0; - app_end_offset = (int32)module_inst->memory_data_size; + if (module_inst->heap_base_offset < app_offset + && app_offset < memory_data_size) { + if (p_app_start_offset) + *p_app_start_offset = module_inst->heap_base_offset; + if (p_app_end_offset) + *p_app_end_offset = memory_data_size; + return true; } - else if (module_inst->heap_base_offset < app_offset - && app_offset < module_inst->heap_base_offset - + (int32)module_inst->heap_data_size) { - app_start_offset = module_inst->heap_base_offset; - app_end_offset = module_inst->heap_base_offset - + (int32)module_inst->heap_data_size; - } - else - return false; - - if (p_app_start_offset) - *p_app_start_offset = app_start_offset; - if (p_app_end_offset) - *p_app_end_offset = app_end_offset; - return true; + return false; } bool @@ -719,39 +707,37 @@ aot_get_native_addr_range(AOTModuleInstance *module_inst, uint8 **p_native_start_addr, uint8 **p_native_end_addr) { - uint8 *native_start_addr, *native_end_addr; + uint8 *addr = (uint8*)native_ptr; + int32 memory_data_size = (int32)module_inst->memory_data_size; - if ((uint8*)module_inst->memory_data.ptr <= (uint8*)native_ptr - && (uint8*)native_ptr < (uint8*)module_inst->memory_data_end.ptr) { - native_start_addr = (uint8*)module_inst->memory_data.ptr; - native_end_addr = (uint8*)module_inst->memory_data_end.ptr; + if ((uint8*)module_inst->heap_data.ptr < addr + && addr < (uint8*)module_inst->memory_data.ptr + + memory_data_size) { + if (p_native_start_addr) + *p_native_start_addr = (uint8*)module_inst->heap_data.ptr; + if (p_native_end_addr) + *p_native_end_addr = (uint8*)module_inst->memory_data.ptr + + memory_data_size; + return true; } - else if ((uint8*)module_inst->heap_data.ptr <= (uint8*)native_ptr - && (uint8*)native_ptr < (uint8*)module_inst->heap_data_end.ptr) { - native_start_addr = (uint8*)module_inst->heap_data.ptr; - native_end_addr = (uint8*)module_inst->heap_data_end.ptr; - } - else - return false; - - if (p_native_start_addr) - *p_native_start_addr = native_start_addr; - if (p_native_end_addr) - *p_native_end_addr = native_end_addr; - return true; + return false; } bool aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count) { - uint8 *mem_data_old = module_inst->memory_data.ptr, *mem_data_new; + uint8 *heap_data_old = module_inst->heap_data.ptr, *heap_data; uint32 num_bytes_per_page = ((AOTModule*)module_inst->aot_module.ptr)->num_bytes_per_page; uint32 cur_page_count = module_inst->mem_cur_page_count; uint32 max_page_count = module_inst->mem_max_page_count; uint32 total_page_count = cur_page_count + inc_page_count; - uint64 total_size = (uint64)num_bytes_per_page * total_page_count; - uint32 total_size_old = module_inst->memory_data_size; + uint64 memory_data_size = (uint64)num_bytes_per_page * total_page_count; + uint32 heap_size = (uint32)((uint8*)module_inst->memory_data.ptr + - (uint8*)module_inst->heap_data.ptr); + uint32 total_size_old = heap_size + module_inst->memory_data_size; + uint64 total_size = heap_size + memory_data_size; + void *heap_handle_old = module_inst->heap_handle.ptr; if (inc_page_count <= 0) /* No need to enlarge memory */ @@ -768,24 +754,50 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count) return false; } - if (!(mem_data_new = wasm_runtime_realloc(mem_data_old, (uint32)total_size))) { - if (!(mem_data_new = wasm_runtime_malloc((uint32)total_size))) { + /* Destroy heap's lock firstly, if its memory is re-allocated, + we cannot access its lock again. */ + mem_allocator_destroy_lock(module_inst->heap_handle.ptr); + if (!(heap_data = wasm_runtime_realloc(heap_handle_old, (uint32)total_size))) { + if (!(heap_data = wasm_runtime_malloc((uint32)total_size))) { + /* Restore heap's lock if memory re-alloc failed */ + mem_allocator_reinit_lock(module_inst->heap_handle.ptr); aot_set_exception(module_inst, "fail to enlarge memory."); return false; } - bh_memcpy_s(mem_data_new, (uint32)total_size, - mem_data_old, total_size_old); - wasm_runtime_free(mem_data_old); + bh_memcpy_s(heap_data, (uint32)total_size, + heap_data_old, total_size_old); + wasm_runtime_free(heap_data_old); } - memset(mem_data_new + total_size_old, + memset(heap_data + total_size_old, 0, (uint32)total_size - total_size_old); - module_inst->mem_cur_page_count = total_page_count; - module_inst->memory_data_size = (uint32)total_size; - module_inst->memory_data.ptr = mem_data_new; - module_inst->memory_data_end.ptr = mem_data_new + (uint32)total_size; + module_inst->heap_data.ptr = heap_data; + module_inst->heap_handle.ptr = (uint8*)heap_handle_old + + (heap_data - heap_data_old); + module_inst->heap_data_end.ptr = heap_data + heap_size; + if (mem_allocator_migrate(module_inst->heap_handle.ptr, + heap_handle_old) != 0) { + aot_set_exception(module_inst, "fail to enlarge memory."); + return false; + } + + module_inst->mem_cur_page_count = total_page_count; + module_inst->memory_data_size = (uint32)memory_data_size; +#if WASM_ENABLE_SPEC_TEST == 0 + module_inst->total_mem_size = (uint32)(heap_size + memory_data_size); +#else + module_inst->total_mem_size = (uint32)memory_data_size; +#endif + module_inst->memory_data.ptr = (uint8*)heap_data + heap_size; + module_inst->memory_data_end.ptr = (uint8*)module_inst->memory_data.ptr + + (uint32)memory_data_size; + + module_inst->mem_bound_check_1byte = module_inst->total_mem_size - 1; + module_inst->mem_bound_check_2bytes = module_inst->total_mem_size - 2; + module_inst->mem_bound_check_4bytes = module_inst->total_mem_size - 4; + module_inst->mem_bound_check_8bytes = module_inst->total_mem_size - 8; return true; } @@ -813,7 +825,7 @@ aot_is_wasm_type_equal(AOTModuleInstance *module_inst, bool aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, - uint32 *frame_lp, uint32 argc, uint32 *argv_ret) + uint32 argc, uint32 *argv) { AOTModuleInstance *module_inst = (AOTModuleInstance*) wasm_runtime_get_module_inst(exec_env); @@ -844,12 +856,12 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, if (!import_func->call_conv_raw) { return wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature, attachment, - frame_lp, argc, argv_ret); + argv, argc, argv); } else { return wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type, signature, attachment, - frame_lp, argc, argv_ret); + argv, argc, argv); } } @@ -857,7 +869,7 @@ bool aot_call_indirect(WASMExecEnv *exec_env, bool check_func_type, uint32 func_type_idx, uint32 table_elem_idx, - uint32 *frame_lp, uint32 argc, uint32 *argv_ret) + uint32 argc, uint32 *argv) { AOTModuleInstance *module_inst = (AOTModuleInstance*) wasm_runtime_get_module_inst(exec_env); @@ -913,11 +925,11 @@ aot_call_indirect(WASMExecEnv *exec_env, return wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type, signature, attachment, - frame_lp, argc, argv_ret); + argv, argc, argv); } } return wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature, attachment, - frame_lp, argc, argv_ret); + argv, argc, argv); } diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 0bd4c765..0239fe35 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -18,9 +18,6 @@ extern "C" { #endif -#define AOT_MAGIC_NUMBER 0x746f6100 -#define AOT_CURRENT_VERSION 1 - typedef enum AOTExceptionID { EXCE_UNREACHABLE = 0, EXCE_OUT_OF_MEMORY, @@ -200,19 +197,27 @@ typedef struct AOTModuleInstance { /* WASI context */ AOTPointer wasi_ctx; + /* total memory size: heap and linear memory */ + uint32 total_mem_size; + + /* boundary check constants for aot code */ + uint32 mem_bound_check_1byte; + uint32 mem_bound_check_2bytes; + uint32 mem_bound_check_4bytes; + uint32 mem_bound_check_8bytes; + /* others */ int32 temp_ret; uint32 llvm_stack; - int32 DYNAMICTOP_PTR_offset; uint32 default_wasm_stack_size; /* reserved */ - uint32 reserved[16]; + uint32 reserved[12]; union { uint64 _make_it_8_byte_aligned_; uint8 bytes[1]; - } global_table_heap_data; + } global_table_data; } AOTModuleInstance; typedef AOTExportFunc AOTFunctionInstance; @@ -441,13 +446,13 @@ aot_is_wasm_type_equal(AOTModuleInstance *module_inst, */ bool aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, - uint32 *frame_lp, uint32 argc, uint32 *argv_ret); + uint32 argc, uint32 *argv); bool aot_call_indirect(WASMExecEnv *exec_env, bool check_func_type, uint32 func_type_idx, uint32 table_elem_idx, - uint32 *frame_lp, uint32 argc, uint32 *argv_ret); + uint32 argc, uint32 *argv); uint32 aot_get_plt_table_size(); diff --git a/core/iwasm/common/wasm_native.c b/core/iwasm/common/wasm_native.c index cbbf2fbd..d92271a9 100644 --- a/core/iwasm/common/wasm_native.c +++ b/core/iwasm/common/wasm_native.c @@ -162,9 +162,11 @@ wasm_native_resolve_symbol(const char *module_name, const char *field_name, if (signature && signature[0] != '\0') { /* signature is not empty, check its format */ if (!check_symbol_signature(func_type, signature)) { +#if WASM_ENABLE_WAMR_COMPILER == 0 /* Output warning except running aot compiler */ LOG_WARNING("failed to check signature '%s' and resolve " "pointer params for import function (%s %s)\n", signature, module_name, field_name); +#endif return NULL; } else diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index ea86d952..276e21b0 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -810,9 +810,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, goto fail; } - wasi_ctx->curfds = curfds; - wasi_ctx->prestats = prestats; - wasi_ctx->argv_environ = argv_environ; + wasi_ctx->curfds_offset = offset_curfds; + wasi_ctx->prestats_offset = offset_prestats; + wasi_ctx->argv_environ_offset = offset_argv_environ; fd_table_init(curfds); fd_prestats_init(prestats); @@ -950,14 +950,32 @@ void wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst) { WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst); + struct argv_environ_values *argv_environ; + struct fd_table *curfds; + struct fd_prestats *prestats; if (wasi_ctx) { - if (wasi_ctx->argv_environ) - argv_environ_destroy(wasi_ctx->argv_environ); - if (wasi_ctx->curfds) - fd_table_destroy(wasi_ctx->curfds); - if (wasi_ctx->prestats) - fd_prestats_destroy(wasi_ctx->prestats); + if (wasi_ctx->argv_environ_offset) { + argv_environ = (struct argv_environ_values *) + wasm_runtime_addr_app_to_native(module_inst, + wasi_ctx->argv_environ_offset); + argv_environ_destroy(argv_environ); + wasm_runtime_module_free(module_inst, wasi_ctx->argv_environ_offset); + } + if (wasi_ctx->curfds_offset) { + curfds = (struct fd_table *) + wasm_runtime_addr_app_to_native(module_inst, + wasi_ctx->curfds_offset); + fd_table_destroy(curfds); + wasm_runtime_module_free(module_inst, wasi_ctx->curfds_offset); + } + if (wasi_ctx->prestats_offset) { + prestats = (struct fd_prestats *) + wasm_runtime_addr_app_to_native(module_inst, + wasi_ctx->prestats_offset); + fd_prestats_destroy(prestats); + wasm_runtime_module_free(module_inst, wasi_ctx->prestats_offset); + } wasm_runtime_free(wasi_ctx); } } @@ -2141,8 +2159,7 @@ wasm_runtime_call_indirect(WASMExecEnv *exec_env, #if WASM_ENABLE_AOT != 0 if (exec_env->module_inst->module_type == Wasm_Module_AoT) return aot_call_indirect(exec_env, false, 0, - element_indices, - argv, argc, argv); + element_indices, argc, argv); #endif return false; } diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 3490620b..432db598 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -46,9 +46,13 @@ typedef struct WASMModuleInstanceCommon { #if WASM_ENABLE_LIBC_WASI != 0 typedef struct WASIContext { - struct fd_table *curfds; - struct fd_prestats *prestats; - struct argv_environ_values *argv_environ; + /* Use offset but not native address, since these fields are + allocated from app's heap, and the heap space may be re-allocated + after memory.grow opcode is executed, the original native address + cannot be accessed again. */ + int32 curfds_offset; + int32 prestats_offset; + int32 argv_environ_offset; } WASIContext; #endif diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 20675f22..557528b0 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -821,13 +821,14 @@ aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset, AOTCompData *comp_data, AOTObjectData *obj_data) { uint32 offset = *p_offset; + uint32 aot_curr_version = AOT_CURRENT_VERSION; EMIT_U8('\0'); EMIT_U8('a'); EMIT_U8('o'); EMIT_U8('t'); - EMIT_U32(1); + EMIT_U32(aot_curr_version); *p_offset = offset; return true; diff --git a/core/iwasm/compilation/aot_emit_function.c b/core/iwasm/compilation/aot_emit_function.c index 0a8d2a1a..dfcff55b 100644 --- a/core/iwasm/compilation/aot_emit_function.c +++ b/core/iwasm/compilation/aot_emit_function.c @@ -143,20 +143,19 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMTypeRef ret_type, uint8 wasm_ret_type, LLVMValueRef *p_value_ret, LLVMValueRef *p_res) { - LLVMTypeRef func_type, func_ptr_type, func_param_types[5]; + LLVMTypeRef func_type, func_ptr_type, func_param_types[4]; LLVMTypeRef ret_ptr_type, elem_ptr_type; LLVMValueRef func, elem_idx, elem_ptr; - LLVMValueRef func_param_values[5], value_ret = NULL, value_ret_ptr, res; + LLVMValueRef func_param_values[4], value_ret = NULL, res; char buf[32], *func_name = "aot_invoke_native"; uint32 i, cell_num = 0; /* prepare function type of aot_invoke_native */ func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */ func_param_types[1] = I32_TYPE; /* func_idx */ - func_param_types[2] = INT32_PTR_TYPE; /* frame_lp */ - func_param_types[3] = I32_TYPE; /* argc */ - func_param_types[4] = INT32_PTR_TYPE; /* argv_ret */ - if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 5, false))) { + func_param_types[2] = I32_TYPE; /* argc */ + func_param_types[3] = INT32_PTR_TYPE; /* argv */ + if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 4, false))) { aot_set_last_error("llvm add function type failed."); return false; } @@ -216,6 +215,24 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, cell_num += wasm_value_type_cell_num(aot_func_type->types[i]); } + func_param_values[0] = func_ctx->exec_env; + func_param_values[1] = func_idx; + func_param_values[2] = I32_CONST(param_cell_num); + func_param_values[3] = func_ctx->argv_buf; + + if (!func_param_values[2]) { + aot_set_last_error("llvm create const failed."); + return false; + } + + /* call aot_invoke_native() function */ + if (!(res = LLVMBuildCall(comp_ctx->builder, func, + func_param_values, 4, "res"))) { + aot_set_last_error("llvm build call failed."); + return false; + } + + /* get function return value */ if (wasm_ret_type != VALUE_TYPE_VOID) { if (!(ret_ptr_type = LLVMPointerType(ret_type, 0))) { aot_set_last_error("llvm add pointer type failed."); @@ -227,39 +244,12 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_set_last_error("llvm build bit cast failed."); return false; } - - /* convert to int32 pointer */ - if (!(value_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, value_ret, - INT32_PTR_TYPE, "argv_ret_ptr"))) { - aot_set_last_error("llvm build store failed."); + if (!(*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret, + "value_ret"))) { + aot_set_last_error("llvm build load failed."); return false; } } - else { - value_ret_ptr = LLVMConstNull(INT32_PTR_TYPE); - } - - func_param_values[0] = func_ctx->exec_env; - func_param_values[1] = func_idx; - func_param_values[2] = func_ctx->argv_buf; - func_param_values[3] = I32_CONST(param_cell_num); - func_param_values[4] = value_ret_ptr; - - if (!func_param_values[3]) { - aot_set_last_error("llvm create const failed."); - return false; - } - - /* call aot_invoke_native() function */ - if (!(res = LLVMBuildCall(comp_ctx->builder, func, - func_param_values, 5, "res"))) { - aot_set_last_error("llvm build call failed."); - return false; - } - - if (wasm_ret_type != VALUE_TYPE_VOID) - /* get function return value */ - *p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret, "value_ret"); *p_res = res; return true; @@ -395,10 +385,10 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMTypeRef ret_type, uint8 wasm_ret_type, LLVMValueRef *p_value_ret, LLVMValueRef *p_res) { - LLVMTypeRef func_type, func_ptr_type, func_param_types[7]; + LLVMTypeRef func_type, func_ptr_type, func_param_types[6]; LLVMTypeRef ret_ptr_type, elem_ptr_type; LLVMValueRef func, elem_idx, elem_ptr; - LLVMValueRef func_param_values[7], value_ret = NULL, value_ret_ptr, res = NULL; + LLVMValueRef func_param_values[6], value_ret = NULL, res = NULL; char buf[32], *func_name = "aot_call_indirect"; uint32 i, cell_num = 0; @@ -407,10 +397,9 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, func_param_types[1] = INT8_TYPE; /* check_func_type */ func_param_types[2] = I32_TYPE; /* func_type_idx */ func_param_types[3] = I32_TYPE; /* table_elem_idx */ - func_param_types[4] = INT32_PTR_TYPE; /* frame_lp */ - func_param_types[5] = I32_TYPE; /* argc */ - func_param_types[6] = INT32_PTR_TYPE; /* argv_ret */ - if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 7, false))) { + func_param_types[4] = I32_TYPE; /* argc */ + func_param_types[5] = INT32_PTR_TYPE; /* argv */ + if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 6, false))) { aot_set_last_error("llvm add function type failed."); return false; } @@ -470,6 +459,26 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, cell_num += wasm_value_type_cell_num(aot_func_type->types[i]); } + func_param_values[0] = func_ctx->exec_env; + func_param_values[1] = I8_CONST(true); + func_param_values[2] = func_type_idx; + func_param_values[3] = table_elem_idx; + func_param_values[4] = I32_CONST(param_cell_num); + func_param_values[5] = func_ctx->argv_buf; + + if (!func_param_values[1] || !func_param_values[4]) { + aot_set_last_error("llvm create const failed."); + return false; + } + + /* call aot_call_indirect() function */ + if (!(res = LLVMBuildCall(comp_ctx->builder, func, + func_param_values, 6, "res"))) { + aot_set_last_error("llvm build call failed."); + return false; + } + + /* get function return value */ if (wasm_ret_type != VALUE_TYPE_VOID) { if (!(ret_ptr_type = LLVMPointerType(ret_type, 0))) { aot_set_last_error("llvm add pointer type failed."); @@ -482,40 +491,12 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } - /* convert to int32 pointer */ - if (!(value_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, value_ret, - INT32_PTR_TYPE, "argv_ret_ptr"))) { - aot_set_last_error("llvm build store failed."); + if (!(*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret, + "value_ret"))) { + aot_set_last_error("llvm build load failed."); return false; } } - else { - value_ret_ptr = LLVMConstNull(INT32_PTR_TYPE); - } - - func_param_values[0] = func_ctx->exec_env; - func_param_values[1] = I8_CONST(true); - func_param_values[2] = func_type_idx; - func_param_values[3] = table_elem_idx; - func_param_values[4] = func_ctx->argv_buf; - func_param_values[5] = I32_CONST(param_cell_num); - func_param_values[6] = value_ret_ptr; - - if (!func_param_values[1] || !func_param_values[4]) { - aot_set_last_error("llvm create const failed."); - return false; - } - - /* call aot_call_indirect() function */ - if (!(res = LLVMBuildCall(comp_ctx->builder, func, - func_param_values, 7, "res"))) { - aot_set_last_error("llvm build call failed."); - return false; - } - - if (wasm_ret_type != VALUE_TYPE_VOID) - /* get function return value */ - *p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret, "value_ret"); *p_res = res; return true; diff --git a/core/iwasm/compilation/aot_emit_memory.c b/core/iwasm/compilation/aot_emit_memory.c index 8b779240..cdabe6b9 100644 --- a/core/iwasm/compilation/aot_emit_memory.c +++ b/core/iwasm/compilation/aot_emit_memory.c @@ -23,14 +23,6 @@ } \ } while (0) -#define BUILD_COND_BR(cmp_val, then_block, else_block) do { \ - if (!LLVMBuildCondBr(comp_ctx->builder, cmp_val, \ - then_block, else_block)) { \ - aot_set_last_error("llvm build cond br failed."); \ - goto fail; \ - } \ - } while (0) - #define ADD_BASIC_BLOCK(block, name) do { \ if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \ func_ctx->func, \ @@ -43,53 +35,88 @@ #define SET_BUILD_POS(block) \ LLVMPositionBuilderAtEnd(comp_ctx->builder, block) +static LLVMValueRef +get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, + uint32 bytes) +{ + LLVMValueRef mem_check_bound = NULL; + switch (bytes) { + case 1: + mem_check_bound = func_ctx->mem_bound_check_1byte; + break; + case 2: + mem_check_bound = func_ctx->mem_bound_check_2bytes; + break; + case 4: + mem_check_bound = func_ctx->mem_bound_check_4bytes; + break; + case 8: + mem_check_bound = func_ctx->mem_bound_check_8bytes; + break; + default: + bh_assert(0); + return NULL; + } + + if (func_ctx->mem_space_unchanged) + return mem_check_bound; + + if (!(mem_check_bound = LLVMBuildLoad(comp_ctx->builder, + mem_check_bound, + "mem_check_bound"))) { + aot_set_last_error("llvm build load failed."); + return NULL; + } + return mem_check_bound; +} + static LLVMValueRef check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 offset, uint32 bytes) { LLVMValueRef offset_const = I32_CONST(offset); - LLVMValueRef size_const = I32_CONST(bytes); - LLVMValueRef addr, maddr, moffset; - LLVMValueRef cmp, phi; - LLVMValueRef mem_base_addr, mem_data_size; - LLVMValueRef heap_base_addr, heap_base_offset; - LLVMValueRef mem_offset_max = NULL, heap_offset_max = NULL; - LLVMBasicBlockRef check_mem_space, check_heap_space, check_succ; + LLVMValueRef bytes_const = I32_CONST(bytes); + LLVMValueRef bytes64_const = I64_CONST(bytes); + LLVMValueRef heap_base_offset = func_ctx->heap_base_offset; + LLVMValueRef addr, maddr, offset1, offset2, cmp; + LLVMValueRef mem_base_addr, mem_check_bound, total_mem_size; LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder); + LLVMBasicBlockRef check_succ, check_mem_space; CHECK_LLVM_CONST(offset_const); - CHECK_LLVM_CONST(size_const); + CHECK_LLVM_CONST(bytes_const); + CHECK_LLVM_CONST(bytes64_const); - heap_base_addr = func_ctx->heap_base_addr; - heap_base_offset = func_ctx->heap_base_offset; + /* Get memory base address and memory data size */ + if (func_ctx->mem_space_unchanged) { + mem_base_addr = func_ctx->mem_base_addr; + } + else { + if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder, + func_ctx->mem_base_addr, + "mem_base"))) { + aot_set_last_error("llvm build load failed."); + goto fail; + } + } POP_I32(addr); - BUILD_OP(Add, offset_const, addr, moffset, "moffset"); + /* offset1 = offset + addr; */ + BUILD_OP(Add, offset_const, addr, offset1, "offset1"); /* return addres directly if constant offset and inside memory space */ - if (LLVMIsConstant(moffset)) { - uint32 memory_offset = (uint32)LLVMConstIntGetZExtValue(moffset); + if (LLVMIsConstant(offset1)) { + uint32 mem_offset = (uint32)LLVMConstIntGetZExtValue(offset1); + uint32 num_bytes_per_page = comp_ctx->comp_data->num_bytes_per_page; uint32 init_page_count = comp_ctx->comp_data->mem_init_page_count; - if (init_page_count > 0 - && memory_offset <= comp_ctx->comp_data->num_bytes_per_page - * init_page_count - bytes) { + uint32 mem_data_size = num_bytes_per_page * init_page_count; + if (mem_data_size > 0 + && mem_offset <= mem_data_size - bytes) { /* inside memory space */ - if (!func_ctx->mem_space_unchanged) { - if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_base_addr, - "mem_base"))) { - aot_set_last_error("llvm build load failed."); - return NULL; - } - } - else { - mem_base_addr = func_ctx->mem_base_addr; - } - /* maddr = mem_base_addr + moffset */ if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr, - &moffset, 1, "maddr"))) { + &offset1, 1, "maddr"))) { aot_set_last_error("llvm build add failed."); goto fail; } @@ -97,136 +124,63 @@ check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } } - /* Add basic blocks */ - ADD_BASIC_BLOCK(check_heap_space, "check_heap_space"); - ADD_BASIC_BLOCK(check_succ, "check_succ"); - - LLVMMoveBasicBlockAfter(check_heap_space, block_curr); - LLVMMoveBasicBlockAfter(check_succ, check_heap_space); - - /* Add return maddress phi for check_succ block */ - SET_BUILD_POS(check_succ); - if (!(phi = LLVMBuildPhi(comp_ctx->builder, - INT8_PTR_TYPE, "maddr_phi"))) { - aot_set_last_error("llvm build phi failed."); - goto fail; - } - SET_BUILD_POS(block_curr); - - /* Get memory data size */ - if (!func_ctx->mem_space_unchanged) { - if (!(mem_data_size = LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_data_size, - "mem_data_size"))) { - aot_set_last_error("llvm build load failed."); - return NULL; - } - } - else { - mem_data_size = func_ctx->mem_data_size; - } - if (comp_ctx->comp_data->mem_init_page_count == 0) { + /* Get total memory size */ + if (func_ctx->mem_space_unchanged) { + total_mem_size = func_ctx->total_mem_size; + } + else { + if (!(total_mem_size = LLVMBuildLoad(comp_ctx->builder, + func_ctx->total_mem_size, + "total_mem_size"))) { + aot_set_last_error("llvm build load failed."); + goto fail; + } + } + ADD_BASIC_BLOCK(check_mem_space, "check_mem_space"); LLVMMoveBasicBlockAfter(check_mem_space, block_curr); - /* if mem_data_size is zero, check heap space */ - BUILD_ICMP(LLVMIntEQ, mem_data_size, I32_ZERO, cmp, - "cmp_mem_data_size"); - BUILD_COND_BR(cmp, check_heap_space, check_mem_space); + /* if total_mem_size is zero, boundary check fail */ + BUILD_ICMP(LLVMIntEQ, total_mem_size, I32_ZERO, cmp, + "cmp_total_mem_size"); + if (!aot_emit_exception(comp_ctx, func_ctx, + EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, + true, cmp, check_mem_space)) { + goto fail; + } SET_BUILD_POS(check_mem_space); } - /* Get memory base address */ - if (!func_ctx->mem_space_unchanged) { - if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder, - func_ctx->mem_base_addr, - "mem_base"))) { - aot_set_last_error("llvm build load failed."); - return NULL; - } - } - else { - mem_base_addr = func_ctx->mem_base_addr; - } + /* offset2 = offset1 - heap_base_offset; */ + BUILD_OP(Sub, offset1, heap_base_offset, offset2, "offset2"); - /* maddr = mem_base_addr + moffset */ - if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr, - &moffset, 1, "maddr"))) { - aot_set_last_error("llvm build add failed."); - goto fail; - } - block_curr = LLVMGetInsertBlock(comp_ctx->builder); - LLVMAddIncoming(phi, &maddr, &block_curr, 1); - - if (!func_ctx->mem_space_unchanged) { - /* mem_offset_max = mem_data_size - bytes to load/read */ - if (!(mem_offset_max = LLVMBuildSub(comp_ctx->builder, - mem_data_size, size_const, - "mem_offset_max"))) { - aot_set_last_error("llvm build sub failed."); - goto fail; - } - } - else { - if (bytes == 1) - mem_offset_max = func_ctx->mem_bound_1_byte; - else if (bytes == 2) - mem_offset_max = func_ctx->mem_bound_2_bytes; - else if (bytes == 4) - mem_offset_max = func_ctx->mem_bound_4_bytes; - else if (bytes == 8) - mem_offset_max = func_ctx->mem_bound_8_bytes; - } - - /* in linear memory if (uint32)moffset <= (uint32)mem_offset_max, - else check heap space */ - BUILD_ICMP(LLVMIntULE, moffset, mem_offset_max, cmp, "cmp_mem_offset"); - - /* Create condtion br */ - BUILD_COND_BR(cmp, check_succ, check_heap_space); - - /* Start to translate the check_heap_space block */ - SET_BUILD_POS(check_heap_space); - - /* moffset -= heap_base_offset */ - if (!(moffset = LLVMBuildSub(comp_ctx->builder, - moffset, heap_base_offset, - "moffset_to_heap"))) { - aot_set_last_error("llvm build sub failed."); + if (!(mem_check_bound = + get_memory_check_bound(comp_ctx, func_ctx, bytes))) { goto fail; } - /* maddr = heap_base_addr + moffset */ - if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, heap_base_addr, - &moffset, 1, "maddr"))) { - aot_set_last_error("llvm build add failed."); - goto fail; - } - block_curr = LLVMGetInsertBlock(comp_ctx->builder); - LLVMAddIncoming(phi, &maddr, &block_curr, 1); + /* Add basic blocks */ + ADD_BASIC_BLOCK(check_succ, "check_succ"); + LLVMMoveBasicBlockAfter(check_succ, block_curr); - /* heap space base addr and size is unchanged, - the heap boundary is unchanged also. */ - if (bytes == 1) - heap_offset_max = func_ctx->heap_bound_1_byte; - else if (bytes == 2) - heap_offset_max = func_ctx->heap_bound_2_bytes; - else if (bytes == 4) - heap_offset_max = func_ctx->heap_bound_4_bytes; - else if (bytes == 8) - heap_offset_max = func_ctx->heap_bound_8_bytes; - - /* in heap space if (uint32)moffset <= (uint32)heap_offset_max, - else throw exception */ - BUILD_ICMP(LLVMIntUGT, moffset, heap_offset_max, cmp, "cmp_heap_offset"); + /* offset2 > bound ? */ + BUILD_ICMP(LLVMIntUGT, offset2, mem_check_bound, cmp, "cmp"); if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, - true, cmp, check_succ)) + true, cmp, check_succ)) { goto fail; + } SET_BUILD_POS(check_succ); - return phi; + + /* maddr = mem_base_addr + offset1 */ + if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr, + &offset1, 1, "maddr"))) { + aot_set_last_error("llvm build add failed."); + goto fail; + } + return maddr; fail: return NULL; } diff --git a/core/iwasm/compilation/aot_emit_variable.c b/core/iwasm/compilation/aot_emit_variable.c index a5565841..97ca8da0 100644 --- a/core/iwasm/compilation/aot_emit_variable.c +++ b/core/iwasm/compilation/aot_emit_variable.c @@ -105,7 +105,7 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, AOTCompData *comp_data = comp_ctx->comp_data; uint32 import_global_count = comp_data->import_global_count; uint32 global_base_offset = offsetof(AOTModuleInstance, - global_table_heap_data.bytes); + global_table_data.bytes); uint32 global_offset; uint8 global_type; LLVMValueRef offset, global_ptr, global; diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index 37f8c20f..5e3da9c4 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -181,68 +181,117 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } } - /* Load memory data size */ - offset = I32_CONST(offsetof(AOTModuleInstance, memory_data_size)); - if (!(func_ctx->mem_data_size = + /* Load total memory size */ + offset = I32_CONST(offsetof(AOTModuleInstance, total_mem_size)); + if (!(func_ctx->total_mem_size = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "mem_data_size_offset"))) { + &offset, 1, "bound_check_1byte_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } - if (!(func_ctx->mem_data_size = - LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_data_size, - INT32_PTR_TYPE, "mem_data_size_ptr"))) { + if (!(func_ctx->total_mem_size = + LLVMBuildBitCast(comp_ctx->builder, func_ctx->total_mem_size, + INT32_PTR_TYPE, "bound_check_1byte_ptr"))) { aot_set_last_error("llvm build bit cast failed"); return false; } if (mem_space_unchanged) { - if (!(func_ctx->mem_data_size = - LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_data_size, - "mem_data_size"))) { + if (!(func_ctx->total_mem_size = + LLVMBuildLoad(comp_ctx->builder, func_ctx->total_mem_size, + "bound_check_1byte"))) { aot_set_last_error("llvm build load failed"); return false; } - if (!(func_ctx->mem_bound_1_byte = - LLVMBuildSub(comp_ctx->builder, - func_ctx->mem_data_size, I32_ONE, - "mem_bound_1_byte")) - || !(func_ctx->mem_bound_2_bytes = - LLVMBuildSub(comp_ctx->builder, - func_ctx->mem_data_size, I32_TWO, - "mem_bound_2_bytes")) - || !(func_ctx->mem_bound_4_bytes = - LLVMBuildSub(comp_ctx->builder, - func_ctx->mem_data_size, I32_FOUR, - "mem_bound_4_bytes")) - || !(func_ctx->mem_bound_8_bytes = - LLVMBuildSub(comp_ctx->builder, - func_ctx->mem_data_size, I32_EIGHT, - "mem_bound_8_bytes"))) { - aot_set_last_error("llvm build sub failed"); - return false; - } } - /* Load heap base address */ - offset = I32_CONST(offsetof(AOTModuleInstance, heap_data.ptr)); - if (!(func_ctx->heap_base_addr = + /* Load memory bound check constants */ + offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_1byte)); + if (!(func_ctx->mem_bound_check_1byte = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "heap_base_addr_offset"))) { + &offset, 1, "bound_check_1byte_offset"))) { aot_set_last_error("llvm build in bounds gep failed"); return false; } - if (!(func_ctx->heap_base_addr = - LLVMBuildBitCast(comp_ctx->builder, func_ctx->heap_base_addr, - int8_ptr_type, "heap_base_addr_tmp"))) { + if (!(func_ctx->mem_bound_check_1byte = + LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_1byte, + INT32_PTR_TYPE, "bound_check_1byte_ptr"))) { aot_set_last_error("llvm build bit cast failed"); return false; } - if (!(func_ctx->heap_base_addr = - LLVMBuildLoad(comp_ctx->builder, func_ctx->heap_base_addr, - "heap_base_addr"))) { - aot_set_last_error("llvm build load failed"); + if (mem_space_unchanged) { + if (!(func_ctx->mem_bound_check_1byte = + LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_1byte, + "bound_check_1byte"))) { + aot_set_last_error("llvm build load failed"); + return false; + } + } + + offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_2bytes)); + if (!(func_ctx->mem_bound_check_2bytes = + LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, + &offset, 1, "bound_check_2bytes_offset"))) { + aot_set_last_error("llvm build in bounds gep failed"); return false; } + if (!(func_ctx->mem_bound_check_2bytes = + LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_2bytes, + INT32_PTR_TYPE, "bound_check_2bytes_ptr"))) { + aot_set_last_error("llvm build bit cast failed"); + return false; + } + if (mem_space_unchanged) { + if (!(func_ctx->mem_bound_check_2bytes = + LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_2bytes, + "bound_check_2bytes"))) { + aot_set_last_error("llvm build load failed"); + return false; + } + } + + offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_4bytes)); + if (!(func_ctx->mem_bound_check_4bytes = + LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, + &offset, 1, "bound_check_4bytes_offset"))) { + aot_set_last_error("llvm build in bounds gep failed"); + return false; + } + if (!(func_ctx->mem_bound_check_4bytes = + LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_4bytes, + INT32_PTR_TYPE, "bound_check_4bytes_ptr"))) { + aot_set_last_error("llvm build bit cast failed"); + return false; + } + if (mem_space_unchanged) { + if (!(func_ctx->mem_bound_check_4bytes = + LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_4bytes, + "bound_check_4bytes"))) { + aot_set_last_error("llvm build load failed"); + return false; + } + } + + offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_8bytes)); + if (!(func_ctx->mem_bound_check_8bytes = + LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, + &offset, 1, "bound_check_8bytes_offset"))) { + aot_set_last_error("llvm build in bounds gep failed"); + return false; + } + if (!(func_ctx->mem_bound_check_8bytes = + LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_8bytes, + INT32_PTR_TYPE, "bound_check_8bytes_ptr"))) { + aot_set_last_error("llvm build bit cast failed"); + return false; + } + if (mem_space_unchanged) { + if (!(func_ctx->mem_bound_check_8bytes = + LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_8bytes, + "bound_check_8bytes"))) { + aot_set_last_error("llvm build load failed"); + return false; + } + } /* Load heap base offset */ offset = I32_CONST(offsetof(AOTModuleInstance, heap_base_offset)); @@ -265,46 +314,6 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } - /* Load heap data size */ - offset = I32_CONST(offsetof(AOTModuleInstance, heap_data_size)); - if (!(func_ctx->heap_data_size = - LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, - &offset, 1, "heap_data_size_offset"))) { - aot_set_last_error("llvm build in bounds gep failed"); - return false; - } - if (!(func_ctx->heap_data_size = - LLVMBuildBitCast(comp_ctx->builder, func_ctx->heap_data_size, - INT32_PTR_TYPE, "heap_data_size_tmp"))) { - aot_set_last_error("llvm build bit cast failed"); - return false; - } - if (!(func_ctx->heap_data_size = - LLVMBuildLoad(comp_ctx->builder, func_ctx->heap_data_size, - "heap_data_size"))) { - aot_set_last_error("llvm build load failed"); - return false; - } - if (!(func_ctx->heap_bound_1_byte = - LLVMBuildSub(comp_ctx->builder, - func_ctx->heap_data_size, I32_ONE, - "heap_bound_1_byte")) - || !(func_ctx->heap_bound_2_bytes = - LLVMBuildSub(comp_ctx->builder, - func_ctx->heap_data_size, I32_TWO, - "heap_bound_2_bytes")) - || !(func_ctx->heap_bound_4_bytes = - LLVMBuildSub(comp_ctx->builder, - func_ctx->heap_data_size, I32_FOUR, - "heap_bound_4_bytes")) - || !(func_ctx->heap_bound_8_bytes = - LLVMBuildSub(comp_ctx->builder, - func_ctx->heap_data_size, I32_EIGHT, - "heap_bound_8_bytes"))) { - aot_set_last_error("llvm build sub failed"); - return false; - } - return true; } @@ -313,7 +322,7 @@ create_table_base(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) { LLVMValueRef offset; - offset = I32_CONST(offsetof(AOTModuleInstance, global_table_heap_data.bytes) + offset = I32_CONST(offsetof(AOTModuleInstance, global_table_data.bytes) + comp_ctx->comp_data->global_data_size); func_ctx->table_base = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, @@ -918,6 +927,7 @@ aot_create_comp_context(AOTCompData *comp_data, /* Create LLVM execution engine */ LLVMInitializeMCJITCompilerOptions(&jit_options, sizeof(jit_options)); jit_options.OptLevel = LLVMCodeGenLevelAggressive; + jit_options.EnableFastISel = true; /*jit_options.CodeModel = LLVMCodeModelSmall;*/ if (LLVMCreateMCJITCompilerForModule (&comp_ctx->exec_engine, comp_ctx->module, diff --git a/core/iwasm/compilation/aot_llvm.h b/core/iwasm/compilation/aot_llvm.h index 80113b73..6cbf1199 100644 --- a/core/iwasm/compilation/aot_llvm.h +++ b/core/iwasm/compilation/aot_llvm.h @@ -94,20 +94,13 @@ typedef struct AOTFuncContext { LLVMValueRef table_base; LLVMValueRef argv_buf; - LLVMValueRef mem_data_size; - LLVMValueRef mem_base_addr; - LLVMValueRef mem_bound_1_byte; - LLVMValueRef mem_bound_2_bytes; - LLVMValueRef mem_bound_4_bytes; - LLVMValueRef mem_bound_8_bytes; - LLVMValueRef heap_base_offset; - LLVMValueRef heap_base_addr; - LLVMValueRef heap_data_size; - LLVMValueRef heap_bound_1_byte; - LLVMValueRef heap_bound_2_bytes; - LLVMValueRef heap_bound_4_bytes; - LLVMValueRef heap_bound_8_bytes; + LLVMValueRef mem_base_addr; + LLVMValueRef total_mem_size; + LLVMValueRef mem_bound_check_1byte; + LLVMValueRef mem_bound_check_2bytes; + LLVMValueRef mem_bound_check_4bytes; + LLVMValueRef mem_bound_check_8bytes; LLVMValueRef cur_exception; diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 3cab86ce..3e7b302b 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -223,28 +223,17 @@ LOAD_I16(void *addr) #endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */ -#define CHECK_MEMORY_OVERFLOW() do { \ - uint64 offset1 = offset + addr; \ - /* if (flags != 2) \ - LOG_VERBOSE("unaligned load/store in wasm interp, flag: %d.\n", flags); */\ - /* The WASM spec doesn't require that the dynamic address operand must be \ - unsigned, so we don't check whether integer overflow or not here. */ \ - /* if (offset1 < offset) \ - goto out_of_bounds; */ \ - if (offset1 + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] <= memory_data_size) { \ - /* If offset1 is in valid range, maddr must also be in valid range, \ - no need to check it again. */ \ - maddr = memory->memory_data + offset1; \ - } \ - else if (offset1 > DEFAULT_APP_HEAP_BASE_OFFSET \ - && (offset1 + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] <= \ - DEFAULT_APP_HEAP_BASE_OFFSET + heap_data_size)) { \ - /* If offset1 is in valid range, maddr must also be in valid range, \ - no need to check it again. */ \ - maddr = memory->heap_data + offset1 - memory->heap_base_offset; \ - } \ - else \ - goto out_of_bounds; \ +#define CHECK_MEMORY_OVERFLOW(bytes) do { \ + int32 offset1 = (int32)(offset + addr); \ + uint64 offset2 = (uint64)(uint32)(offset1 - heap_base_offset); \ + /* if (flags != 2) \ + LOG_VERBOSE("unaligned load/store, flag: %d.\n", flags); */ \ + if (offset2 + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] <= total_mem_size) \ + /* If offset1 is in valid range, maddr must also be in valid range, \ + no need to check it again. */ \ + maddr = memory->memory_data + offset1; \ + else \ + goto out_of_bounds; \ } while (0) static inline uint32 @@ -798,9 +787,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, WASMInterpFrame *prev_frame) { WASMMemoryInstance *memory = module->default_memory; + int32 heap_base_offset = memory ? memory->heap_base_offset : 0; uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; - uint32 memory_data_size = memory ? num_bytes_per_page * memory->cur_page_count : 0; - uint32 heap_data_size = memory ? (uint32)(memory->heap_data_end - memory->heap_data) : 0; + uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count + - heap_base_offset : 0; uint8 *global_data = memory ? memory->global_data : NULL; WASMTableInstance *table = module->default_table; WASMGlobalInstance *globals = module->globals; @@ -1419,7 +1409,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, PUSH_I32(prev_page_count); /* update the memory instance ptr */ memory = module->default_memory; - memory_data_size = num_bytes_per_page * memory->cur_page_count; + total_mem_size = num_bytes_per_page * memory->cur_page_count + - heap_base_offset; global_data = memory->global_data; } diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 5edfec5f..6eb28c4a 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -225,28 +225,17 @@ LOAD_I16(void *addr) #endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */ -#define CHECK_MEMORY_OVERFLOW(bytes) do { \ - uint64 offset1 = offset + addr; \ - /* if (flags != 2) \ - LOG_VERBOSE("unaligned load/store in wasm interp, flag: %d.\n", flags); */\ - /* The WASM spec doesn't require that the dynamic address operand must be \ - unsigned, so we don't check whether integer overflow or not here. */ \ - /* if (offset1 < offset) \ - goto out_of_bounds; */ \ - if (offset1 + bytes <= memory_data_size) { \ - /* If offset1 is in valid range, maddr must also be in valid range, \ - no need to check it again. */ \ - maddr = memory->memory_data + offset1; \ - } \ - else if (offset1 > DEFAULT_APP_HEAP_BASE_OFFSET \ - && (offset1 + bytes <= \ - DEFAULT_APP_HEAP_BASE_OFFSET + heap_data_size)) { \ - /* If offset1 is in valid range, maddr must also be in valid range, \ - no need to check it again. */ \ - maddr = memory->heap_data + offset1 - DEFAULT_APP_HEAP_BASE_OFFSET; \ - } \ - else \ - goto out_of_bounds; \ +#define CHECK_MEMORY_OVERFLOW(bytes) do { \ + int32 offset1 = (int32)(offset + addr); \ + uint64 offset2 = (uint64)(uint32)(offset1 - heap_base_offset); \ + /* if (flags != 2) \ + LOG_VERBOSE("unaligned load/store, flag: %d.\n", flags); */ \ + if (offset2 + bytes <= total_mem_size) \ + /* If offset1 is in valid range, maddr must also be in valid range,\ + no need to check it again. */ \ + maddr = memory->memory_data + offset1; \ + else \ + goto out_of_bounds; \ } while (0) static inline uint32 @@ -501,10 +490,18 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign) frame_ip += 6; \ } while (0) +#if defined(BUILD_TARGET_X86_32) +#define DEF_OP_REINTERPRET(src_type) do { \ + void *src = frame_lp + GET_OFFSET(); \ + void *dst = frame_lp + GET_OFFSET(); \ + bh_memcpy_s(dst, sizeof(src_type), src, sizeof(src_type)); \ + } while (0) +#else #define DEF_OP_REINTERPRET(src_type) do { \ SET_OPERAND(src_type, 2, GET_OPERAND(src_type, 0)); \ frame_ip += 4; \ } while (0) +#endif #if WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 #define DEF_OP_NUMERIC_64 DEF_OP_NUMERIC @@ -779,9 +776,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, WASMInterpFrame *prev_frame) { WASMMemoryInstance *memory = module->default_memory; + int32 heap_base_offset = memory ? memory->heap_base_offset : 0; uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; - uint32 memory_data_size = memory ? num_bytes_per_page * memory->cur_page_count : 0; - uint32 heap_data_size = memory ? (uint32)(memory->heap_data_end - memory->heap_data) : 0; + uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count + - heap_base_offset : 0; uint8 *global_data = memory ? memory->global_data : NULL; WASMTableInstance *table = module->default_table; WASMGlobalInstance *globals = module->globals; @@ -929,10 +927,24 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, addr2 = GET_OFFSET(); addr_ret = GET_OFFSET(); - if (!cond) + if (!cond) { +#if defined(BUILD_TARGET_X86_32) + if (addr_ret != addr1) + bh_memcpy_s(frame_lp + addr_ret, sizeof(int32), + frame_lp + addr1, sizeof(int32)); +#else frame_lp[addr_ret] = frame_lp[addr1]; - else +#endif + } + else { +#if defined(BUILD_TARGET_X86_32) + if (addr_ret != addr2) + bh_memcpy_s(frame_lp + addr_ret, sizeof(int32), + frame_lp + addr2, sizeof(int32)); +#else frame_lp[addr_ret] = frame_lp[addr2]; +#endif + } HANDLE_OP_END (); } @@ -943,10 +955,24 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, addr2 = GET_OFFSET(); addr_ret = GET_OFFSET(); - if (!cond) + if (!cond) { +#if defined(BUILD_TARGET_X86_32) + if (addr_ret != addr1) + bh_memcpy_s(frame_lp + addr_ret, sizeof(int64), + frame_lp + addr1, sizeof(int64)); +#else *(int64*)(frame_lp + addr_ret) = *(int64*)(frame_lp + addr1); - else +#endif + } + else { +#if defined(BUILD_TARGET_X86_32) + if (addr_ret != addr2) + bh_memcpy_s(frame_lp + addr_ret, sizeof(int64), + frame_lp + addr2, sizeof(int64)); +#else *(int64*)(frame_lp + addr_ret) = *(int64*)(frame_lp + addr2); +#endif + } HANDLE_OP_END (); } @@ -1288,7 +1314,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, frame_lp[addr_ret] = prev_page_count; /* update the memory instance ptr */ memory = module->default_memory; - memory_data_size = num_bytes_per_page * memory->cur_page_count; + total_mem_size = num_bytes_per_page * memory->cur_page_count + - heap_base_offset; global_data = memory->global_data; } @@ -2061,13 +2088,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, HANDLE_OP (EXT_OP_COPY_STACK_TOP): addr1 = GET_OFFSET(); addr2 = GET_OFFSET(); +#if defined(BUILD_TARGET_X86_32) + bh_memcpy_s(frame_lp + addr2, sizeof(int32), + frame_lp + addr1, sizeof(int32)); +#else frame_lp[addr2] = frame_lp[addr1]; +#endif HANDLE_OP_END (); HANDLE_OP (EXT_OP_COPY_STACK_TOP_I64): addr1 = GET_OFFSET(); addr2 = GET_OFFSET(); +#if defined(BUILD_TARGET_X86_32) + bh_memcpy_s(frame_lp + addr2, sizeof(int64), + frame_lp + addr1, sizeof(int64)); +#else *(float64*)(frame_lp + addr2) = *(float64*)(frame_lp + addr1); +#endif HANDLE_OP_END (); HANDLE_OP (WASM_OP_SET_LOCAL): diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index f136f4c1..12f7c79b 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -2816,21 +2816,21 @@ wasm_loader_check_br(WASMLoaderContext *ctx, uint32 depth, #define GET_CONST_OFFSET(type, val) do { \ if (!(wasm_loader_get_const_offset(loader_ctx, type, \ - val, 0, 0, &operand_offset, \ + &val, &operand_offset, \ error_buf, error_buf_size))) \ goto fail; \ } while (0) #define GET_CONST_F32_OFFSET(type, fval) do { \ if (!(wasm_loader_get_const_offset(loader_ctx, type, \ - 0, fval, 0, &operand_offset, \ + &fval, &operand_offset, \ error_buf, error_buf_size))) \ goto fail; \ } while (0) #define GET_CONST_F64_OFFSET(type, fval) do { \ if (!(wasm_loader_get_const_offset(loader_ctx, type, \ - 0, 0, fval, &operand_offset, \ + &fval, &operand_offset, \ error_buf, error_buf_size))) \ goto fail; \ } while (0) @@ -3110,9 +3110,11 @@ wasm_loader_push_frame_offset(WASMLoaderContext *ctx, uint8 type, } ctx->frame_offset++; - ctx->dynamic_offset++; - if (ctx->dynamic_offset > ctx->max_dynamic_offset) - ctx->max_dynamic_offset = ctx->dynamic_offset; + if (!disable_emit) { + ctx->dynamic_offset++; + if (ctx->dynamic_offset > ctx->max_dynamic_offset) + ctx->max_dynamic_offset = ctx->dynamic_offset; + } return true; } @@ -3170,8 +3172,7 @@ wasm_loader_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 type, static bool wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, - int64 val_int, float32 val_f32, - float64 val_f64, int16 *offset, + void *value, int16 *offset, char *error_buf, uint32 error_buf_size) { int16 operand_offset = 0; @@ -3179,10 +3180,12 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, for (c = (Const *)ctx->const_buf; (uint8*)c < ctx->const_buf + ctx->num_const * sizeof(Const); c ++) { if ((type == c->value_type) - && ((type == VALUE_TYPE_I64 && (int64)val_int == c->value.i64) - || (type == VALUE_TYPE_I32 && (int32)val_int == c->value.i32) - || (type == VALUE_TYPE_F64 && (float64)val_f64 == c->value.f64) - || (type == VALUE_TYPE_F32 && (float32)val_f32 == c->value.f32))) { + && ((type == VALUE_TYPE_I64 && *(int64*)value == c->value.i64) + || (type == VALUE_TYPE_I32 && *(int32*)value == c->value.i32) + || (type == VALUE_TYPE_F64 + && (0 == memcmp(value, &(c->value.f64), sizeof(float64)))) + || (type == VALUE_TYPE_F32 + && (0 == memcmp(value, &(c->value.f32), sizeof(float32)))))) { operand_offset = c->slot_index; break; } @@ -3203,23 +3206,23 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, c->value_type = type; switch (type) { case VALUE_TYPE_F64: - c->value.f64 = (float64)val_f64; + bh_memcpy_s(&(c->value.f64), sizeof(WASMValue), value, sizeof(float64)); ctx->const_cell_num += 2; /* The const buf will be reversed, we use the second cell */ /* of the i64/f64 const so the finnal offset is corrent */ operand_offset ++; break; case VALUE_TYPE_I64: - c->value.i64 = (int64)val_int; + c->value.i64 = *(int64*)value; ctx->const_cell_num += 2; operand_offset ++; break; case VALUE_TYPE_F32: - c->value.f32 = (float32)val_f32; + bh_memcpy_s(&(c->value.f32), sizeof(WASMValue), value, sizeof(float32)); ctx->const_cell_num ++; break; case VALUE_TYPE_I32: - c->value.i32 = (int32)val_int; + c->value.i32 = *(int32*)value; ctx->const_cell_num ++; break; default: @@ -3495,8 +3498,8 @@ re_scan: if (loader_ctx->code_compiled_size > 0) { if (!wasm_loader_ctx_reinit(loader_ctx)) { set_error_buf(error_buf, error_buf_size, - "WASM loader prepare bytecode failed: " - "allocate memory failed"); + "WASM loader prepare bytecode failed: " + "allocate memory failed"); goto fail; } p = func->code; @@ -4005,7 +4008,7 @@ handle_next_reachable_block: #if WASM_ENABLE_FAST_INTERP != 0 if (loader_ctx->p_code_compiled) { #if WASM_ENABLE_ABS_LABEL_ADDR != 0 - *(void**)(loader_ctx->p_code_compiled - 10) = + *(void**)(loader_ctx->p_code_compiled - 2 - sizeof(void*)) = handle_table[WASM_OP_SELECT_64]; #else *((int16*)loader_ctx->p_code_compiled - 2) = (int16) @@ -4373,7 +4376,7 @@ handle_next_reachable_block: #if WASM_ENABLE_FAST_INTERP != 0 skip_label(); disable_emit = true; - f32 = *(float32 *)p_org; + bh_memcpy_s((uint8*)&f32, sizeof(float32), p_org, sizeof(float32)); GET_CONST_F32_OFFSET(VALUE_TYPE_F32, f32); #endif PUSH_F32(); @@ -4385,7 +4388,7 @@ handle_next_reachable_block: skip_label(); disable_emit = true; /* Some MCU may require 8-byte align */ - memcpy((uint8*)&f64, p_org, sizeof(float64)); + bh_memcpy_s((uint8*)&f64, sizeof(float64), p_org, sizeof(float64)); GET_CONST_F64_OFFSET(VALUE_TYPE_F64, f64); #endif PUSH_F64(); @@ -4687,10 +4690,11 @@ handle_next_reachable_block: if (c->value_type == VALUE_TYPE_F64 || c->value_type == VALUE_TYPE_I64) { bh_memcpy_s(func_const, func_const_end - func_const, - &c->value.f64, sizeof(int64)); + &(c->value.f64), sizeof(int64)); func_const += sizeof(int64); } else { - *(uint32*)func_const = c->value.i32; + bh_memcpy_s(func_const, func_const_end - func_const, + &(c->value.f32), sizeof(int32)); func_const += sizeof(int32); } } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index e69730da..06f4f896 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -51,7 +51,6 @@ memories_deinstantiate(WASMMemoryInstance **memories, uint32 count) if (memories[i]) { if (memories[i]->heap_handle) mem_allocator_destroy(memories[i]->heap_handle); - wasm_runtime_free(memories[i]->heap_data); wasm_runtime_free(memories[i]); } wasm_runtime_free(memories); @@ -67,6 +66,7 @@ memory_instantiate(uint32 num_bytes_per_page, { WASMMemoryInstance *memory; uint64 total_size = offsetof(WASMMemoryInstance, base_addr) + + (uint64)heap_size + num_bytes_per_page * (uint64)init_page_count + global_data_size; @@ -83,42 +83,28 @@ memory_instantiate(uint32 num_bytes_per_page, memory->cur_page_count = init_page_count; memory->max_page_count = max_page_count; - memory->memory_data = memory->base_addr; - + memory->heap_data = memory->base_addr; + memory->memory_data = memory->heap_data + heap_size; memory->global_data = memory->memory_data + num_bytes_per_page * memory->cur_page_count; memory->global_data_size = global_data_size; - memory->end_addr = memory->global_data + global_data_size; - /* Allocate heap space */ - if (!(memory->heap_data = wasm_runtime_malloc(heap_size))) { - set_error_buf(error_buf, error_buf_size, - "Instantiate memory failed: allocate memory failed."); - goto fail1; - } - memory->heap_data_end = memory->heap_data + heap_size; + bh_assert(memory->end_addr - (uint8*)memory == (uint32)total_size); /* Initialize heap */ if (!(memory->heap_handle = mem_allocator_create (memory->heap_data, heap_size))) { - goto fail2; + wasm_runtime_free(memory); + return NULL; } -#if WASM_ENABLE_MEMORY_GROW != 0 - memory->heap_base_offset = DEFAULT_APP_HEAP_BASE_OFFSET; +#if WASM_ENABLE_SPEC_TEST == 0 + memory->heap_base_offset = -(int32)heap_size; #else - memory->heap_base_offset = memory->end_addr - memory->memory_data; + memory->heap_base_offset = 0; #endif - return memory; - -fail2: - wasm_runtime_free(memory->heap_data); - -fail1: - wasm_runtime_free(memory); - return NULL; } /** @@ -811,6 +797,10 @@ wasm_instantiate(WASMModule *module, /* Initialize the thread related data */ if (stack_size == 0) stack_size = DEFAULT_WASM_STACK_SIZE; +#if WASM_ENABLE_SPEC_TEST != 0 + if (stack_size < 48 *1024) + stack_size = 48 * 1024; +#endif module_inst->default_wasm_stack_size = stack_size; /* Execute __post_instantiate function */ @@ -923,13 +913,13 @@ wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size, { WASMMemoryInstance *memory = module_inst->default_memory; uint8 *addr = mem_allocator_malloc(memory->heap_handle, size); - if (p_native_addr) - *p_native_addr = addr; if (!addr) { wasm_set_exception(module_inst, "out of memory"); return 0; } - return memory->heap_base_offset + (int32)(addr - memory->heap_data); + if (p_native_addr) + *p_native_addr = addr; + return (int32)(addr - memory->memory_data); } void @@ -937,8 +927,8 @@ wasm_module_free(WASMModuleInstance *module_inst, int32 ptr) { if (ptr) { WASMMemoryInstance *memory = module_inst->default_memory; - uint8 *addr = memory->heap_data + (ptr - memory->heap_base_offset); - if (memory->heap_data < addr && addr < memory->heap_data_end) + uint8 *addr = memory->memory_data + ptr; + if (memory->heap_data < addr && addr < memory->memory_data) mem_allocator_free(memory->heap_handle, addr); } } @@ -961,31 +951,20 @@ bool wasm_validate_app_addr(WASMModuleInstance *module_inst, int32 app_offset, uint32 size) { - WASMMemoryInstance *memory; - uint8 *addr; + WASMMemoryInstance *memory = module_inst->default_memory; + int32 memory_data_size = + (int32)(memory->num_bytes_per_page * memory->cur_page_count); /* integer overflow check */ - if(app_offset + (int32)size < app_offset) { + if (app_offset + (int32)size < app_offset) { goto fail; } - memory = module_inst->default_memory; - if (0 <= app_offset - && app_offset < memory->heap_base_offset) { - addr = memory->memory_data + app_offset; - if (!(memory->base_addr <= addr && addr + size <= memory->end_addr)) - goto fail; - return true; + if (app_offset <= memory->heap_base_offset + || app_offset + (int32)size > memory_data_size) { + goto fail; } - else if (memory->heap_base_offset < app_offset - && app_offset < memory->heap_base_offset - + (memory->heap_data_end - memory->heap_data)) { - addr = memory->heap_data + (app_offset - memory->heap_base_offset); - if (!(memory->heap_data <= addr && addr + size <= memory->heap_data_end)) - goto fail; - return true; - } - + return true; fail: wasm_set_exception(module_inst, "out of bounds memory access"); return false; @@ -995,18 +974,20 @@ bool wasm_validate_native_addr(WASMModuleInstance *module_inst, void *native_ptr, uint32 size) { - uint8 *addr = native_ptr; + uint8 *addr = (uint8*)native_ptr; WASMMemoryInstance *memory = module_inst->default_memory; + int32 memory_data_size = + (int32)(memory->num_bytes_per_page * memory->cur_page_count); if (addr + size < addr) { goto fail; } - if ((memory->base_addr <= addr && addr + size <= memory->end_addr) - || (memory->heap_data <= addr && addr + size <= memory->heap_data_end) - ) - return true; - + if (addr <= memory->heap_data + || addr + size > memory->memory_data + memory_data_size) { + goto fail; + } + return true; fail: wasm_set_exception(module_inst, "out of bounds memory access"); return false; @@ -1017,14 +998,13 @@ wasm_addr_app_to_native(WASMModuleInstance *module_inst, int32 app_offset) { WASMMemoryInstance *memory = module_inst->default_memory; - if (0 <= app_offset && app_offset < memory->heap_base_offset) + int32 memory_data_size = + (int32)(memory->num_bytes_per_page * memory->cur_page_count); + + if (memory->heap_base_offset < app_offset + && app_offset < memory_data_size) return memory->memory_data + app_offset; - else if (memory->heap_base_offset < app_offset - && app_offset < memory->heap_base_offset - + (memory->heap_data_end - memory->heap_data)) - return memory->heap_data + (app_offset - memory->heap_base_offset); - else - return NULL; + return NULL; } int32 @@ -1032,15 +1012,14 @@ wasm_addr_native_to_app(WASMModuleInstance *module_inst, void *native_ptr) { WASMMemoryInstance *memory = module_inst->default_memory; - if (memory->base_addr <= (uint8*)native_ptr - && (uint8*)native_ptr < memory->end_addr) - return (int32)((uint8*)native_ptr - memory->memory_data); - else if (memory->heap_data <= (uint8*)native_ptr - && (uint8*)native_ptr < memory->heap_data_end) - return memory->heap_base_offset - + (int32)((uint8*)native_ptr - memory->heap_data); - else - return 0; + uint8 *addr = (uint8*)native_ptr; + int32 memory_data_size = + (int32)(memory->num_bytes_per_page * memory->cur_page_count); + + if (memory->heap_data < addr + && addr < memory->memory_data + memory_data_size) + return (int32)(addr - memory->memory_data); + return 0; } bool @@ -1049,28 +1028,19 @@ wasm_get_app_addr_range(WASMModuleInstance *module_inst, int32 *p_app_start_offset, int32 *p_app_end_offset) { - int32 app_start_offset, app_end_offset; WASMMemoryInstance *memory = module_inst->default_memory; + int32 memory_data_size = + (int32)(memory->num_bytes_per_page * memory->cur_page_count); - if (0 <= app_offset && app_offset < memory->heap_base_offset) { - app_start_offset = 0; - app_end_offset = (int32)(memory->num_bytes_per_page * memory->cur_page_count); + if (memory->heap_base_offset < app_offset + && app_offset < memory_data_size) { + if (p_app_start_offset) + *p_app_start_offset = memory->heap_base_offset; + if (p_app_end_offset) + *p_app_end_offset = memory_data_size; + return true; } - else if (memory->heap_base_offset < app_offset - && app_offset < memory->heap_base_offset - + (memory->heap_data_end - memory->heap_data)) { - app_start_offset = memory->heap_base_offset; - app_end_offset = memory->heap_base_offset - + (int32)(memory->heap_data_end - memory->heap_data); - } - else - return false; - - if (p_app_start_offset) - *p_app_start_offset = app_start_offset; - if (p_app_end_offset) - *p_app_end_offset = app_end_offset; - return true; + return false; } bool @@ -1079,42 +1049,36 @@ wasm_get_native_addr_range(WASMModuleInstance *module_inst, uint8 **p_native_start_addr, uint8 **p_native_end_addr) { - uint8 *native_start_addr, *native_end_addr; WASMMemoryInstance *memory = module_inst->default_memory; + uint8 *addr = (uint8*)native_ptr; + int32 memory_data_size = + (int32)(memory->num_bytes_per_page * memory->cur_page_count); - if (memory->base_addr <= (uint8*)native_ptr - && (uint8*)native_ptr < memory->end_addr) { - native_start_addr = memory->memory_data; - native_end_addr = memory->memory_data - + memory->num_bytes_per_page * memory->cur_page_count; + if (memory->heap_data < addr + && addr < memory->memory_data + memory_data_size) { + if (p_native_start_addr) + *p_native_start_addr = memory->heap_data; + if (p_native_end_addr) + *p_native_end_addr = memory->memory_data + memory_data_size; + return true; } - else if (memory->heap_data <= (uint8*)native_ptr - && (uint8*)native_ptr < memory->heap_data_end) { - native_start_addr = memory->heap_data; - native_end_addr = memory->heap_data_end; - } - else - return false; - - if (p_native_start_addr) - *p_native_start_addr = native_start_addr; - if (p_native_end_addr) - *p_native_end_addr = native_end_addr; - return true; + return false; } bool wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) { -#if WASM_ENABLE_MEMORY_GROW != 0 WASMMemoryInstance *memory = module->default_memory, *new_memory; + uint32 heap_size = memory->memory_data - memory->heap_data; uint32 old_page_count = memory->cur_page_count; uint32 total_size_old = memory->end_addr - (uint8*)memory; uint32 total_page_count = inc_page_count + memory->cur_page_count; - uint64 total_size = offsetof(WASMMemoryInstance, base_addr) + - memory->num_bytes_per_page * (uint64)total_page_count + - memory->global_data_size; + uint64 total_size = offsetof(WASMMemoryInstance, base_addr) + + (uint64)heap_size + + memory->num_bytes_per_page * (uint64)total_page_count + + memory->global_data_size; uint8 *global_data_old; + void *heap_handle_old = memory->heap_handle; if (inc_page_count <= 0) /* No need to enlarge memory */ @@ -1131,8 +1095,13 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) return false; } + /* Destroy heap's lock firstly, if its memory is re-allocated, + we cannot access its lock again. */ + mem_allocator_destroy_lock(memory->heap_handle); if (!(new_memory = wasm_runtime_realloc(memory, (uint32)total_size))) { if (!(new_memory = wasm_runtime_malloc((uint32)total_size))) { + /* Restore heap's lock if memory re-alloc failed */ + mem_allocator_reinit_lock(memory->heap_handle); wasm_set_exception(module, "fail to enlarge memory."); return false; } @@ -1144,8 +1113,17 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) memset((uint8*)new_memory + total_size_old, 0, (uint32)total_size - total_size_old); + new_memory->heap_handle = (uint8*)heap_handle_old + + ((uint8*)new_memory - (uint8*)memory); + if (mem_allocator_migrate(new_memory->heap_handle, + heap_handle_old) != 0) { + wasm_set_exception(module, "fail to enlarge memory."); + return false; + } + new_memory->cur_page_count = total_page_count; - new_memory->memory_data = new_memory->base_addr; + new_memory->heap_data = new_memory->base_addr; + new_memory->memory_data = new_memory->base_addr + heap_size; new_memory->global_data = new_memory->memory_data + new_memory->num_bytes_per_page * total_page_count; new_memory->end_addr = new_memory->global_data + new_memory->global_data_size; @@ -1160,10 +1138,6 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) module->memories[0] = module->default_memory = new_memory; return true; -#else /* else of WASM_ENABLE_MEMORY_GROW */ - wasm_set_exception(module, "unsupported operation: enlarge memory."); - return false; -#endif /* end of WASM_ENABLE_MEMORY_GROW */ } diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 03a5e4d4..dd512494 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -23,17 +23,16 @@ typedef struct WASMMemoryInstance { /* Maximum page count */ uint32 max_page_count; - /* Heap data base address */ - uint8 *heap_data; - /* Heap data end address */ - uint8 *heap_data_end; - /* The heap created */ - void *heap_handle; /* Heap base offset of wasm app */ int32 heap_base_offset; + /* Heap data base address */ + uint8 *heap_data; + /* The heap created */ + void *heap_handle; /* Memory data */ uint8 *memory_data; + /* Global data of global instances */ uint8 *global_data; uint32 global_data_size; @@ -42,12 +41,11 @@ typedef struct WASMMemoryInstance { uint8 *end_addr; /* Base address, the layout is: - thunk_argv data + thunk arg offsets + - memory data + global data + heap_data + memory data + global data memory data init size is: num_bytes_per_page * cur_page_count global data size is calculated in module instantiating - Note: when memory is re-allocated, the thunk argv data, thunk - argv offsets and memory data must be copied to new memory also. + Note: when memory is re-allocated, the heap data and memory data + must be copied to new memory also. */ uint8 base_addr[1]; } WASMMemoryInstance; diff --git a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c index a0f1d432..c5780dbd 100644 --- a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c +++ b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c @@ -46,26 +46,54 @@ typedef struct iovec_app { } iovec_app_t; typedef struct WASIContext { - void *curfds; - void *prestats; - void *argv_environ; + int32 curfds_offset; + int32 prestats_offset; + int32 argv_environ_offset; } *wasi_ctx_t; wasi_ctx_t wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst); +static struct fd_table * +wasi_ctx_get_curfds(wasm_module_inst_t module_inst, + wasi_ctx_t wasi_ctx) +{ + return (struct fd_table *) + wasm_runtime_addr_app_to_native(module_inst, + wasi_ctx->curfds_offset); +} + +static struct argv_environ_values * +wasi_ctx_get_argv_environ(wasm_module_inst_t module_inst, + wasi_ctx_t wasi_ctx) +{ + return (struct argv_environ_values *) + wasm_runtime_addr_app_to_native(module_inst, + wasi_ctx->argv_environ_offset); +} + +static struct fd_prestats * +wasi_ctx_get_prestats(wasm_module_inst_t module_inst, + wasi_ctx_t wasi_ctx) +{ + return (struct fd_prestats *) + wasm_runtime_addr_app_to_native(module_inst, + wasi_ctx->prestats_offset); +} + static wasi_errno_t wasi_args_get(wasm_exec_env_t exec_env, int32 *argv_offsets, char *argv_buf) { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct argv_environ_values *argv_environ = + wasi_ctx_get_argv_environ(module_inst, wasi_ctx); size_t argc, argv_buf_size, i; char **argv; uint64 total_size; wasi_errno_t err; - err = wasmtime_ssp_args_sizes_get(wasi_ctx->argv_environ, - &argc, &argv_buf_size); + err = wasmtime_ssp_args_sizes_get(argv_environ, &argc, &argv_buf_size); if (err) return err; @@ -81,7 +109,7 @@ wasi_args_get(wasm_exec_env_t exec_env, int32 *argv_offsets, char *argv_buf) || !(argv = wasm_runtime_malloc((uint32)total_size))) return (wasi_errno_t)-1; - err = wasmtime_ssp_args_get(wasi_ctx->argv_environ, argv, argv_buf); + err = wasmtime_ssp_args_get(argv_environ, argv, argv_buf); if (err) { wasm_runtime_free(argv); return err; @@ -101,6 +129,7 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct argv_environ_values *argv_environ; size_t argc, argv_buf_size; wasi_errno_t err; @@ -108,7 +137,11 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env, || !validate_native_addr(argv_buf_size_app, sizeof(uint32))) return (wasi_errno_t)-1; - err = wasmtime_ssp_args_sizes_get(wasi_ctx->argv_environ, + argv_environ = (struct argv_environ_values *) + wasm_runtime_addr_app_to_native(module_inst, + wasi_ctx->argv_environ_offset); + + err = wasmtime_ssp_args_sizes_get(argv_environ, &argc, &argv_buf_size); if (err) return err; @@ -151,12 +184,14 @@ wasi_environ_get(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct argv_environ_values *argv_environ = + wasi_ctx_get_argv_environ(module_inst, wasi_ctx); size_t environ_count, environ_buf_size, i; uint64 total_size; char **environs; wasi_errno_t err; - err = wasmtime_ssp_environ_sizes_get(wasi_ctx->argv_environ, + err = wasmtime_ssp_environ_sizes_get(argv_environ, &environ_count, &environ_buf_size); if (err) return err; @@ -174,7 +209,7 @@ wasi_environ_get(wasm_exec_env_t exec_env, || !(environs = wasm_runtime_malloc((uint32)total_size))) return (wasi_errno_t)-1; - err = wasmtime_ssp_environ_get(wasi_ctx->argv_environ, environs, environ_buf); + err = wasmtime_ssp_environ_get(argv_environ, environs, environ_buf); if (err) { wasm_runtime_free(environs); return err; @@ -194,6 +229,8 @@ wasi_environ_sizes_get(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct argv_environ_values *argv_environ = + wasi_ctx_get_argv_environ(module_inst, wasi_ctx); size_t environ_count, environ_buf_size; wasi_errno_t err; @@ -201,7 +238,7 @@ wasi_environ_sizes_get(wasm_exec_env_t exec_env, || !validate_native_addr(environ_buf_size_app, sizeof(uint32))) return (wasi_errno_t)-1; - err = wasmtime_ssp_environ_sizes_get(wasi_ctx->argv_environ, + err = wasmtime_ssp_environ_sizes_get(argv_environ, &environ_count, &environ_buf_size); if (err) return err; @@ -218,13 +255,14 @@ wasi_fd_prestat_get(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx); wasi_prestat_t prestat; wasi_errno_t err; if (!validate_native_addr(prestat_app, sizeof(wasi_prestat_app_t))) return (wasi_errno_t)-1; - err = wasmtime_ssp_fd_prestat_get(wasi_ctx->prestats, fd, &prestat); + err = wasmtime_ssp_fd_prestat_get(prestats, fd, &prestat); if (err) return err; @@ -239,8 +277,9 @@ wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx); - return wasmtime_ssp_fd_prestat_dir_name(wasi_ctx->prestats, + return wasmtime_ssp_fd_prestat_dir_name(prestats, fd, path, path_len); } @@ -249,8 +288,10 @@ wasi_fd_close(wasm_exec_env_t exec_env, wasi_fd_t fd) { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); + struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx); - return wasmtime_ssp_fd_close(wasi_ctx->curfds, wasi_ctx->prestats, fd); + return wasmtime_ssp_fd_close(curfds, prestats, fd); } static wasi_errno_t @@ -258,8 +299,9 @@ wasi_fd_datasync(wasm_exec_env_t exec_env, wasi_fd_t fd) { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_fd_datasync(wasi_ctx->curfds, fd); + return wasmtime_ssp_fd_datasync(curfds, fd); } static wasi_errno_t @@ -269,6 +311,7 @@ wasi_fd_pread(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); wasi_iovec_t *iovec, *iovec_begin; uint64 total_size; size_t nread; @@ -298,7 +341,7 @@ wasi_fd_pread(wasm_exec_env_t exec_env, iovec->buf_len = iovec_app->buf_len; } - err = wasmtime_ssp_fd_pread(wasi_ctx->curfds, fd, iovec_begin, + err = wasmtime_ssp_fd_pread(curfds, fd, iovec_begin, iovs_len, offset, &nread); if (err) goto fail; @@ -320,6 +363,7 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); wasi_ciovec_t *ciovec, *ciovec_begin; uint64 total_size; size_t nwritten; @@ -349,7 +393,7 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env, ciovec->buf_len = iovec_app->buf_len; } - err = wasmtime_ssp_fd_pwrite(wasi_ctx->curfds, fd, ciovec_begin, + err = wasmtime_ssp_fd_pwrite(curfds, fd, ciovec_begin, iovs_len, offset, &nwritten); if (err) goto fail; @@ -371,6 +415,7 @@ wasi_fd_read(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); wasi_iovec_t *iovec, *iovec_begin; uint64 total_size; size_t nread; @@ -400,7 +445,7 @@ wasi_fd_read(wasm_exec_env_t exec_env, iovec->buf_len = iovec_app->buf_len; } - err = wasmtime_ssp_fd_read(wasi_ctx->curfds, fd, + err = wasmtime_ssp_fd_read(curfds, fd, iovec_begin, iovs_len, &nread); if (err) goto fail; @@ -420,9 +465,10 @@ wasi_fd_renumber(wasm_exec_env_t exec_env, wasi_fd_t from, wasi_fd_t to) { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); + struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx); - return wasmtime_ssp_fd_renumber(wasi_ctx->curfds, - wasi_ctx->prestats, from, to); + return wasmtime_ssp_fd_renumber(curfds, prestats, from, to); } static wasi_errno_t @@ -432,12 +478,12 @@ wasi_fd_seek(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t))) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_seek(wasi_ctx->curfds, fd, - offset, whence, newoffset); + return wasmtime_ssp_fd_seek(curfds, fd, offset, whence, newoffset); } static wasi_errno_t @@ -446,11 +492,12 @@ wasi_fd_tell(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t))) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_tell(wasi_ctx->curfds, fd, newoffset); + return wasmtime_ssp_fd_tell(curfds, fd, newoffset); } static wasi_errno_t @@ -459,13 +506,14 @@ wasi_fd_fdstat_get(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); wasi_fdstat_t fdstat; wasi_errno_t err; if (!validate_native_addr(fdstat_app, sizeof(wasi_fdstat_t))) return (wasi_errno_t)-1; - err = wasmtime_ssp_fd_fdstat_get(wasi_ctx->curfds, fd, &fdstat); + err = wasmtime_ssp_fd_fdstat_get(curfds, fd, &fdstat); if (err) return err; @@ -479,8 +527,9 @@ wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_fd_fdstat_set_flags(wasi_ctx->curfds, fd, flags); + return wasmtime_ssp_fd_fdstat_set_flags(curfds, fd, flags); } static wasi_errno_t @@ -491,8 +540,9 @@ wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_fd_fdstat_set_rights(wasi_ctx->curfds, fd, + return wasmtime_ssp_fd_fdstat_set_rights(curfds, fd, fs_rights_base, fs_rights_inheriting); } @@ -501,8 +551,9 @@ wasi_fd_sync(wasm_exec_env_t exec_env, wasi_fd_t fd) { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_fd_sync(wasi_ctx->curfds, fd); + return wasmtime_ssp_fd_sync(curfds, fd); } static wasi_errno_t @@ -512,6 +563,7 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); wasi_ciovec_t *ciovec, *ciovec_begin; uint64 total_size; size_t nwritten; @@ -541,7 +593,7 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd, ciovec->buf_len = iovec_app->buf_len; } - err = wasmtime_ssp_fd_write(wasi_ctx->curfds, fd, + err = wasmtime_ssp_fd_write(curfds, fd, ciovec_begin, iovs_len, &nwritten); if (err) goto fail; @@ -565,8 +617,9 @@ wasi_fd_advise(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_fd_advise(wasi_ctx->curfds, fd, offset, len, advice); + return wasmtime_ssp_fd_advise(curfds, fd, offset, len, advice); } static wasi_errno_t @@ -577,8 +630,9 @@ wasi_fd_allocate(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_fd_allocate(wasi_ctx->curfds, fd, offset, len); + return wasmtime_ssp_fd_allocate(curfds, fd, offset, len); } static wasi_errno_t @@ -587,8 +641,9 @@ wasi_path_create_directory(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_path_create_directory(wasi_ctx->curfds, fd, + return wasmtime_ssp_path_create_directory(curfds, fd, path, path_len); } @@ -602,8 +657,10 @@ wasi_path_link(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); + struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx); - return wasmtime_ssp_path_link(wasi_ctx->curfds, wasi_ctx->prestats, + return wasmtime_ssp_path_link(curfds, prestats, old_fd, old_flags, old_path, old_path_len, new_fd, new_path, new_path_len); } @@ -621,20 +678,21 @@ wasi_path_open(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); wasi_fd_t fd = -1; /* set fd_app -1 if path open failed */ wasi_errno_t err; if (!validate_native_addr(fd_app, sizeof(wasi_fd_t))) return (wasi_errno_t)-1; - err = wasmtime_ssp_path_open(wasi_ctx->curfds, - dirfd, dirflags, - path, path_len, - oflags, - fs_rights_base, - fs_rights_inheriting, - fs_flags, - &fd); + err = wasmtime_ssp_path_open(curfds, + dirfd, dirflags, + path, path_len, + oflags, + fs_rights_base, + fs_rights_inheriting, + fs_flags, + &fd); *fd_app = fd; return err; @@ -649,13 +707,14 @@ wasi_fd_readdir(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); size_t bufused; wasi_errno_t err; if (!validate_native_addr(bufused_app, sizeof(uint32))) return (wasi_errno_t)-1; - err = wasmtime_ssp_fd_readdir(wasi_ctx->curfds, fd, + err = wasmtime_ssp_fd_readdir(curfds, fd, buf, buf_len, cookie, &bufused); if (err) return err; @@ -673,13 +732,14 @@ wasi_path_readlink(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); size_t bufused; wasi_errno_t err; if (!validate_native_addr(bufused_app, sizeof(uint32))) return (wasi_errno_t)-1; - err = wasmtime_ssp_path_readlink(wasi_ctx->curfds, fd, + err = wasmtime_ssp_path_readlink(curfds, fd, path, path_len, buf, buf_len, &bufused); if (err) @@ -696,8 +756,9 @@ wasi_path_rename(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_path_rename(wasi_ctx->curfds, + return wasmtime_ssp_path_rename(curfds, old_fd, old_path, old_path_len, new_fd, new_path, new_path_len); } @@ -708,11 +769,12 @@ wasi_fd_filestat_get(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); if (!validate_native_addr(filestat, sizeof(wasi_filestat_t))) return (wasi_errno_t)-1; - return wasmtime_ssp_fd_filestat_get(wasi_ctx->curfds, fd, filestat); + return wasmtime_ssp_fd_filestat_get(curfds, fd, filestat); } static wasi_errno_t @@ -724,8 +786,9 @@ wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_fd_filestat_set_times(wasi_ctx->curfds, fd, + return wasmtime_ssp_fd_filestat_set_times(curfds, fd, st_atim, st_mtim, fstflags); } @@ -736,8 +799,9 @@ wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_fd_filestat_set_size(wasi_ctx->curfds, fd, st_size); + return wasmtime_ssp_fd_filestat_set_size(curfds, fd, st_size); } static wasi_errno_t @@ -749,11 +813,12 @@ wasi_path_filestat_get(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); if (!validate_native_addr(filestat, sizeof(wasi_filestat_t))) return (wasi_errno_t)-1; - return wasmtime_ssp_path_filestat_get(wasi_ctx->curfds, fd, + return wasmtime_ssp_path_filestat_get(curfds, fd, flags, path, path_len, filestat); } @@ -768,8 +833,9 @@ wasi_path_filestat_set_times(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_path_filestat_set_times(wasi_ctx->curfds, fd, + return wasmtime_ssp_path_filestat_set_times(curfds, fd, flags, path, path_len, st_atim, st_mtim, fstflags); } @@ -781,8 +847,10 @@ wasi_path_symlink(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); + struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx); - return wasmtime_ssp_path_symlink(wasi_ctx->curfds, wasi_ctx->prestats, + return wasmtime_ssp_path_symlink(curfds, prestats, old_path, old_path_len, fd, new_path, new_path_len); } @@ -793,8 +861,9 @@ wasi_path_unlink_file(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_path_unlink_file(wasi_ctx->curfds, fd, path, path_len); + return wasmtime_ssp_path_unlink_file(curfds, fd, path, path_len); } static wasi_errno_t @@ -803,8 +872,9 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_path_remove_directory(wasi_ctx->curfds, fd, path, path_len); + return wasmtime_ssp_path_remove_directory(curfds, fd, path, path_len); } static wasi_errno_t @@ -814,6 +884,7 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); size_t nevents; wasi_errno_t err; @@ -822,7 +893,7 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env, || !validate_native_addr(nevents_app, sizeof(uint32))) return (wasi_errno_t)-1; - err = wasmtime_ssp_poll_oneoff(wasi_ctx->curfds, in, out, + err = wasmtime_ssp_poll_oneoff(curfds, in, out, nsubscriptions, &nevents); if (err) return err; @@ -864,6 +935,7 @@ wasi_sock_recv(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); wasi_iovec_t *iovec, *iovec_begin; uint64 total_size; size_t ro_datalen; @@ -894,7 +966,7 @@ wasi_sock_recv(wasm_exec_env_t exec_env, iovec->buf_len = ri_data->buf_len; } - err = wasmtime_ssp_sock_recv(wasi_ctx->curfds, sock, + err = wasmtime_ssp_sock_recv(curfds, sock, iovec_begin, ri_data_len, ri_flags, &ro_datalen, ro_flags); @@ -920,6 +992,7 @@ wasi_sock_send(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); wasi_ciovec_t *ciovec, *ciovec_begin; uint64 total_size; size_t so_datalen; @@ -949,7 +1022,7 @@ wasi_sock_send(wasm_exec_env_t exec_env, ciovec->buf_len = si_data->buf_len; } - err = wasmtime_ssp_sock_send(wasi_ctx->curfds, sock, + err = wasmtime_ssp_sock_send(curfds, sock, ciovec_begin, si_data_len, si_flags, &so_datalen); if (err) @@ -971,8 +1044,9 @@ wasi_sock_shutdown(wasm_exec_env_t exec_env, { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); + struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasmtime_ssp_sock_shutdown(wasi_ctx->curfds, sock, how); + return wasmtime_ssp_sock_shutdown(curfds, sock, how); } static wasi_errno_t diff --git a/core/shared/mem-alloc/ems/ems_alloc.c b/core/shared/mem-alloc/ems/ems_alloc.c index 45d6b585..167f656a 100644 --- a/core/shared/mem-alloc/ems/ems_alloc.c +++ b/core/shared/mem-alloc/ems/ems_alloc.c @@ -404,10 +404,11 @@ gc_realloc_vo_internal(void *vheap, void *ptr, gc_size_t size, #endif { gc_heap_t* heap = (gc_heap_t*) vheap; - hmu_t *hmu = NULL, *hmu_old = NULL; + hmu_t *hmu = NULL, *hmu_old = NULL, *hmu_next; gc_object_t ret = (gc_object_t) NULL, obj_old = (gc_object_t)ptr; - gc_size_t tot_size, tot_size_unaligned, tot_size_old = 0; + gc_size_t tot_size, tot_size_unaligned, tot_size_old = 0, tot_size_next; gc_size_t obj_size, obj_size_old; + hmu_type_t ut; /* hmu header + prefix + obj + suffix */ tot_size_unaligned = HMU_SIZE + OBJ_PREFIX_SIZE + size + OBJ_SUFFIX_SIZE; @@ -427,6 +428,32 @@ gc_realloc_vo_internal(void *vheap, void *ptr, gc_size_t size, os_mutex_lock(&heap->lock); + if (hmu_old) { + hmu_next = (hmu_t*)((char *)hmu_old + tot_size_old); + if (hmu_is_in_heap(heap, hmu_next)) { + ut = hmu_get_ut(hmu_next); + tot_size_next = hmu_get_size(hmu_next); + if (ut == HMU_FC + && tot_size <= tot_size_old + tot_size_next) { + /* current node and next node meets requirement */ + unlink_hmu(heap, hmu_next); + hmu_set_size(hmu_old, tot_size); + memset((char*)hmu_old + tot_size_old, 0, tot_size - tot_size_old); +#if BH_ENABLE_GC_VERIFY != 0 + hmu_init_prefix_and_suffix(hmu_old, tot_size, file, line); +#endif + if (tot_size < tot_size_old + tot_size_next) { + hmu_next = (hmu_t*)((char*)hmu_old + tot_size); + tot_size_next = tot_size_old + tot_size_next - tot_size; + gci_add_fc(heap, hmu_next, tot_size_next); + } + os_mutex_unlock(&heap->lock); + return obj_old; + } + } + } + + hmu = alloc_hmu_ex(heap, tot_size); if (!hmu) goto finish; diff --git a/core/shared/mem-alloc/ems/ems_gc.h b/core/shared/mem-alloc/ems/ems_gc.h index 636d3b5e..206c8bd0 100644 --- a/core/shared/mem-alloc/ems/ems_gc.h +++ b/core/shared/mem-alloc/ems/ems_gc.h @@ -72,6 +72,35 @@ gc_init_with_pool(char *buf, gc_size_t buf_size); int gc_destroy_with_pool(gc_handle_t handle); +/** + * Migrate heap from one place to another place + * + * @param handle handle of the new heap + * @param handle_old handle of the old heap + * + * @return GC_SUCCESS if success, GC_ERROR otherwise + */ +int +gc_migrate(gc_handle_t handle, gc_handle_t handle_old); + +/** + * Re-initialize lock of heap + * + * @param handle the heap handle + * + * @return GC_SUCCESS if success, GC_ERROR otherwise + */ +int +gc_reinit_lock(gc_handle_t handle); + +/** + * Destroy lock of heap + * + * @param handle the heap handle + */ +void +gc_destroy_lock(gc_handle_t handle); + /** * Get Heap Stats * diff --git a/core/shared/mem-alloc/ems/ems_gc_internal.h b/core/shared/mem-alloc/ems/ems_gc_internal.h index 717149b9..976a32a6 100644 --- a/core/shared/mem-alloc/ems/ems_gc_internal.h +++ b/core/shared/mem-alloc/ems/ems_gc_internal.h @@ -192,7 +192,6 @@ typedef struct gc_heap_struct { gc_uint8 *base_addr; gc_size_t current_size; - gc_size_t max_size; korp_mutex lock; diff --git a/core/shared/mem-alloc/ems/ems_kfc.c b/core/shared/mem-alloc/ems/ems_kfc.c index d0ec2548..e0b0edb8 100644 --- a/core/shared/mem-alloc/ems/ems_kfc.c +++ b/core/shared/mem-alloc/ems/ems_kfc.c @@ -35,7 +35,6 @@ gc_init_with_pool(char *buf, gc_size_t buf_size) } /* init all data structures*/ - heap->max_size = heap_max_size; heap->current_size = heap_max_size; heap->base_addr = (gc_uint8*)base_addr; heap->heap_id = (gc_handle_t)heap; @@ -82,11 +81,72 @@ gc_destroy_with_pool(gc_handle_t handle) { gc_heap_t *heap = (gc_heap_t *) handle; os_mutex_destroy(&heap->lock); - memset(heap->base_addr, 0, heap->max_size); + memset(heap->base_addr, 0, heap->current_size); memset(heap, 0, sizeof(gc_heap_t)); return GC_SUCCESS; } +static void +adjust_ptr(uint8 **p_ptr, intptr_t offset) +{ + if (*p_ptr) + *p_ptr += offset; +} + +int +gc_migrate(gc_handle_t handle, gc_handle_t handle_old) +{ + gc_heap_t *heap = (gc_heap_t *) handle; + intptr_t offset = (uint8*)handle - (uint8*)handle_old; + hmu_t *cur = NULL, *end = NULL; + hmu_tree_node_t *tree_node; + gc_size_t size; + + os_mutex_init(&heap->lock); + + if (offset == 0) + return 0; + + heap->heap_id = (gc_handle_t)heap; + heap->base_addr += offset; + adjust_ptr((uint8**)&heap->kfc_tree_root.left, offset); + adjust_ptr((uint8**)&heap->kfc_tree_root.right, offset); + adjust_ptr((uint8**)&heap->kfc_tree_root.parent, offset); + + cur = (hmu_t*)heap->base_addr; + end = (hmu_t*)((char*)heap->base_addr + heap->current_size); + + while (cur < end) { + size = hmu_get_size(cur); + bh_assert(size > 0); + + if (!HMU_IS_FC_NORMAL(size)) { + tree_node = (hmu_tree_node_t *)cur; + adjust_ptr((uint8**)&tree_node->left, offset); + adjust_ptr((uint8**)&tree_node->right, offset); + adjust_ptr((uint8**)&tree_node->parent, offset); + } + cur = (hmu_t*)((char *)cur + size); + } + + bh_assert(cur == end); + return 0; +} + +int +gc_reinit_lock(gc_handle_t handle) +{ + gc_heap_t *heap = (gc_heap_t *) handle; + return os_mutex_init(&heap->lock); +} + +void +gc_destroy_lock(gc_handle_t handle) +{ + gc_heap_t *heap = (gc_heap_t *) handle; + os_mutex_destroy(&heap->lock); +} + #if BH_ENABLE_GC_VERIFY != 0 void gci_verify_heap(gc_heap_t *heap) diff --git a/core/shared/mem-alloc/mem_alloc.c b/core/shared/mem-alloc/mem_alloc.c index 183b16f0..32d07513 100644 --- a/core/shared/mem-alloc/mem_alloc.c +++ b/core/shared/mem-alloc/mem_alloc.c @@ -37,6 +37,26 @@ void mem_allocator_free(mem_allocator_t allocator, void *ptr) gc_free_vo((gc_handle_t) allocator, ptr); } +int +mem_allocator_migrate(mem_allocator_t allocator, + mem_allocator_t allocator_old) +{ + return gc_migrate((gc_handle_t) allocator, + (gc_handle_t) allocator_old); +} + +int +mem_allocator_reinit_lock(mem_allocator_t allocator) +{ + return gc_reinit_lock((gc_handle_t) allocator); +} + +void +mem_allocator_destroy_lock(mem_allocator_t allocator) +{ + gc_destroy_lock((gc_handle_t) allocator); +} + #else /* else of DEFAULT_MEM_ALLOCATOR */ #include "tlsf/tlsf.h" @@ -141,5 +161,27 @@ mem_allocator_free(mem_allocator_t allocator, void *ptr) } } +int +mem_allocator_migrate(mem_allocator_t allocator, + mem_allocator_t allocator_old) +{ + return tlsf_migrate((mem_allocator_tlsf *) allocator, + (mem_allocator_tlsf *) allocator_old); +} + +int +mem_allocator_init_lock(mem_allocator_t allocator) +{ + mem_allocator_tlsf *allocator_tlsf = (mem_allocator_tlsf *)allocator; + return os_mutex_init(&allocator_tlsf->lock); +} + +void +mem_allocator_destroy_lock(mem_allocator_t allocator) +{ + mem_allocator_tlsf *allocator_tlsf = (mem_allocator_tlsf *)allocator; + os_mutex_destroy(&allocator_tlsf->lock); +} + #endif /* end of DEFAULT_MEM_ALLOCATOR */ diff --git a/core/shared/mem-alloc/mem_alloc.h b/core/shared/mem-alloc/mem_alloc.h index ed07325f..eb1032e5 100644 --- a/core/shared/mem-alloc/mem_alloc.h +++ b/core/shared/mem-alloc/mem_alloc.h @@ -29,6 +29,16 @@ mem_allocator_realloc(mem_allocator_t allocator, void *ptr, uint32_t size); void mem_allocator_free(mem_allocator_t allocator, void *ptr); +int +mem_allocator_migrate(mem_allocator_t allocator, + mem_allocator_t allocator_old); + +int +mem_allocator_reinit_lock(mem_allocator_t allocator); + +void +mem_allocator_destroy_lock(mem_allocator_t allocator); + #ifdef __cplusplus } #endif diff --git a/doc/build_wasm_app.md b/doc/build_wasm_app.md index 39b6ed97..8401da19 100644 --- a/doc/build_wasm_app.md +++ b/doc/build_wasm_app.md @@ -129,7 +129,7 @@ Run the test.wasm or test.aot with WAMR mini product build: You will get the following output: ``` Hello world! -buf ptr: 0x400002b0 +buf ptr: 0xffffc2c8 buf: 1234 ``` If you would like to run the test app on Zephyr, we have embedded a test sample into its OS image. You will need to execute: diff --git a/product-mini/platforms/zephyr/simple/build_and_run.sh b/product-mini/platforms/zephyr/simple/build_and_run.sh old mode 100644 new mode 100755 diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c index c229daec..9b5fa286 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c @@ -345,7 +345,7 @@ static host_interface interface = { .send = uart_send, .destroy = uart_destroy } #endif #ifdef __x86_64__ -static char global_heap_buf[420 * 1024] = { 0 }; +static char global_heap_buf[400 * 1024] = { 0 }; #else static char global_heap_buf[270 * 1024] = { 0 }; #endif