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