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