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
This commit is contained in:
wenyongh 2020-04-13 10:49:40 +08:00 committed by GitHub
parent ffd975d2d6
commit b40e79c160
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 983 additions and 755 deletions

View File

@ -61,6 +61,9 @@ enum {
#define WASM_ENABLE_AOT 0 #define WASM_ENABLE_AOT 0
#endif #endif
#define AOT_MAGIC_NUMBER 0x746f6100
#define AOT_CURRENT_VERSION 1
#ifndef WASM_ENABLE_JIT #ifndef WASM_ENABLE_JIT
#define WASM_ENABLE_JIT 0 #define WASM_ENABLE_JIT 0
#endif #endif
@ -147,9 +150,6 @@ enum {
/* Default watchdog interval in ms */ /* Default watchdog interval in ms */
#define DEFAULT_WATCHDOG_INTERVAL (3 * 60 * 1000) #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 */ /* The max percentage of global heap that app memory space can grow */
#define APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT 1 / 3 #define APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT 1 / 3
@ -183,5 +183,9 @@ enum {
#define BLOCK_ADDR_CACHE_SIZE 64 #define BLOCK_ADDR_CACHE_SIZE 64
#define BLOCK_ADDR_CONFLICT_SIZE 2 #define BLOCK_ADDR_CONFLICT_SIZE 2
#ifndef WASM_ENABLE_SPEC_TEST
#define WASM_ENABLE_SPEC_TEST 0
#endif
#endif /* end of _CONFIG_H_ */ #endif /* end of _CONFIG_H_ */

View File

@ -107,29 +107,64 @@ table_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
static bool static bool
memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module, 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; uint32 i, global_index, global_data_offset, base_offset, length;
AOTMemInitData *data_seg; 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 */ /* Allocate memory */
if (total_size >= UINT32_MAX 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, set_error_buf(error_buf, error_buf_size,
"AOT module instantiate failed: allocate memory failed."); "AOT module instantiate failed: allocate memory failed.");
return false; 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 */ /* Init memory info */
module_inst->memory_data_end.ptr = (uint8*)module_inst->memory_data.ptr module_inst->memory_data.ptr = p;
+ total_size; p += (uint32)memory_data_size;
module_inst->memory_data_size = (uint32)total_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_cur_page_count = module->mem_init_page_count;
module_inst->mem_max_page_count = module->mem_max_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) { if (module->mem_init_page_count > 0) {
for (i = 0; i < module->mem_init_data_count; i++) { for (i = 0; i < module->mem_init_data_count; i++) {
data_seg = module->mem_init_data_list[i]; data_seg = module->mem_init_data_list[i];
@ -165,11 +200,9 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
if (length > 0 if (length > 0
&& (base_offset >= module_inst->memory_data_size && (base_offset >= module_inst->memory_data_size
|| base_offset + length > 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, set_error_buf(error_buf, error_buf_size,
"AOT module instantiate failed: data segment out of range."); "AOT module instantiate failed: data segment out of range.");
return false; goto fail2;
} }
/* Copy memory data */ /* Copy memory data */
@ -179,6 +212,14 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
} }
return true; 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 static bool
@ -285,12 +326,11 @@ aot_instantiate(AOTModule *module,
{ {
AOTModuleInstance *module_inst; AOTModuleInstance *module_inst;
uint32 module_inst_struct_size = 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 table_data_size = (uint64)module->table_size * sizeof(uint32);
uint64 total_size = (uint64)module_inst_struct_size uint64 total_size = (uint64)module_inst_struct_size
+ module->global_data_size + module->global_data_size
+ table_data_size + heap_size; + table_data_size;
void *heap_handle;
uint8 *p; uint8 *p;
/* Check heap size */ /* Check heap size */
@ -330,27 +370,9 @@ aot_instantiate(AOTModule *module,
if (!table_instantiate(module_inst, module, error_buf, error_buf_size)) if (!table_instantiate(module_inst, module, error_buf, error_buf_size))
goto fail; 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 */ /* 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; goto fail;
/* Initialize function pointers */ /* Initialize function pointers */
@ -378,6 +400,10 @@ aot_instantiate(AOTModule *module,
/* Initialize the thread related data */ /* Initialize the thread related data */
if (stack_size == 0) if (stack_size == 0)
stack_size = DEFAULT_WASM_STACK_SIZE; 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; module_inst->default_wasm_stack_size = stack_size;
/* Execute __post_instantiate function and start function*/ /* Execute __post_instantiate function and start function*/
@ -406,12 +432,12 @@ aot_deinstantiate(AOTModuleInstance *module_inst)
wasm_runtime_destroy_wasi((WASMModuleInstanceCommon*)module_inst); wasm_runtime_destroy_wasi((WASMModuleInstanceCommon*)module_inst);
#endif #endif
if (module_inst->memory_data.ptr)
wasm_runtime_free(module_inst->memory_data.ptr);
if (module_inst->heap_handle.ptr) if (module_inst->heap_handle.ptr)
mem_allocator_destroy(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) if (module_inst->func_ptrs.ptr)
wasm_runtime_free(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, aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
void **p_native_addr) void **p_native_addr)
{ {
uint8 *addr = uint8 *addr = mem_allocator_malloc(module_inst->heap_handle.ptr, size);
mem_allocator_malloc(module_inst->heap_handle.ptr, size);
if (p_native_addr)
*p_native_addr = addr;
if (!addr) { if (!addr) {
aot_set_exception(module_inst, "out of memory"); aot_set_exception(module_inst, "out of memory");
return 0; return 0;
} }
return (int32)(module_inst->heap_base_offset if (p_native_addr)
+ (addr - (uint8*)module_inst->heap_data.ptr)); *p_native_addr = addr;
return (int32)(addr - (uint8*)module_inst->memory_data.ptr);
} }
void void
aot_module_free(AOTModuleInstance *module_inst, int32 ptr) aot_module_free(AOTModuleInstance *module_inst, int32 ptr)
{ {
if (ptr) { if (ptr) {
uint8 *addr = (uint8*)module_inst->heap_data.ptr uint8 *addr = (uint8*)module_inst->memory_data.ptr + ptr;
+ (ptr - module_inst->heap_base_offset);
if ((uint8*)module_inst->heap_data.ptr < addr 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); mem_allocator_free(module_inst->heap_handle.ptr, addr);
} }
} }
@ -598,34 +620,16 @@ bool
aot_validate_app_addr(AOTModuleInstance *module_inst, aot_validate_app_addr(AOTModuleInstance *module_inst,
int32 app_offset, uint32 size) int32 app_offset, uint32 size)
{ {
uint8 *addr;
/* integer overflow check */ /* integer overflow check */
if(app_offset + (int32)size < app_offset) { if(app_offset + (int32)size < app_offset) {
goto fail; goto fail;
} }
if (0 <= app_offset if (app_offset <= module_inst->heap_base_offset
&& app_offset < (int32)module_inst->memory_data_size) { || app_offset + (int32)size > (int32)module_inst->memory_data_size) {
addr = (uint8*)module_inst->memory_data.ptr + app_offset; goto fail;
if (!((uint8*)module_inst->memory_data.ptr <= addr
&& addr + size <= (uint8*)module_inst->memory_data_end.ptr))
goto fail;
return true;
} }
/* Currently heap_size is no more than 1G, and heap_base_offset is 1G, return true;
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;
}
fail: fail:
aot_set_exception(module_inst, "out of bounds memory access"); aot_set_exception(module_inst, "out of bounds memory access");
return false; return false;
@ -635,20 +639,20 @@ bool
aot_validate_native_addr(AOTModuleInstance *module_inst, aot_validate_native_addr(AOTModuleInstance *module_inst,
void *native_ptr, uint32 size) 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 */ /* integer overflow check */
if (addr + size < addr) { if (addr + size < addr) {
goto fail; goto fail;
} }
if (((uint8*)module_inst->memory_data.ptr <= addr if (addr <= (uint8*)module_inst->heap_data.ptr
&& addr + size <= (uint8*)module_inst->memory_data_end.ptr) || addr + size > (uint8*)module_inst->memory_data.ptr
|| ((uint8*)module_inst->heap_data.ptr <= addr + memory_data_size) {
&& addr + size <= (uint8*)module_inst->heap_data_end.ptr) goto fail;
) }
return true; return true;
fail: fail:
aot_set_exception(module_inst, "out of bounds memory access"); aot_set_exception(module_inst, "out of bounds memory access");
return false; return false;
@ -657,30 +661,24 @@ fail:
void * void *
aot_addr_app_to_native(AOTModuleInstance *module_inst, int32 app_offset) aot_addr_app_to_native(AOTModuleInstance *module_inst, int32 app_offset)
{ {
if (0 <= app_offset && app_offset < module_inst->heap_base_offset) int32 memory_data_size = (int32)module_inst->memory_data_size;
return (uint8*)module_inst->memory_data.ptr + app_offset;
if (module_inst->heap_base_offset < app_offset if (module_inst->heap_base_offset < app_offset
&& app_offset < module_inst->heap_base_offset && app_offset < memory_data_size)
+ (int32)module_inst->heap_data_size) return (uint8*)module_inst->memory_data.ptr + app_offset;
return (uint8*)module_inst->heap_data.ptr
+ (app_offset - module_inst->heap_base_offset);
return NULL; return NULL;
} }
int32 int32
aot_addr_native_to_app(AOTModuleInstance *module_inst, void *native_ptr) aot_addr_native_to_app(AOTModuleInstance *module_inst, void *native_ptr)
{ {
if ((uint8*)module_inst->memory_data.ptr <= (uint8*)native_ptr uint8 *addr = (uint8*)native_ptr;
&& (uint8*)native_ptr < (uint8*)module_inst->memory_data_end.ptr) int32 memory_data_size = (int32)module_inst->memory_data_size;
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));
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; return 0;
} }
@ -690,27 +688,17 @@ aot_get_app_addr_range(AOTModuleInstance *module_inst,
int32 *p_app_start_offset, int32 *p_app_start_offset,
int32 *p_app_end_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) { if (module_inst->heap_base_offset < app_offset
app_start_offset = 0; && app_offset < memory_data_size) {
app_end_offset = (int32)module_inst->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 return false;
&& 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;
} }
bool bool
@ -719,39 +707,37 @@ aot_get_native_addr_range(AOTModuleInstance *module_inst,
uint8 **p_native_start_addr, uint8 **p_native_start_addr,
uint8 **p_native_end_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 if ((uint8*)module_inst->heap_data.ptr < addr
&& (uint8*)native_ptr < (uint8*)module_inst->memory_data_end.ptr) { && addr < (uint8*)module_inst->memory_data.ptr
native_start_addr = (uint8*)module_inst->memory_data.ptr; + memory_data_size) {
native_end_addr = (uint8*)module_inst->memory_data_end.ptr; 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 return false;
&& (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;
} }
bool bool
aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count) 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 = uint32 num_bytes_per_page =
((AOTModule*)module_inst->aot_module.ptr)->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 cur_page_count = module_inst->mem_cur_page_count;
uint32 max_page_count = module_inst->mem_max_page_count; uint32 max_page_count = module_inst->mem_max_page_count;
uint32 total_page_count = cur_page_count + inc_page_count; uint32 total_page_count = cur_page_count + inc_page_count;
uint64 total_size = (uint64)num_bytes_per_page * total_page_count; uint64 memory_data_size = (uint64)num_bytes_per_page * total_page_count;
uint32 total_size_old = module_inst->memory_data_size; 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) if (inc_page_count <= 0)
/* No need to enlarge memory */ /* No need to enlarge memory */
@ -768,24 +754,50 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
return false; return false;
} }
if (!(mem_data_new = wasm_runtime_realloc(mem_data_old, (uint32)total_size))) { /* Destroy heap's lock firstly, if its memory is re-allocated,
if (!(mem_data_new = wasm_runtime_malloc((uint32)total_size))) { 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."); aot_set_exception(module_inst, "fail to enlarge memory.");
return false; return false;
} }
bh_memcpy_s(mem_data_new, (uint32)total_size, bh_memcpy_s(heap_data, (uint32)total_size,
mem_data_old, total_size_old); heap_data_old, total_size_old);
wasm_runtime_free(mem_data_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); 0, (uint32)total_size - total_size_old);
module_inst->mem_cur_page_count = total_page_count; module_inst->heap_data.ptr = heap_data;
module_inst->memory_data_size = (uint32)total_size; module_inst->heap_handle.ptr = (uint8*)heap_handle_old
module_inst->memory_data.ptr = mem_data_new; + (heap_data - heap_data_old);
module_inst->memory_data_end.ptr = mem_data_new + (uint32)total_size; 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; return true;
} }
@ -813,7 +825,7 @@ aot_is_wasm_type_equal(AOTModuleInstance *module_inst,
bool bool
aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, 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*) AOTModuleInstance *module_inst = (AOTModuleInstance*)
wasm_runtime_get_module_inst(exec_env); 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) { if (!import_func->call_conv_raw) {
return wasm_runtime_invoke_native(exec_env, func_ptr, return wasm_runtime_invoke_native(exec_env, func_ptr,
func_type, signature, attachment, func_type, signature, attachment,
frame_lp, argc, argv_ret); argv, argc, argv);
} }
else { else {
return wasm_runtime_invoke_native_raw(exec_env, func_ptr, return wasm_runtime_invoke_native_raw(exec_env, func_ptr,
func_type, signature, attachment, func_type, signature, attachment,
frame_lp, argc, argv_ret); argv, argc, argv);
} }
} }
@ -857,7 +869,7 @@ bool
aot_call_indirect(WASMExecEnv *exec_env, aot_call_indirect(WASMExecEnv *exec_env,
bool check_func_type, uint32 func_type_idx, bool check_func_type, uint32 func_type_idx,
uint32 table_elem_idx, uint32 table_elem_idx,
uint32 *frame_lp, uint32 argc, uint32 *argv_ret) uint32 argc, uint32 *argv)
{ {
AOTModuleInstance *module_inst = (AOTModuleInstance*) AOTModuleInstance *module_inst = (AOTModuleInstance*)
wasm_runtime_get_module_inst(exec_env); 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, return wasm_runtime_invoke_native_raw(exec_env, func_ptr,
func_type, signature, func_type, signature,
attachment, attachment,
frame_lp, argc, argv_ret); argv, argc, argv);
} }
} }
return wasm_runtime_invoke_native(exec_env, func_ptr, return wasm_runtime_invoke_native(exec_env, func_ptr,
func_type, signature, attachment, func_type, signature, attachment,
frame_lp, argc, argv_ret); argv, argc, argv);
} }

View File

@ -18,9 +18,6 @@
extern "C" { extern "C" {
#endif #endif
#define AOT_MAGIC_NUMBER 0x746f6100
#define AOT_CURRENT_VERSION 1
typedef enum AOTExceptionID { typedef enum AOTExceptionID {
EXCE_UNREACHABLE = 0, EXCE_UNREACHABLE = 0,
EXCE_OUT_OF_MEMORY, EXCE_OUT_OF_MEMORY,
@ -200,19 +197,27 @@ typedef struct AOTModuleInstance {
/* WASI context */ /* WASI context */
AOTPointer wasi_ctx; 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 */ /* others */
int32 temp_ret; int32 temp_ret;
uint32 llvm_stack; uint32 llvm_stack;
int32 DYNAMICTOP_PTR_offset;
uint32 default_wasm_stack_size; uint32 default_wasm_stack_size;
/* reserved */ /* reserved */
uint32 reserved[16]; uint32 reserved[12];
union { union {
uint64 _make_it_8_byte_aligned_; uint64 _make_it_8_byte_aligned_;
uint8 bytes[1]; uint8 bytes[1];
} global_table_heap_data; } global_table_data;
} AOTModuleInstance; } AOTModuleInstance;
typedef AOTExportFunc AOTFunctionInstance; typedef AOTExportFunc AOTFunctionInstance;
@ -441,13 +446,13 @@ aot_is_wasm_type_equal(AOTModuleInstance *module_inst,
*/ */
bool bool
aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
uint32 *frame_lp, uint32 argc, uint32 *argv_ret); uint32 argc, uint32 *argv);
bool bool
aot_call_indirect(WASMExecEnv *exec_env, aot_call_indirect(WASMExecEnv *exec_env,
bool check_func_type, uint32 func_type_idx, bool check_func_type, uint32 func_type_idx,
uint32 table_elem_idx, uint32 table_elem_idx,
uint32 *frame_lp, uint32 argc, uint32 *argv_ret); uint32 argc, uint32 *argv);
uint32 uint32
aot_get_plt_table_size(); aot_get_plt_table_size();

View File

@ -162,9 +162,11 @@ wasm_native_resolve_symbol(const char *module_name, const char *field_name,
if (signature && signature[0] != '\0') { if (signature && signature[0] != '\0') {
/* signature is not empty, check its format */ /* signature is not empty, check its format */
if (!check_symbol_signature(func_type, signature)) { 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 " LOG_WARNING("failed to check signature '%s' and resolve "
"pointer params for import function (%s %s)\n", "pointer params for import function (%s %s)\n",
signature, module_name, field_name); signature, module_name, field_name);
#endif
return NULL; return NULL;
} }
else else

View File

@ -810,9 +810,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
goto fail; goto fail;
} }
wasi_ctx->curfds = curfds; wasi_ctx->curfds_offset = offset_curfds;
wasi_ctx->prestats = prestats; wasi_ctx->prestats_offset = offset_prestats;
wasi_ctx->argv_environ = argv_environ; wasi_ctx->argv_environ_offset = offset_argv_environ;
fd_table_init(curfds); fd_table_init(curfds);
fd_prestats_init(prestats); fd_prestats_init(prestats);
@ -950,14 +950,32 @@ void
wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst) wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst)
{ {
WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(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) {
if (wasi_ctx->argv_environ) if (wasi_ctx->argv_environ_offset) {
argv_environ_destroy(wasi_ctx->argv_environ); argv_environ = (struct argv_environ_values *)
if (wasi_ctx->curfds) wasm_runtime_addr_app_to_native(module_inst,
fd_table_destroy(wasi_ctx->curfds); wasi_ctx->argv_environ_offset);
if (wasi_ctx->prestats) argv_environ_destroy(argv_environ);
fd_prestats_destroy(wasi_ctx->prestats); 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); wasm_runtime_free(wasi_ctx);
} }
} }
@ -2141,8 +2159,7 @@ wasm_runtime_call_indirect(WASMExecEnv *exec_env,
#if WASM_ENABLE_AOT != 0 #if WASM_ENABLE_AOT != 0
if (exec_env->module_inst->module_type == Wasm_Module_AoT) if (exec_env->module_inst->module_type == Wasm_Module_AoT)
return aot_call_indirect(exec_env, false, 0, return aot_call_indirect(exec_env, false, 0,
element_indices, element_indices, argc, argv);
argv, argc, argv);
#endif #endif
return false; return false;
} }

View File

@ -46,9 +46,13 @@ typedef struct WASMModuleInstanceCommon {
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
typedef struct WASIContext { typedef struct WASIContext {
struct fd_table *curfds; /* Use offset but not native address, since these fields are
struct fd_prestats *prestats; allocated from app's heap, and the heap space may be re-allocated
struct argv_environ_values *argv_environ; 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; } WASIContext;
#endif #endif

View File

@ -821,13 +821,14 @@ aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
AOTCompData *comp_data, AOTObjectData *obj_data) AOTCompData *comp_data, AOTObjectData *obj_data)
{ {
uint32 offset = *p_offset; uint32 offset = *p_offset;
uint32 aot_curr_version = AOT_CURRENT_VERSION;
EMIT_U8('\0'); EMIT_U8('\0');
EMIT_U8('a'); EMIT_U8('a');
EMIT_U8('o'); EMIT_U8('o');
EMIT_U8('t'); EMIT_U8('t');
EMIT_U32(1); EMIT_U32(aot_curr_version);
*p_offset = offset; *p_offset = offset;
return true; return true;

View File

@ -143,20 +143,19 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef ret_type, uint8 wasm_ret_type, LLVMTypeRef ret_type, uint8 wasm_ret_type,
LLVMValueRef *p_value_ret, LLVMValueRef *p_res) 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; LLVMTypeRef ret_ptr_type, elem_ptr_type;
LLVMValueRef func, elem_idx, elem_ptr; 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"; char buf[32], *func_name = "aot_invoke_native";
uint32 i, cell_num = 0; uint32 i, cell_num = 0;
/* prepare function type of aot_invoke_native */ /* prepare function type of aot_invoke_native */
func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */ func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */
func_param_types[1] = I32_TYPE; /* func_idx */ func_param_types[1] = I32_TYPE; /* func_idx */
func_param_types[2] = INT32_PTR_TYPE; /* frame_lp */ func_param_types[2] = I32_TYPE; /* argc */
func_param_types[3] = I32_TYPE; /* argc */ func_param_types[3] = INT32_PTR_TYPE; /* argv */
func_param_types[4] = INT32_PTR_TYPE; /* argv_ret */ if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 4, false))) {
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 5, false))) {
aot_set_last_error("llvm add function type failed."); aot_set_last_error("llvm add function type failed.");
return false; 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]); 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 (wasm_ret_type != VALUE_TYPE_VOID) {
if (!(ret_ptr_type = LLVMPointerType(ret_type, 0))) { if (!(ret_ptr_type = LLVMPointerType(ret_type, 0))) {
aot_set_last_error("llvm add pointer type failed."); 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."); aot_set_last_error("llvm build bit cast failed.");
return false; return false;
} }
if (!(*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret,
/* convert to int32 pointer */ "value_ret"))) {
if (!(value_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, value_ret, aot_set_last_error("llvm build load failed.");
INT32_PTR_TYPE, "argv_ret_ptr"))) {
aot_set_last_error("llvm build store failed.");
return false; 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; *p_res = res;
return true; return true;
@ -395,10 +385,10 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef ret_type, uint8 wasm_ret_type, LLVMTypeRef ret_type, uint8 wasm_ret_type,
LLVMValueRef *p_value_ret, LLVMValueRef *p_res) 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; LLVMTypeRef ret_ptr_type, elem_ptr_type;
LLVMValueRef func, elem_idx, elem_ptr; 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"; char buf[32], *func_name = "aot_call_indirect";
uint32 i, cell_num = 0; 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[1] = INT8_TYPE; /* check_func_type */
func_param_types[2] = I32_TYPE; /* func_type_idx */ func_param_types[2] = I32_TYPE; /* func_type_idx */
func_param_types[3] = I32_TYPE; /* table_elem_idx */ func_param_types[3] = I32_TYPE; /* table_elem_idx */
func_param_types[4] = INT32_PTR_TYPE; /* frame_lp */ func_param_types[4] = I32_TYPE; /* argc */
func_param_types[5] = I32_TYPE; /* argc */ func_param_types[5] = INT32_PTR_TYPE; /* argv */
func_param_types[6] = INT32_PTR_TYPE; /* argv_ret */ if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 6, false))) {
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 7, false))) {
aot_set_last_error("llvm add function type failed."); aot_set_last_error("llvm add function type failed.");
return false; 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]); 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 (wasm_ret_type != VALUE_TYPE_VOID) {
if (!(ret_ptr_type = LLVMPointerType(ret_type, 0))) { if (!(ret_ptr_type = LLVMPointerType(ret_type, 0))) {
aot_set_last_error("llvm add pointer type failed."); 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; return false;
} }
/* convert to int32 pointer */ if (!(*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret,
if (!(value_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, value_ret, "value_ret"))) {
INT32_PTR_TYPE, "argv_ret_ptr"))) { aot_set_last_error("llvm build load failed.");
aot_set_last_error("llvm build store failed.");
return false; 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; *p_res = res;
return true; return true;

View File

@ -23,14 +23,6 @@
} \ } \
} while (0) } 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 { \ #define ADD_BASIC_BLOCK(block, name) do { \
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \ if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
func_ctx->func, \ func_ctx->func, \
@ -43,53 +35,88 @@
#define SET_BUILD_POS(block) \ #define SET_BUILD_POS(block) \
LLVMPositionBuilderAtEnd(comp_ctx->builder, 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 static LLVMValueRef
check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 offset, uint32 bytes) uint32 offset, uint32 bytes)
{ {
LLVMValueRef offset_const = I32_CONST(offset); LLVMValueRef offset_const = I32_CONST(offset);
LLVMValueRef size_const = I32_CONST(bytes); LLVMValueRef bytes_const = I32_CONST(bytes);
LLVMValueRef addr, maddr, moffset; LLVMValueRef bytes64_const = I64_CONST(bytes);
LLVMValueRef cmp, phi; LLVMValueRef heap_base_offset = func_ctx->heap_base_offset;
LLVMValueRef mem_base_addr, mem_data_size; LLVMValueRef addr, maddr, offset1, offset2, cmp;
LLVMValueRef heap_base_addr, heap_base_offset; LLVMValueRef mem_base_addr, mem_check_bound, total_mem_size;
LLVMValueRef mem_offset_max = NULL, heap_offset_max = NULL;
LLVMBasicBlockRef check_mem_space, check_heap_space, check_succ;
LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder); LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
LLVMBasicBlockRef check_succ, check_mem_space;
CHECK_LLVM_CONST(offset_const); 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; /* Get memory base address and memory data size */
heap_base_offset = func_ctx->heap_base_offset; 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); 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 */ /* return addres directly if constant offset and inside memory space */
if (LLVMIsConstant(moffset)) { if (LLVMIsConstant(offset1)) {
uint32 memory_offset = (uint32)LLVMConstIntGetZExtValue(moffset); 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; uint32 init_page_count = comp_ctx->comp_data->mem_init_page_count;
if (init_page_count > 0 uint32 mem_data_size = num_bytes_per_page * init_page_count;
&& memory_offset <= comp_ctx->comp_data->num_bytes_per_page if (mem_data_size > 0
* init_page_count - bytes) { && mem_offset <= mem_data_size - bytes) {
/* inside memory space */ /* 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 */ /* maddr = mem_base_addr + moffset */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder,
mem_base_addr, mem_base_addr,
&moffset, 1, "maddr"))) { &offset1, 1, "maddr"))) {
aot_set_last_error("llvm build add failed."); aot_set_last_error("llvm build add failed.");
goto fail; 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) { 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"); ADD_BASIC_BLOCK(check_mem_space, "check_mem_space");
LLVMMoveBasicBlockAfter(check_mem_space, block_curr); LLVMMoveBasicBlockAfter(check_mem_space, block_curr);
/* if mem_data_size is zero, check heap space */ /* if total_mem_size is zero, boundary check fail */
BUILD_ICMP(LLVMIntEQ, mem_data_size, I32_ZERO, cmp, BUILD_ICMP(LLVMIntEQ, total_mem_size, I32_ZERO, cmp,
"cmp_mem_data_size"); "cmp_total_mem_size");
BUILD_COND_BR(cmp, check_heap_space, check_mem_space); 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); SET_BUILD_POS(check_mem_space);
} }
/* Get memory base address */ /* offset2 = offset1 - heap_base_offset; */
if (!func_ctx->mem_space_unchanged) { BUILD_OP(Sub, offset1, heap_base_offset, offset2, "offset2");
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 (!(mem_check_bound =
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr, get_memory_check_bound(comp_ctx, func_ctx, bytes))) {
&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.");
goto fail; goto fail;
} }
/* maddr = heap_base_addr + moffset */ /* Add basic blocks */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, heap_base_addr, ADD_BASIC_BLOCK(check_succ, "check_succ");
&moffset, 1, "maddr"))) { LLVMMoveBasicBlockAfter(check_succ, block_curr);
aot_set_last_error("llvm build add failed.");
goto fail;
}
block_curr = LLVMGetInsertBlock(comp_ctx->builder);
LLVMAddIncoming(phi, &maddr, &block_curr, 1);
/* heap space base addr and size is unchanged, /* offset2 > bound ? */
the heap boundary is unchanged also. */ BUILD_ICMP(LLVMIntUGT, offset2, mem_check_bound, cmp, "cmp");
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");
if (!aot_emit_exception(comp_ctx, func_ctx, if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
true, cmp, check_succ)) true, cmp, check_succ)) {
goto fail; goto fail;
}
SET_BUILD_POS(check_succ); 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: fail:
return NULL; return NULL;
} }

View File

@ -105,7 +105,7 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
AOTCompData *comp_data = comp_ctx->comp_data; AOTCompData *comp_data = comp_ctx->comp_data;
uint32 import_global_count = comp_data->import_global_count; uint32 import_global_count = comp_data->import_global_count;
uint32 global_base_offset = offsetof(AOTModuleInstance, uint32 global_base_offset = offsetof(AOTModuleInstance,
global_table_heap_data.bytes); global_table_data.bytes);
uint32 global_offset; uint32 global_offset;
uint8 global_type; uint8 global_type;
LLVMValueRef offset, global_ptr, global; LLVMValueRef offset, global_ptr, global;

View File

@ -181,68 +181,117 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
} }
/* Load memory data size */ /* Load total memory size */
offset = I32_CONST(offsetof(AOTModuleInstance, memory_data_size)); offset = I32_CONST(offsetof(AOTModuleInstance, total_mem_size));
if (!(func_ctx->mem_data_size = if (!(func_ctx->total_mem_size =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, 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"); aot_set_last_error("llvm build in bounds gep failed");
return false; return false;
} }
if (!(func_ctx->mem_data_size = if (!(func_ctx->total_mem_size =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_data_size, LLVMBuildBitCast(comp_ctx->builder, func_ctx->total_mem_size,
INT32_PTR_TYPE, "mem_data_size_ptr"))) { INT32_PTR_TYPE, "bound_check_1byte_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (mem_space_unchanged) { if (mem_space_unchanged) {
if (!(func_ctx->mem_data_size = if (!(func_ctx->total_mem_size =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_data_size, LLVMBuildLoad(comp_ctx->builder, func_ctx->total_mem_size,
"mem_data_size"))) { "bound_check_1byte"))) {
aot_set_last_error("llvm build load failed"); aot_set_last_error("llvm build load failed");
return false; 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 */ /* Load memory bound check constants */
offset = I32_CONST(offsetof(AOTModuleInstance, heap_data.ptr)); offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_1byte));
if (!(func_ctx->heap_base_addr = if (!(func_ctx->mem_bound_check_1byte =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, 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"); aot_set_last_error("llvm build in bounds gep failed");
return false; return false;
} }
if (!(func_ctx->heap_base_addr = if (!(func_ctx->mem_bound_check_1byte =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->heap_base_addr, LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_1byte,
int8_ptr_type, "heap_base_addr_tmp"))) { INT32_PTR_TYPE, "bound_check_1byte_ptr"))) {
aot_set_last_error("llvm build bit cast failed"); aot_set_last_error("llvm build bit cast failed");
return false; return false;
} }
if (!(func_ctx->heap_base_addr = if (mem_space_unchanged) {
LLVMBuildLoad(comp_ctx->builder, func_ctx->heap_base_addr, if (!(func_ctx->mem_bound_check_1byte =
"heap_base_addr"))) { LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_1byte,
aot_set_last_error("llvm build load failed"); "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; 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 */ /* Load heap base offset */
offset = I32_CONST(offsetof(AOTModuleInstance, 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; 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; return true;
} }
@ -313,7 +322,7 @@ create_table_base(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{ {
LLVMValueRef offset; 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); + comp_ctx->comp_data->global_data_size);
func_ctx->table_base = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->table_base = LLVMBuildInBoundsGEP(comp_ctx->builder,
func_ctx->aot_inst, func_ctx->aot_inst,
@ -918,6 +927,7 @@ aot_create_comp_context(AOTCompData *comp_data,
/* Create LLVM execution engine */ /* Create LLVM execution engine */
LLVMInitializeMCJITCompilerOptions(&jit_options, sizeof(jit_options)); LLVMInitializeMCJITCompilerOptions(&jit_options, sizeof(jit_options));
jit_options.OptLevel = LLVMCodeGenLevelAggressive; jit_options.OptLevel = LLVMCodeGenLevelAggressive;
jit_options.EnableFastISel = true;
/*jit_options.CodeModel = LLVMCodeModelSmall;*/ /*jit_options.CodeModel = LLVMCodeModelSmall;*/
if (LLVMCreateMCJITCompilerForModule if (LLVMCreateMCJITCompilerForModule
(&comp_ctx->exec_engine, comp_ctx->module, (&comp_ctx->exec_engine, comp_ctx->module,

View File

@ -94,20 +94,13 @@ typedef struct AOTFuncContext {
LLVMValueRef table_base; LLVMValueRef table_base;
LLVMValueRef argv_buf; 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_offset;
LLVMValueRef heap_base_addr; LLVMValueRef mem_base_addr;
LLVMValueRef heap_data_size; LLVMValueRef total_mem_size;
LLVMValueRef heap_bound_1_byte; LLVMValueRef mem_bound_check_1byte;
LLVMValueRef heap_bound_2_bytes; LLVMValueRef mem_bound_check_2bytes;
LLVMValueRef heap_bound_4_bytes; LLVMValueRef mem_bound_check_4bytes;
LLVMValueRef heap_bound_8_bytes; LLVMValueRef mem_bound_check_8bytes;
LLVMValueRef cur_exception; LLVMValueRef cur_exception;

View File

@ -223,28 +223,17 @@ LOAD_I16(void *addr)
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */ #endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
#define CHECK_MEMORY_OVERFLOW() do { \ #define CHECK_MEMORY_OVERFLOW(bytes) do { \
uint64 offset1 = offset + addr; \ int32 offset1 = (int32)(offset + addr); \
/* if (flags != 2) \ uint64 offset2 = (uint64)(uint32)(offset1 - heap_base_offset); \
LOG_VERBOSE("unaligned load/store in wasm interp, flag: %d.\n", flags); */\ /* if (flags != 2) \
/* The WASM spec doesn't require that the dynamic address operand must be \ LOG_VERBOSE("unaligned load/store, flag: %d.\n", flags); */ \
unsigned, so we don't check whether integer overflow or not here. */ \ if (offset2 + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] <= total_mem_size) \
/* if (offset1 < offset) \ /* If offset1 is in valid range, maddr must also be in valid range, \
goto out_of_bounds; */ \ no need to check it again. */ \
if (offset1 + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] <= memory_data_size) { \ maddr = memory->memory_data + offset1; \
/* If offset1 is in valid range, maddr must also be in valid range, \ else \
no need to check it again. */ \ goto out_of_bounds; \
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; \
} while (0) } while (0)
static inline uint32 static inline uint32
@ -798,9 +787,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMInterpFrame *prev_frame) WASMInterpFrame *prev_frame)
{ {
WASMMemoryInstance *memory = module->default_memory; 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 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 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count
uint32 heap_data_size = memory ? (uint32)(memory->heap_data_end - memory->heap_data) : 0; - heap_base_offset : 0;
uint8 *global_data = memory ? memory->global_data : NULL; uint8 *global_data = memory ? memory->global_data : NULL;
WASMTableInstance *table = module->default_table; WASMTableInstance *table = module->default_table;
WASMGlobalInstance *globals = module->globals; WASMGlobalInstance *globals = module->globals;
@ -1419,7 +1409,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
PUSH_I32(prev_page_count); PUSH_I32(prev_page_count);
/* update the memory instance ptr */ /* update the memory instance ptr */
memory = module->default_memory; 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; global_data = memory->global_data;
} }

View File

@ -225,28 +225,17 @@ LOAD_I16(void *addr)
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */ #endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
#define CHECK_MEMORY_OVERFLOW(bytes) do { \ #define CHECK_MEMORY_OVERFLOW(bytes) do { \
uint64 offset1 = offset + addr; \ int32 offset1 = (int32)(offset + addr); \
/* if (flags != 2) \ uint64 offset2 = (uint64)(uint32)(offset1 - heap_base_offset); \
LOG_VERBOSE("unaligned load/store in wasm interp, flag: %d.\n", flags); */\ /* if (flags != 2) \
/* The WASM spec doesn't require that the dynamic address operand must be \ LOG_VERBOSE("unaligned load/store, flag: %d.\n", flags); */ \
unsigned, so we don't check whether integer overflow or not here. */ \ if (offset2 + bytes <= total_mem_size) \
/* if (offset1 < offset) \ /* If offset1 is in valid range, maddr must also be in valid range,\
goto out_of_bounds; */ \ no need to check it again. */ \
if (offset1 + bytes <= memory_data_size) { \ maddr = memory->memory_data + offset1; \
/* If offset1 is in valid range, maddr must also be in valid range, \ else \
no need to check it again. */ \ goto out_of_bounds; \
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; \
} while (0) } while (0)
static inline uint32 static inline uint32
@ -501,10 +490,18 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
frame_ip += 6; \ frame_ip += 6; \
} while (0) } 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 { \ #define DEF_OP_REINTERPRET(src_type) do { \
SET_OPERAND(src_type, 2, GET_OPERAND(src_type, 0)); \ SET_OPERAND(src_type, 2, GET_OPERAND(src_type, 0)); \
frame_ip += 4; \ frame_ip += 4; \
} while (0) } while (0)
#endif
#if WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 #if WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0
#define DEF_OP_NUMERIC_64 DEF_OP_NUMERIC #define DEF_OP_NUMERIC_64 DEF_OP_NUMERIC
@ -779,9 +776,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMInterpFrame *prev_frame) WASMInterpFrame *prev_frame)
{ {
WASMMemoryInstance *memory = module->default_memory; 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 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 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count
uint32 heap_data_size = memory ? (uint32)(memory->heap_data_end - memory->heap_data) : 0; - heap_base_offset : 0;
uint8 *global_data = memory ? memory->global_data : NULL; uint8 *global_data = memory ? memory->global_data : NULL;
WASMTableInstance *table = module->default_table; WASMTableInstance *table = module->default_table;
WASMGlobalInstance *globals = module->globals; WASMGlobalInstance *globals = module->globals;
@ -929,10 +927,24 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
addr2 = GET_OFFSET(); addr2 = GET_OFFSET();
addr_ret = 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]; 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]; frame_lp[addr_ret] = frame_lp[addr2];
#endif
}
HANDLE_OP_END (); HANDLE_OP_END ();
} }
@ -943,10 +955,24 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
addr2 = GET_OFFSET(); addr2 = GET_OFFSET();
addr_ret = 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); *(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); *(int64*)(frame_lp + addr_ret) = *(int64*)(frame_lp + addr2);
#endif
}
HANDLE_OP_END (); HANDLE_OP_END ();
} }
@ -1288,7 +1314,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
frame_lp[addr_ret] = prev_page_count; frame_lp[addr_ret] = prev_page_count;
/* update the memory instance ptr */ /* update the memory instance ptr */
memory = module->default_memory; 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; global_data = memory->global_data;
} }
@ -2061,13 +2088,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (EXT_OP_COPY_STACK_TOP): HANDLE_OP (EXT_OP_COPY_STACK_TOP):
addr1 = GET_OFFSET(); addr1 = GET_OFFSET();
addr2 = 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]; frame_lp[addr2] = frame_lp[addr1];
#endif
HANDLE_OP_END (); HANDLE_OP_END ();
HANDLE_OP (EXT_OP_COPY_STACK_TOP_I64): HANDLE_OP (EXT_OP_COPY_STACK_TOP_I64):
addr1 = GET_OFFSET(); addr1 = GET_OFFSET();
addr2 = 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); *(float64*)(frame_lp + addr2) = *(float64*)(frame_lp + addr1);
#endif
HANDLE_OP_END (); HANDLE_OP_END ();
HANDLE_OP (WASM_OP_SET_LOCAL): HANDLE_OP (WASM_OP_SET_LOCAL):

View File

@ -2816,21 +2816,21 @@ wasm_loader_check_br(WASMLoaderContext *ctx, uint32 depth,
#define GET_CONST_OFFSET(type, val) do { \ #define GET_CONST_OFFSET(type, val) do { \
if (!(wasm_loader_get_const_offset(loader_ctx, type, \ if (!(wasm_loader_get_const_offset(loader_ctx, type, \
val, 0, 0, &operand_offset, \ &val, &operand_offset, \
error_buf, error_buf_size))) \ error_buf, error_buf_size))) \
goto fail; \ goto fail; \
} while (0) } while (0)
#define GET_CONST_F32_OFFSET(type, fval) do { \ #define GET_CONST_F32_OFFSET(type, fval) do { \
if (!(wasm_loader_get_const_offset(loader_ctx, type, \ if (!(wasm_loader_get_const_offset(loader_ctx, type, \
0, fval, 0, &operand_offset, \ &fval, &operand_offset, \
error_buf, error_buf_size))) \ error_buf, error_buf_size))) \
goto fail; \ goto fail; \
} while (0) } while (0)
#define GET_CONST_F64_OFFSET(type, fval) do { \ #define GET_CONST_F64_OFFSET(type, fval) do { \
if (!(wasm_loader_get_const_offset(loader_ctx, type, \ if (!(wasm_loader_get_const_offset(loader_ctx, type, \
0, 0, fval, &operand_offset, \ &fval, &operand_offset, \
error_buf, error_buf_size))) \ error_buf, error_buf_size))) \
goto fail; \ goto fail; \
} while (0) } while (0)
@ -3110,9 +3110,11 @@ wasm_loader_push_frame_offset(WASMLoaderContext *ctx, uint8 type,
} }
ctx->frame_offset++; ctx->frame_offset++;
ctx->dynamic_offset++; if (!disable_emit) {
if (ctx->dynamic_offset > ctx->max_dynamic_offset) ctx->dynamic_offset++;
ctx->max_dynamic_offset = ctx->dynamic_offset; if (ctx->dynamic_offset > ctx->max_dynamic_offset)
ctx->max_dynamic_offset = ctx->dynamic_offset;
}
return true; return true;
} }
@ -3170,8 +3172,7 @@ wasm_loader_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 type,
static bool static bool
wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type, wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type,
int64 val_int, float32 val_f32, void *value, int16 *offset,
float64 val_f64, int16 *offset,
char *error_buf, uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
int16 operand_offset = 0; int16 operand_offset = 0;
@ -3179,10 +3180,12 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type,
for (c = (Const *)ctx->const_buf; for (c = (Const *)ctx->const_buf;
(uint8*)c < ctx->const_buf + ctx->num_const * sizeof(Const); c ++) { (uint8*)c < ctx->const_buf + ctx->num_const * sizeof(Const); c ++) {
if ((type == c->value_type) if ((type == c->value_type)
&& ((type == VALUE_TYPE_I64 && (int64)val_int == c->value.i64) && ((type == VALUE_TYPE_I64 && *(int64*)value == c->value.i64)
|| (type == VALUE_TYPE_I32 && (int32)val_int == c->value.i32) || (type == VALUE_TYPE_I32 && *(int32*)value == c->value.i32)
|| (type == VALUE_TYPE_F64 && (float64)val_f64 == c->value.f64) || (type == VALUE_TYPE_F64
|| (type == VALUE_TYPE_F32 && (float32)val_f32 == c->value.f32))) { && (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; operand_offset = c->slot_index;
break; break;
} }
@ -3203,23 +3206,23 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type,
c->value_type = type; c->value_type = type;
switch (type) { switch (type) {
case VALUE_TYPE_F64: 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; ctx->const_cell_num += 2;
/* The const buf will be reversed, we use the second cell */ /* The const buf will be reversed, we use the second cell */
/* of the i64/f64 const so the finnal offset is corrent */ /* of the i64/f64 const so the finnal offset is corrent */
operand_offset ++; operand_offset ++;
break; break;
case VALUE_TYPE_I64: case VALUE_TYPE_I64:
c->value.i64 = (int64)val_int; c->value.i64 = *(int64*)value;
ctx->const_cell_num += 2; ctx->const_cell_num += 2;
operand_offset ++; operand_offset ++;
break; break;
case VALUE_TYPE_F32: 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 ++; ctx->const_cell_num ++;
break; break;
case VALUE_TYPE_I32: case VALUE_TYPE_I32:
c->value.i32 = (int32)val_int; c->value.i32 = *(int32*)value;
ctx->const_cell_num ++; ctx->const_cell_num ++;
break; break;
default: default:
@ -3495,8 +3498,8 @@ re_scan:
if (loader_ctx->code_compiled_size > 0) { if (loader_ctx->code_compiled_size > 0) {
if (!wasm_loader_ctx_reinit(loader_ctx)) { if (!wasm_loader_ctx_reinit(loader_ctx)) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"WASM loader prepare bytecode failed: " "WASM loader prepare bytecode failed: "
"allocate memory failed"); "allocate memory failed");
goto fail; goto fail;
} }
p = func->code; p = func->code;
@ -4005,7 +4008,7 @@ handle_next_reachable_block:
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
if (loader_ctx->p_code_compiled) { if (loader_ctx->p_code_compiled) {
#if WASM_ENABLE_ABS_LABEL_ADDR != 0 #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]; handle_table[WASM_OP_SELECT_64];
#else #else
*((int16*)loader_ctx->p_code_compiled - 2) = (int16) *((int16*)loader_ctx->p_code_compiled - 2) = (int16)
@ -4373,7 +4376,7 @@ handle_next_reachable_block:
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
skip_label(); skip_label();
disable_emit = true; 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); GET_CONST_F32_OFFSET(VALUE_TYPE_F32, f32);
#endif #endif
PUSH_F32(); PUSH_F32();
@ -4385,7 +4388,7 @@ handle_next_reachable_block:
skip_label(); skip_label();
disable_emit = true; disable_emit = true;
/* Some MCU may require 8-byte align */ /* 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); GET_CONST_F64_OFFSET(VALUE_TYPE_F64, f64);
#endif #endif
PUSH_F64(); PUSH_F64();
@ -4687,10 +4690,11 @@ handle_next_reachable_block:
if (c->value_type == VALUE_TYPE_F64 if (c->value_type == VALUE_TYPE_F64
|| c->value_type == VALUE_TYPE_I64) { || c->value_type == VALUE_TYPE_I64) {
bh_memcpy_s(func_const, func_const_end - func_const, bh_memcpy_s(func_const, func_const_end - func_const,
&c->value.f64, sizeof(int64)); &(c->value.f64), sizeof(int64));
func_const += sizeof(int64); func_const += sizeof(int64);
} else { } 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); func_const += sizeof(int32);
} }
} }

View File

@ -51,7 +51,6 @@ memories_deinstantiate(WASMMemoryInstance **memories, uint32 count)
if (memories[i]) { if (memories[i]) {
if (memories[i]->heap_handle) if (memories[i]->heap_handle)
mem_allocator_destroy(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[i]);
} }
wasm_runtime_free(memories); wasm_runtime_free(memories);
@ -67,6 +66,7 @@ memory_instantiate(uint32 num_bytes_per_page,
{ {
WASMMemoryInstance *memory; WASMMemoryInstance *memory;
uint64 total_size = offsetof(WASMMemoryInstance, base_addr) + uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
(uint64)heap_size +
num_bytes_per_page * (uint64)init_page_count + num_bytes_per_page * (uint64)init_page_count +
global_data_size; global_data_size;
@ -83,42 +83,28 @@ memory_instantiate(uint32 num_bytes_per_page,
memory->cur_page_count = init_page_count; memory->cur_page_count = init_page_count;
memory->max_page_count = max_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 + memory->global_data = memory->memory_data +
num_bytes_per_page * memory->cur_page_count; num_bytes_per_page * memory->cur_page_count;
memory->global_data_size = global_data_size; memory->global_data_size = global_data_size;
memory->end_addr = memory->global_data + global_data_size; memory->end_addr = memory->global_data + global_data_size;
/* Allocate heap space */ bh_assert(memory->end_addr - (uint8*)memory == (uint32)total_size);
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;
/* Initialize heap */ /* Initialize heap */
if (!(memory->heap_handle = mem_allocator_create if (!(memory->heap_handle = mem_allocator_create
(memory->heap_data, heap_size))) { (memory->heap_data, heap_size))) {
goto fail2; wasm_runtime_free(memory);
return NULL;
} }
#if WASM_ENABLE_MEMORY_GROW != 0 #if WASM_ENABLE_SPEC_TEST == 0
memory->heap_base_offset = DEFAULT_APP_HEAP_BASE_OFFSET; memory->heap_base_offset = -(int32)heap_size;
#else #else
memory->heap_base_offset = memory->end_addr - memory->memory_data; memory->heap_base_offset = 0;
#endif #endif
return memory; 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 */ /* Initialize the thread related data */
if (stack_size == 0) if (stack_size == 0)
stack_size = DEFAULT_WASM_STACK_SIZE; 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; module_inst->default_wasm_stack_size = stack_size;
/* Execute __post_instantiate function */ /* Execute __post_instantiate function */
@ -923,13 +913,13 @@ wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
{ {
WASMMemoryInstance *memory = module_inst->default_memory; WASMMemoryInstance *memory = module_inst->default_memory;
uint8 *addr = mem_allocator_malloc(memory->heap_handle, size); uint8 *addr = mem_allocator_malloc(memory->heap_handle, size);
if (p_native_addr)
*p_native_addr = addr;
if (!addr) { if (!addr) {
wasm_set_exception(module_inst, "out of memory"); wasm_set_exception(module_inst, "out of memory");
return 0; 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 void
@ -937,8 +927,8 @@ wasm_module_free(WASMModuleInstance *module_inst, int32 ptr)
{ {
if (ptr) { if (ptr) {
WASMMemoryInstance *memory = module_inst->default_memory; WASMMemoryInstance *memory = module_inst->default_memory;
uint8 *addr = memory->heap_data + (ptr - memory->heap_base_offset); uint8 *addr = memory->memory_data + ptr;
if (memory->heap_data < addr && addr < memory->heap_data_end) if (memory->heap_data < addr && addr < memory->memory_data)
mem_allocator_free(memory->heap_handle, addr); mem_allocator_free(memory->heap_handle, addr);
} }
} }
@ -961,31 +951,20 @@ bool
wasm_validate_app_addr(WASMModuleInstance *module_inst, wasm_validate_app_addr(WASMModuleInstance *module_inst,
int32 app_offset, uint32 size) int32 app_offset, uint32 size)
{ {
WASMMemoryInstance *memory; WASMMemoryInstance *memory = module_inst->default_memory;
uint8 *addr; int32 memory_data_size =
(int32)(memory->num_bytes_per_page * memory->cur_page_count);
/* integer overflow check */ /* integer overflow check */
if(app_offset + (int32)size < app_offset) { if (app_offset + (int32)size < app_offset) {
goto fail; goto fail;
} }
memory = module_inst->default_memory; if (app_offset <= memory->heap_base_offset
if (0 <= app_offset || app_offset + (int32)size > memory_data_size) {
&& app_offset < memory->heap_base_offset) { goto fail;
addr = memory->memory_data + app_offset;
if (!(memory->base_addr <= addr && addr + size <= memory->end_addr))
goto fail;
return true;
} }
else if (memory->heap_base_offset < app_offset return true;
&& 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;
}
fail: fail:
wasm_set_exception(module_inst, "out of bounds memory access"); wasm_set_exception(module_inst, "out of bounds memory access");
return false; return false;
@ -995,18 +974,20 @@ bool
wasm_validate_native_addr(WASMModuleInstance *module_inst, wasm_validate_native_addr(WASMModuleInstance *module_inst,
void *native_ptr, uint32 size) void *native_ptr, uint32 size)
{ {
uint8 *addr = native_ptr; uint8 *addr = (uint8*)native_ptr;
WASMMemoryInstance *memory = module_inst->default_memory; WASMMemoryInstance *memory = module_inst->default_memory;
int32 memory_data_size =
(int32)(memory->num_bytes_per_page * memory->cur_page_count);
if (addr + size < addr) { if (addr + size < addr) {
goto fail; goto fail;
} }
if ((memory->base_addr <= addr && addr + size <= memory->end_addr) if (addr <= memory->heap_data
|| (memory->heap_data <= addr && addr + size <= memory->heap_data_end) || addr + size > memory->memory_data + memory_data_size) {
) goto fail;
return true; }
return true;
fail: fail:
wasm_set_exception(module_inst, "out of bounds memory access"); wasm_set_exception(module_inst, "out of bounds memory access");
return false; return false;
@ -1017,14 +998,13 @@ wasm_addr_app_to_native(WASMModuleInstance *module_inst,
int32 app_offset) int32 app_offset)
{ {
WASMMemoryInstance *memory = module_inst->default_memory; 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; return memory->memory_data + app_offset;
else if (memory->heap_base_offset < app_offset return NULL;
&& 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;
} }
int32 int32
@ -1032,15 +1012,14 @@ wasm_addr_native_to_app(WASMModuleInstance *module_inst,
void *native_ptr) void *native_ptr)
{ {
WASMMemoryInstance *memory = module_inst->default_memory; WASMMemoryInstance *memory = module_inst->default_memory;
if (memory->base_addr <= (uint8*)native_ptr uint8 *addr = (uint8*)native_ptr;
&& (uint8*)native_ptr < memory->end_addr) int32 memory_data_size =
return (int32)((uint8*)native_ptr - memory->memory_data); (int32)(memory->num_bytes_per_page * memory->cur_page_count);
else if (memory->heap_data <= (uint8*)native_ptr
&& (uint8*)native_ptr < memory->heap_data_end) if (memory->heap_data < addr
return memory->heap_base_offset && addr < memory->memory_data + memory_data_size)
+ (int32)((uint8*)native_ptr - memory->heap_data); return (int32)(addr - memory->memory_data);
else return 0;
return 0;
} }
bool bool
@ -1049,28 +1028,19 @@ wasm_get_app_addr_range(WASMModuleInstance *module_inst,
int32 *p_app_start_offset, int32 *p_app_start_offset,
int32 *p_app_end_offset) int32 *p_app_end_offset)
{ {
int32 app_start_offset, app_end_offset;
WASMMemoryInstance *memory = module_inst->default_memory; 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) { if (memory->heap_base_offset < app_offset
app_start_offset = 0; && app_offset < memory_data_size) {
app_end_offset = (int32)(memory->num_bytes_per_page * memory->cur_page_count); 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 return false;
&& 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;
} }
bool bool
@ -1079,42 +1049,36 @@ wasm_get_native_addr_range(WASMModuleInstance *module_inst,
uint8 **p_native_start_addr, uint8 **p_native_start_addr,
uint8 **p_native_end_addr) uint8 **p_native_end_addr)
{ {
uint8 *native_start_addr, *native_end_addr;
WASMMemoryInstance *memory = module_inst->default_memory; 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 if (memory->heap_data < addr
&& (uint8*)native_ptr < memory->end_addr) { && addr < memory->memory_data + memory_data_size) {
native_start_addr = memory->memory_data; if (p_native_start_addr)
native_end_addr = memory->memory_data *p_native_start_addr = memory->heap_data;
+ memory->num_bytes_per_page * memory->cur_page_count; 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 return false;
&& (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;
} }
bool bool
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
{ {
#if WASM_ENABLE_MEMORY_GROW != 0
WASMMemoryInstance *memory = module->default_memory, *new_memory; 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 old_page_count = memory->cur_page_count;
uint32 total_size_old = memory->end_addr - (uint8*)memory; uint32 total_size_old = memory->end_addr - (uint8*)memory;
uint32 total_page_count = inc_page_count + memory->cur_page_count; uint32 total_page_count = inc_page_count + memory->cur_page_count;
uint64 total_size = offsetof(WASMMemoryInstance, base_addr) + uint64 total_size = offsetof(WASMMemoryInstance, base_addr)
memory->num_bytes_per_page * (uint64)total_page_count + + (uint64)heap_size
memory->global_data_size; + memory->num_bytes_per_page * (uint64)total_page_count
+ memory->global_data_size;
uint8 *global_data_old; uint8 *global_data_old;
void *heap_handle_old = memory->heap_handle;
if (inc_page_count <= 0) if (inc_page_count <= 0)
/* No need to enlarge memory */ /* No need to enlarge memory */
@ -1131,8 +1095,13 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
return false; 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_realloc(memory, (uint32)total_size))) {
if (!(new_memory = wasm_runtime_malloc((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."); wasm_set_exception(module, "fail to enlarge memory.");
return false; return false;
} }
@ -1144,8 +1113,17 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
memset((uint8*)new_memory + total_size_old, memset((uint8*)new_memory + total_size_old,
0, (uint32)total_size - 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->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->global_data = new_memory->memory_data +
new_memory->num_bytes_per_page * total_page_count; new_memory->num_bytes_per_page * total_page_count;
new_memory->end_addr = new_memory->global_data + new_memory->global_data_size; 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; module->memories[0] = module->default_memory = new_memory;
return true; 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 */
} }

View File

@ -23,17 +23,16 @@ typedef struct WASMMemoryInstance {
/* Maximum page count */ /* Maximum page count */
uint32 max_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 */ /* Heap base offset of wasm app */
int32 heap_base_offset; int32 heap_base_offset;
/* Heap data base address */
uint8 *heap_data;
/* The heap created */
void *heap_handle;
/* Memory data */ /* Memory data */
uint8 *memory_data; uint8 *memory_data;
/* Global data of global instances */ /* Global data of global instances */
uint8 *global_data; uint8 *global_data;
uint32 global_data_size; uint32 global_data_size;
@ -42,12 +41,11 @@ typedef struct WASMMemoryInstance {
uint8 *end_addr; uint8 *end_addr;
/* Base address, the layout is: /* Base address, the layout is:
thunk_argv data + thunk arg offsets + heap_data + memory data + global data
memory data + global data
memory data init size is: num_bytes_per_page * cur_page_count memory data init size is: num_bytes_per_page * cur_page_count
global data size is calculated in module instantiating global data size is calculated in module instantiating
Note: when memory is re-allocated, the thunk argv data, thunk Note: when memory is re-allocated, the heap data and memory data
argv offsets and memory data must be copied to new memory also. must be copied to new memory also.
*/ */
uint8 base_addr[1]; uint8 base_addr[1];
} WASMMemoryInstance; } WASMMemoryInstance;

View File

@ -46,26 +46,54 @@ typedef struct iovec_app {
} iovec_app_t; } iovec_app_t;
typedef struct WASIContext { typedef struct WASIContext {
void *curfds; int32 curfds_offset;
void *prestats; int32 prestats_offset;
void *argv_environ; int32 argv_environ_offset;
} *wasi_ctx_t; } *wasi_ctx_t;
wasi_ctx_t wasi_ctx_t
wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst); 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 static wasi_errno_t
wasi_args_get(wasm_exec_env_t exec_env, int32 *argv_offsets, char *argv_buf) 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; size_t argc, argv_buf_size, i;
char **argv; char **argv;
uint64 total_size; uint64 total_size;
wasi_errno_t err; wasi_errno_t err;
err = wasmtime_ssp_args_sizes_get(wasi_ctx->argv_environ, err = wasmtime_ssp_args_sizes_get(argv_environ, &argc, &argv_buf_size);
&argc, &argv_buf_size);
if (err) if (err)
return 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))) || !(argv = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1; 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) { if (err) {
wasm_runtime_free(argv); wasm_runtime_free(argv);
return err; 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct argv_environ_values *argv_environ;
size_t argc, argv_buf_size; size_t argc, argv_buf_size;
wasi_errno_t err; 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))) || !validate_native_addr(argv_buf_size_app, sizeof(uint32)))
return (wasi_errno_t)-1; 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); &argc, &argv_buf_size);
if (err) if (err)
return 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; size_t environ_count, environ_buf_size, i;
uint64 total_size; uint64 total_size;
char **environs; char **environs;
wasi_errno_t err; 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); &environ_count, &environ_buf_size);
if (err) if (err)
return err; return err;
@ -174,7 +209,7 @@ wasi_environ_get(wasm_exec_env_t exec_env,
|| !(environs = wasm_runtime_malloc((uint32)total_size))) || !(environs = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1; 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) { if (err) {
wasm_runtime_free(environs); wasm_runtime_free(environs);
return err; 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; size_t environ_count, environ_buf_size;
wasi_errno_t err; 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))) || !validate_native_addr(environ_buf_size_app, sizeof(uint32)))
return (wasi_errno_t)-1; 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); &environ_count, &environ_buf_size);
if (err) if (err)
return 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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_prestat_t prestat;
wasi_errno_t err; wasi_errno_t err;
if (!validate_native_addr(prestat_app, sizeof(wasi_prestat_app_t))) if (!validate_native_addr(prestat_app, sizeof(wasi_prestat_app_t)))
return (wasi_errno_t)-1; 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) if (err)
return 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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); 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; wasi_iovec_t *iovec, *iovec_begin;
uint64 total_size; uint64 total_size;
size_t nread; size_t nread;
@ -298,7 +341,7 @@ wasi_fd_pread(wasm_exec_env_t exec_env,
iovec->buf_len = iovec_app->buf_len; 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); iovs_len, offset, &nread);
if (err) if (err)
goto fail; 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; wasi_ciovec_t *ciovec, *ciovec_begin;
uint64 total_size; uint64 total_size;
size_t nwritten; size_t nwritten;
@ -349,7 +393,7 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env,
ciovec->buf_len = iovec_app->buf_len; 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); iovs_len, offset, &nwritten);
if (err) if (err)
goto fail; 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; wasi_iovec_t *iovec, *iovec_begin;
uint64 total_size; uint64 total_size;
size_t nread; size_t nread;
@ -400,7 +445,7 @@ wasi_fd_read(wasm_exec_env_t exec_env,
iovec->buf_len = iovec_app->buf_len; 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); iovec_begin, iovs_len, &nread);
if (err) if (err)
goto fail; 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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, return wasmtime_ssp_fd_renumber(curfds, prestats, from, to);
wasi_ctx->prestats, from, to);
} }
static wasi_errno_t 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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))) if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
return wasmtime_ssp_fd_seek(wasi_ctx->curfds, fd, return wasmtime_ssp_fd_seek(curfds, fd, offset, whence, newoffset);
offset, whence, newoffset);
} }
static wasi_errno_t 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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))) if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
return (wasi_errno_t)-1; 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 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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_fdstat_t fdstat;
wasi_errno_t err; wasi_errno_t err;
if (!validate_native_addr(fdstat_app, sizeof(wasi_fdstat_t))) if (!validate_native_addr(fdstat_app, sizeof(wasi_fdstat_t)))
return (wasi_errno_t)-1; 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) if (err)
return 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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); 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; wasi_ciovec_t *ciovec, *ciovec_begin;
uint64 total_size; uint64 total_size;
size_t nwritten; 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; 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); ciovec_begin, iovs_len, &nwritten);
if (err) if (err)
goto fail; 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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); 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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, old_fd, old_flags, old_path, old_path_len,
new_fd, new_path, new_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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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_fd_t fd = -1; /* set fd_app -1 if path open failed */
wasi_errno_t err; wasi_errno_t err;
if (!validate_native_addr(fd_app, sizeof(wasi_fd_t))) if (!validate_native_addr(fd_app, sizeof(wasi_fd_t)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_path_open(wasi_ctx->curfds, err = wasmtime_ssp_path_open(curfds,
dirfd, dirflags, dirfd, dirflags,
path, path_len, path, path_len,
oflags, oflags,
fs_rights_base, fs_rights_base,
fs_rights_inheriting, fs_rights_inheriting,
fs_flags, fs_flags,
&fd); &fd);
*fd_app = fd; *fd_app = fd;
return err; 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; size_t bufused;
wasi_errno_t err; wasi_errno_t err;
if (!validate_native_addr(bufused_app, sizeof(uint32))) if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1; 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); buf, buf_len, cookie, &bufused);
if (err) if (err)
return 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; size_t bufused;
wasi_errno_t err; wasi_errno_t err;
if (!validate_native_addr(bufused_app, sizeof(uint32))) if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1; return (wasi_errno_t)-1;
err = wasmtime_ssp_path_readlink(wasi_ctx->curfds, fd, err = wasmtime_ssp_path_readlink(curfds, fd,
path, path_len, path, path_len,
buf, buf_len, &bufused); buf, buf_len, &bufused);
if (err) 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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, old_fd, old_path, old_path_len,
new_fd, new_path, new_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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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))) if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1; 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 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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); 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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))) if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1; 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); 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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, flags, path, path_len,
st_atim, st_mtim, fstflags); 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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, old_path, old_path_len, fd,
new_path, new_path_len); 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; size_t nevents;
wasi_errno_t err; wasi_errno_t err;
@ -822,7 +893,7 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env,
|| !validate_native_addr(nevents_app, sizeof(uint32))) || !validate_native_addr(nevents_app, sizeof(uint32)))
return (wasi_errno_t)-1; 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); nsubscriptions, &nevents);
if (err) if (err)
return 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; wasi_iovec_t *iovec, *iovec_begin;
uint64 total_size; uint64 total_size;
size_t ro_datalen; size_t ro_datalen;
@ -894,7 +966,7 @@ wasi_sock_recv(wasm_exec_env_t exec_env,
iovec->buf_len = ri_data->buf_len; 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, iovec_begin, ri_data_len,
ri_flags, &ro_datalen, ri_flags, &ro_datalen,
ro_flags); 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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; wasi_ciovec_t *ciovec, *ciovec_begin;
uint64 total_size; uint64 total_size;
size_t so_datalen; size_t so_datalen;
@ -949,7 +1022,7 @@ wasi_sock_send(wasm_exec_env_t exec_env,
ciovec->buf_len = si_data->buf_len; 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, ciovec_begin, si_data_len,
si_flags, &so_datalen); si_flags, &so_datalen);
if (err) 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); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); 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 static wasi_errno_t

View File

@ -404,10 +404,11 @@ gc_realloc_vo_internal(void *vheap, void *ptr, gc_size_t size,
#endif #endif
{ {
gc_heap_t* heap = (gc_heap_t*) vheap; 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_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; gc_size_t obj_size, obj_size_old;
hmu_type_t ut;
/* hmu header + prefix + obj + suffix */ /* hmu header + prefix + obj + suffix */
tot_size_unaligned = HMU_SIZE + OBJ_PREFIX_SIZE + size + OBJ_SUFFIX_SIZE; 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); 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); hmu = alloc_hmu_ex(heap, tot_size);
if (!hmu) if (!hmu)
goto finish; goto finish;

View File

@ -72,6 +72,35 @@ gc_init_with_pool(char *buf, gc_size_t buf_size);
int int
gc_destroy_with_pool(gc_handle_t handle); 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 * Get Heap Stats
* *

View File

@ -192,7 +192,6 @@ typedef struct gc_heap_struct {
gc_uint8 *base_addr; gc_uint8 *base_addr;
gc_size_t current_size; gc_size_t current_size;
gc_size_t max_size;
korp_mutex lock; korp_mutex lock;

View File

@ -35,7 +35,6 @@ gc_init_with_pool(char *buf, gc_size_t buf_size)
} }
/* init all data structures*/ /* init all data structures*/
heap->max_size = heap_max_size;
heap->current_size = heap_max_size; heap->current_size = heap_max_size;
heap->base_addr = (gc_uint8*)base_addr; heap->base_addr = (gc_uint8*)base_addr;
heap->heap_id = (gc_handle_t)heap; 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; gc_heap_t *heap = (gc_heap_t *) handle;
os_mutex_destroy(&heap->lock); 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)); memset(heap, 0, sizeof(gc_heap_t));
return GC_SUCCESS; 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 #if BH_ENABLE_GC_VERIFY != 0
void void
gci_verify_heap(gc_heap_t *heap) gci_verify_heap(gc_heap_t *heap)

View File

@ -37,6 +37,26 @@ void mem_allocator_free(mem_allocator_t allocator, void *ptr)
gc_free_vo((gc_handle_t) allocator, 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 */ #else /* else of DEFAULT_MEM_ALLOCATOR */
#include "tlsf/tlsf.h" #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 */ #endif /* end of DEFAULT_MEM_ALLOCATOR */

View File

@ -29,6 +29,16 @@ mem_allocator_realloc(mem_allocator_t allocator, void *ptr, uint32_t size);
void void
mem_allocator_free(mem_allocator_t allocator, void *ptr); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -129,7 +129,7 @@ Run the test.wasm or test.aot with WAMR mini product build:
You will get the following output: You will get the following output:
``` ```
Hello world! Hello world!
buf ptr: 0x400002b0 buf ptr: 0xffffc2c8
buf: 1234 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: 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:

0
product-mini/platforms/zephyr/simple/build_and_run.sh Normal file → Executable file
View File

View File

@ -345,7 +345,7 @@ static host_interface interface = { .send = uart_send, .destroy = uart_destroy }
#endif #endif
#ifdef __x86_64__ #ifdef __x86_64__
static char global_heap_buf[420 * 1024] = { 0 }; static char global_heap_buf[400 * 1024] = { 0 };
#else #else
static char global_heap_buf[270 * 1024] = { 0 }; static char global_heap_buf[270 * 1024] = { 0 };
#endif #endif