Make heap and linear memory contiguous to refine compilation time and footprint (#233)

Use FastISel for JIT mode
Use united aot version in aot file and aot runtime
Disable check signature failed warning for wamrc
Fix fast interpreter x86_32 float issue
Remove unused empty lvgl folder
This commit is contained in:
wenyongh 2020-04-13 10:49:40 +08:00 committed by GitHub
parent ffd975d2d6
commit b40e79c160
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 983 additions and 755 deletions

View File

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

View File

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

View File

@ -18,9 +18,6 @@
extern "C" {
#endif
#define AOT_MAGIC_NUMBER 0x746f6100
#define AOT_CURRENT_VERSION 1
typedef enum AOTExceptionID {
EXCE_UNREACHABLE = 0,
EXCE_OUT_OF_MEMORY,
@ -200,19 +197,27 @@ typedef struct AOTModuleInstance {
/* WASI context */
AOTPointer wasi_ctx;
/* total memory size: heap and linear memory */
uint32 total_mem_size;
/* boundary check constants for aot code */
uint32 mem_bound_check_1byte;
uint32 mem_bound_check_2bytes;
uint32 mem_bound_check_4bytes;
uint32 mem_bound_check_8bytes;
/* others */
int32 temp_ret;
uint32 llvm_stack;
int32 DYNAMICTOP_PTR_offset;
uint32 default_wasm_stack_size;
/* reserved */
uint32 reserved[16];
uint32 reserved[12];
union {
uint64 _make_it_8_byte_aligned_;
uint8 bytes[1];
} global_table_heap_data;
} global_table_data;
} AOTModuleInstance;
typedef AOTExportFunc AOTFunctionInstance;
@ -441,13 +446,13 @@ aot_is_wasm_type_equal(AOTModuleInstance *module_inst,
*/
bool
aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
uint32 *frame_lp, uint32 argc, uint32 *argv_ret);
uint32 argc, uint32 *argv);
bool
aot_call_indirect(WASMExecEnv *exec_env,
bool check_func_type, uint32 func_type_idx,
uint32 table_elem_idx,
uint32 *frame_lp, uint32 argc, uint32 *argv_ret);
uint32 argc, uint32 *argv);
uint32
aot_get_plt_table_size();

View File

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

View File

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

View File

@ -46,9 +46,13 @@ typedef struct WASMModuleInstanceCommon {
#if WASM_ENABLE_LIBC_WASI != 0
typedef struct WASIContext {
struct fd_table *curfds;
struct fd_prestats *prestats;
struct argv_environ_values *argv_environ;
/* Use offset but not native address, since these fields are
allocated from app's heap, and the heap space may be re-allocated
after memory.grow opcode is executed, the original native address
cannot be accessed again. */
int32 curfds_offset;
int32 prestats_offset;
int32 argv_environ_offset;
} WASIContext;
#endif

View File

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

View File

@ -143,20 +143,19 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef ret_type, uint8 wasm_ret_type,
LLVMValueRef *p_value_ret, LLVMValueRef *p_res)
{
LLVMTypeRef func_type, func_ptr_type, func_param_types[5];
LLVMTypeRef func_type, func_ptr_type, func_param_types[4];
LLVMTypeRef ret_ptr_type, elem_ptr_type;
LLVMValueRef func, elem_idx, elem_ptr;
LLVMValueRef func_param_values[5], value_ret = NULL, value_ret_ptr, res;
LLVMValueRef func_param_values[4], value_ret = NULL, res;
char buf[32], *func_name = "aot_invoke_native";
uint32 i, cell_num = 0;
/* prepare function type of aot_invoke_native */
func_param_types[0] = comp_ctx->exec_env_type; /* exec_env */
func_param_types[1] = I32_TYPE; /* func_idx */
func_param_types[2] = INT32_PTR_TYPE; /* frame_lp */
func_param_types[3] = I32_TYPE; /* argc */
func_param_types[4] = INT32_PTR_TYPE; /* argv_ret */
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 5, false))) {
func_param_types[2] = I32_TYPE; /* argc */
func_param_types[3] = INT32_PTR_TYPE; /* argv */
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 4, false))) {
aot_set_last_error("llvm add function type failed.");
return false;
}
@ -216,6 +215,24 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
cell_num += wasm_value_type_cell_num(aot_func_type->types[i]);
}
func_param_values[0] = func_ctx->exec_env;
func_param_values[1] = func_idx;
func_param_values[2] = I32_CONST(param_cell_num);
func_param_values[3] = func_ctx->argv_buf;
if (!func_param_values[2]) {
aot_set_last_error("llvm create const failed.");
return false;
}
/* call aot_invoke_native() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func,
func_param_values, 4, "res"))) {
aot_set_last_error("llvm build call failed.");
return false;
}
/* get function return value */
if (wasm_ret_type != VALUE_TYPE_VOID) {
if (!(ret_ptr_type = LLVMPointerType(ret_type, 0))) {
aot_set_last_error("llvm add pointer type failed.");
@ -227,39 +244,12 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_set_last_error("llvm build bit cast failed.");
return false;
}
/* convert to int32 pointer */
if (!(value_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, value_ret,
INT32_PTR_TYPE, "argv_ret_ptr"))) {
aot_set_last_error("llvm build store failed.");
if (!(*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret,
"value_ret"))) {
aot_set_last_error("llvm build load failed.");
return false;
}
}
else {
value_ret_ptr = LLVMConstNull(INT32_PTR_TYPE);
}
func_param_values[0] = func_ctx->exec_env;
func_param_values[1] = func_idx;
func_param_values[2] = func_ctx->argv_buf;
func_param_values[3] = I32_CONST(param_cell_num);
func_param_values[4] = value_ret_ptr;
if (!func_param_values[3]) {
aot_set_last_error("llvm create const failed.");
return false;
}
/* call aot_invoke_native() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func,
func_param_values, 5, "res"))) {
aot_set_last_error("llvm build call failed.");
return false;
}
if (wasm_ret_type != VALUE_TYPE_VOID)
/* get function return value */
*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret, "value_ret");
*p_res = res;
return true;
@ -395,10 +385,10 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef ret_type, uint8 wasm_ret_type,
LLVMValueRef *p_value_ret, LLVMValueRef *p_res)
{
LLVMTypeRef func_type, func_ptr_type, func_param_types[7];
LLVMTypeRef func_type, func_ptr_type, func_param_types[6];
LLVMTypeRef ret_ptr_type, elem_ptr_type;
LLVMValueRef func, elem_idx, elem_ptr;
LLVMValueRef func_param_values[7], value_ret = NULL, value_ret_ptr, res = NULL;
LLVMValueRef func_param_values[6], value_ret = NULL, res = NULL;
char buf[32], *func_name = "aot_call_indirect";
uint32 i, cell_num = 0;
@ -407,10 +397,9 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
func_param_types[1] = INT8_TYPE; /* check_func_type */
func_param_types[2] = I32_TYPE; /* func_type_idx */
func_param_types[3] = I32_TYPE; /* table_elem_idx */
func_param_types[4] = INT32_PTR_TYPE; /* frame_lp */
func_param_types[5] = I32_TYPE; /* argc */
func_param_types[6] = INT32_PTR_TYPE; /* argv_ret */
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 7, false))) {
func_param_types[4] = I32_TYPE; /* argc */
func_param_types[5] = INT32_PTR_TYPE; /* argv */
if (!(func_type = LLVMFunctionType(INT8_TYPE, func_param_types, 6, false))) {
aot_set_last_error("llvm add function type failed.");
return false;
}
@ -470,6 +459,26 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
cell_num += wasm_value_type_cell_num(aot_func_type->types[i]);
}
func_param_values[0] = func_ctx->exec_env;
func_param_values[1] = I8_CONST(true);
func_param_values[2] = func_type_idx;
func_param_values[3] = table_elem_idx;
func_param_values[4] = I32_CONST(param_cell_num);
func_param_values[5] = func_ctx->argv_buf;
if (!func_param_values[1] || !func_param_values[4]) {
aot_set_last_error("llvm create const failed.");
return false;
}
/* call aot_call_indirect() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func,
func_param_values, 6, "res"))) {
aot_set_last_error("llvm build call failed.");
return false;
}
/* get function return value */
if (wasm_ret_type != VALUE_TYPE_VOID) {
if (!(ret_ptr_type = LLVMPointerType(ret_type, 0))) {
aot_set_last_error("llvm add pointer type failed.");
@ -482,40 +491,12 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false;
}
/* convert to int32 pointer */
if (!(value_ret_ptr = LLVMBuildBitCast(comp_ctx->builder, value_ret,
INT32_PTR_TYPE, "argv_ret_ptr"))) {
aot_set_last_error("llvm build store failed.");
if (!(*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret,
"value_ret"))) {
aot_set_last_error("llvm build load failed.");
return false;
}
}
else {
value_ret_ptr = LLVMConstNull(INT32_PTR_TYPE);
}
func_param_values[0] = func_ctx->exec_env;
func_param_values[1] = I8_CONST(true);
func_param_values[2] = func_type_idx;
func_param_values[3] = table_elem_idx;
func_param_values[4] = func_ctx->argv_buf;
func_param_values[5] = I32_CONST(param_cell_num);
func_param_values[6] = value_ret_ptr;
if (!func_param_values[1] || !func_param_values[4]) {
aot_set_last_error("llvm create const failed.");
return false;
}
/* call aot_call_indirect() function */
if (!(res = LLVMBuildCall(comp_ctx->builder, func,
func_param_values, 7, "res"))) {
aot_set_last_error("llvm build call failed.");
return false;
}
if (wasm_ret_type != VALUE_TYPE_VOID)
/* get function return value */
*p_value_ret = LLVMBuildLoad(comp_ctx->builder, value_ret, "value_ret");
*p_res = res;
return true;

View File

@ -23,14 +23,6 @@
} \
} while (0)
#define BUILD_COND_BR(cmp_val, then_block, else_block) do { \
if (!LLVMBuildCondBr(comp_ctx->builder, cmp_val, \
then_block, else_block)) { \
aot_set_last_error("llvm build cond br failed."); \
goto fail; \
} \
} while (0)
#define ADD_BASIC_BLOCK(block, name) do { \
if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
func_ctx->func, \
@ -43,53 +35,88 @@
#define SET_BUILD_POS(block) \
LLVMPositionBuilderAtEnd(comp_ctx->builder, block)
static LLVMValueRef
get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 bytes)
{
LLVMValueRef mem_check_bound = NULL;
switch (bytes) {
case 1:
mem_check_bound = func_ctx->mem_bound_check_1byte;
break;
case 2:
mem_check_bound = func_ctx->mem_bound_check_2bytes;
break;
case 4:
mem_check_bound = func_ctx->mem_bound_check_4bytes;
break;
case 8:
mem_check_bound = func_ctx->mem_bound_check_8bytes;
break;
default:
bh_assert(0);
return NULL;
}
if (func_ctx->mem_space_unchanged)
return mem_check_bound;
if (!(mem_check_bound = LLVMBuildLoad(comp_ctx->builder,
mem_check_bound,
"mem_check_bound"))) {
aot_set_last_error("llvm build load failed.");
return NULL;
}
return mem_check_bound;
}
static LLVMValueRef
check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 offset, uint32 bytes)
{
LLVMValueRef offset_const = I32_CONST(offset);
LLVMValueRef size_const = I32_CONST(bytes);
LLVMValueRef addr, maddr, moffset;
LLVMValueRef cmp, phi;
LLVMValueRef mem_base_addr, mem_data_size;
LLVMValueRef heap_base_addr, heap_base_offset;
LLVMValueRef mem_offset_max = NULL, heap_offset_max = NULL;
LLVMBasicBlockRef check_mem_space, check_heap_space, check_succ;
LLVMValueRef bytes_const = I32_CONST(bytes);
LLVMValueRef bytes64_const = I64_CONST(bytes);
LLVMValueRef heap_base_offset = func_ctx->heap_base_offset;
LLVMValueRef addr, maddr, offset1, offset2, cmp;
LLVMValueRef mem_base_addr, mem_check_bound, total_mem_size;
LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
LLVMBasicBlockRef check_succ, check_mem_space;
CHECK_LLVM_CONST(offset_const);
CHECK_LLVM_CONST(size_const);
CHECK_LLVM_CONST(bytes_const);
CHECK_LLVM_CONST(bytes64_const);
heap_base_addr = func_ctx->heap_base_addr;
heap_base_offset = func_ctx->heap_base_offset;
/* Get memory base address and memory data size */
if (func_ctx->mem_space_unchanged) {
mem_base_addr = func_ctx->mem_base_addr;
}
else {
if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_base_addr,
"mem_base"))) {
aot_set_last_error("llvm build load failed.");
goto fail;
}
}
POP_I32(addr);
BUILD_OP(Add, offset_const, addr, moffset, "moffset");
/* offset1 = offset + addr; */
BUILD_OP(Add, offset_const, addr, offset1, "offset1");
/* return addres directly if constant offset and inside memory space */
if (LLVMIsConstant(moffset)) {
uint32 memory_offset = (uint32)LLVMConstIntGetZExtValue(moffset);
if (LLVMIsConstant(offset1)) {
uint32 mem_offset = (uint32)LLVMConstIntGetZExtValue(offset1);
uint32 num_bytes_per_page = comp_ctx->comp_data->num_bytes_per_page;
uint32 init_page_count = comp_ctx->comp_data->mem_init_page_count;
if (init_page_count > 0
&& memory_offset <= comp_ctx->comp_data->num_bytes_per_page
* init_page_count - bytes) {
uint32 mem_data_size = num_bytes_per_page * init_page_count;
if (mem_data_size > 0
&& mem_offset <= mem_data_size - bytes) {
/* inside memory space */
if (!func_ctx->mem_space_unchanged) {
if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_base_addr,
"mem_base"))) {
aot_set_last_error("llvm build load failed.");
return NULL;
}
}
else {
mem_base_addr = func_ctx->mem_base_addr;
}
/* maddr = mem_base_addr + moffset */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder,
mem_base_addr,
&moffset, 1, "maddr"))) {
&offset1, 1, "maddr"))) {
aot_set_last_error("llvm build add failed.");
goto fail;
}
@ -97,136 +124,63 @@ check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
}
/* Add basic blocks */
ADD_BASIC_BLOCK(check_heap_space, "check_heap_space");
ADD_BASIC_BLOCK(check_succ, "check_succ");
LLVMMoveBasicBlockAfter(check_heap_space, block_curr);
LLVMMoveBasicBlockAfter(check_succ, check_heap_space);
/* Add return maddress phi for check_succ block */
SET_BUILD_POS(check_succ);
if (!(phi = LLVMBuildPhi(comp_ctx->builder,
INT8_PTR_TYPE, "maddr_phi"))) {
aot_set_last_error("llvm build phi failed.");
goto fail;
}
SET_BUILD_POS(block_curr);
/* Get memory data size */
if (!func_ctx->mem_space_unchanged) {
if (!(mem_data_size = LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_data_size,
"mem_data_size"))) {
aot_set_last_error("llvm build load failed.");
return NULL;
}
}
else {
mem_data_size = func_ctx->mem_data_size;
}
if (comp_ctx->comp_data->mem_init_page_count == 0) {
/* Get total memory size */
if (func_ctx->mem_space_unchanged) {
total_mem_size = func_ctx->total_mem_size;
}
else {
if (!(total_mem_size = LLVMBuildLoad(comp_ctx->builder,
func_ctx->total_mem_size,
"total_mem_size"))) {
aot_set_last_error("llvm build load failed.");
goto fail;
}
}
ADD_BASIC_BLOCK(check_mem_space, "check_mem_space");
LLVMMoveBasicBlockAfter(check_mem_space, block_curr);
/* if mem_data_size is zero, check heap space */
BUILD_ICMP(LLVMIntEQ, mem_data_size, I32_ZERO, cmp,
"cmp_mem_data_size");
BUILD_COND_BR(cmp, check_heap_space, check_mem_space);
/* if total_mem_size is zero, boundary check fail */
BUILD_ICMP(LLVMIntEQ, total_mem_size, I32_ZERO, cmp,
"cmp_total_mem_size");
if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
true, cmp, check_mem_space)) {
goto fail;
}
SET_BUILD_POS(check_mem_space);
}
/* Get memory base address */
if (!func_ctx->mem_space_unchanged) {
if (!(mem_base_addr = LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_base_addr,
"mem_base"))) {
aot_set_last_error("llvm build load failed.");
return NULL;
}
}
else {
mem_base_addr = func_ctx->mem_base_addr;
}
/* offset2 = offset1 - heap_base_offset; */
BUILD_OP(Sub, offset1, heap_base_offset, offset2, "offset2");
/* maddr = mem_base_addr + moffset */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr,
&moffset, 1, "maddr"))) {
aot_set_last_error("llvm build add failed.");
goto fail;
}
block_curr = LLVMGetInsertBlock(comp_ctx->builder);
LLVMAddIncoming(phi, &maddr, &block_curr, 1);
if (!func_ctx->mem_space_unchanged) {
/* mem_offset_max = mem_data_size - bytes to load/read */
if (!(mem_offset_max = LLVMBuildSub(comp_ctx->builder,
mem_data_size, size_const,
"mem_offset_max"))) {
aot_set_last_error("llvm build sub failed.");
goto fail;
}
}
else {
if (bytes == 1)
mem_offset_max = func_ctx->mem_bound_1_byte;
else if (bytes == 2)
mem_offset_max = func_ctx->mem_bound_2_bytes;
else if (bytes == 4)
mem_offset_max = func_ctx->mem_bound_4_bytes;
else if (bytes == 8)
mem_offset_max = func_ctx->mem_bound_8_bytes;
}
/* in linear memory if (uint32)moffset <= (uint32)mem_offset_max,
else check heap space */
BUILD_ICMP(LLVMIntULE, moffset, mem_offset_max, cmp, "cmp_mem_offset");
/* Create condtion br */
BUILD_COND_BR(cmp, check_succ, check_heap_space);
/* Start to translate the check_heap_space block */
SET_BUILD_POS(check_heap_space);
/* moffset -= heap_base_offset */
if (!(moffset = LLVMBuildSub(comp_ctx->builder,
moffset, heap_base_offset,
"moffset_to_heap"))) {
aot_set_last_error("llvm build sub failed.");
if (!(mem_check_bound =
get_memory_check_bound(comp_ctx, func_ctx, bytes))) {
goto fail;
}
/* maddr = heap_base_addr + moffset */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, heap_base_addr,
&moffset, 1, "maddr"))) {
aot_set_last_error("llvm build add failed.");
goto fail;
}
block_curr = LLVMGetInsertBlock(comp_ctx->builder);
LLVMAddIncoming(phi, &maddr, &block_curr, 1);
/* Add basic blocks */
ADD_BASIC_BLOCK(check_succ, "check_succ");
LLVMMoveBasicBlockAfter(check_succ, block_curr);
/* heap space base addr and size is unchanged,
the heap boundary is unchanged also. */
if (bytes == 1)
heap_offset_max = func_ctx->heap_bound_1_byte;
else if (bytes == 2)
heap_offset_max = func_ctx->heap_bound_2_bytes;
else if (bytes == 4)
heap_offset_max = func_ctx->heap_bound_4_bytes;
else if (bytes == 8)
heap_offset_max = func_ctx->heap_bound_8_bytes;
/* in heap space if (uint32)moffset <= (uint32)heap_offset_max,
else throw exception */
BUILD_ICMP(LLVMIntUGT, moffset, heap_offset_max, cmp, "cmp_heap_offset");
/* offset2 > bound ? */
BUILD_ICMP(LLVMIntUGT, offset2, mem_check_bound, cmp, "cmp");
if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
true, cmp, check_succ))
true, cmp, check_succ)) {
goto fail;
}
SET_BUILD_POS(check_succ);
return phi;
/* maddr = mem_base_addr + offset1 */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr,
&offset1, 1, "maddr"))) {
aot_set_last_error("llvm build add failed.");
goto fail;
}
return maddr;
fail:
return NULL;
}

View File

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

View File

@ -181,68 +181,117 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
}
/* Load memory data size */
offset = I32_CONST(offsetof(AOTModuleInstance, memory_data_size));
if (!(func_ctx->mem_data_size =
/* Load total memory size */
offset = I32_CONST(offsetof(AOTModuleInstance, total_mem_size));
if (!(func_ctx->total_mem_size =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "mem_data_size_offset"))) {
&offset, 1, "bound_check_1byte_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->mem_data_size =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_data_size,
INT32_PTR_TYPE, "mem_data_size_ptr"))) {
if (!(func_ctx->total_mem_size =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->total_mem_size,
INT32_PTR_TYPE, "bound_check_1byte_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (mem_space_unchanged) {
if (!(func_ctx->mem_data_size =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_data_size,
"mem_data_size"))) {
if (!(func_ctx->total_mem_size =
LLVMBuildLoad(comp_ctx->builder, func_ctx->total_mem_size,
"bound_check_1byte"))) {
aot_set_last_error("llvm build load failed");
return false;
}
if (!(func_ctx->mem_bound_1_byte =
LLVMBuildSub(comp_ctx->builder,
func_ctx->mem_data_size, I32_ONE,
"mem_bound_1_byte"))
|| !(func_ctx->mem_bound_2_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->mem_data_size, I32_TWO,
"mem_bound_2_bytes"))
|| !(func_ctx->mem_bound_4_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->mem_data_size, I32_FOUR,
"mem_bound_4_bytes"))
|| !(func_ctx->mem_bound_8_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->mem_data_size, I32_EIGHT,
"mem_bound_8_bytes"))) {
aot_set_last_error("llvm build sub failed");
return false;
}
}
/* Load heap base address */
offset = I32_CONST(offsetof(AOTModuleInstance, heap_data.ptr));
if (!(func_ctx->heap_base_addr =
/* Load memory bound check constants */
offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_1byte));
if (!(func_ctx->mem_bound_check_1byte =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "heap_base_addr_offset"))) {
&offset, 1, "bound_check_1byte_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->heap_base_addr =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->heap_base_addr,
int8_ptr_type, "heap_base_addr_tmp"))) {
if (!(func_ctx->mem_bound_check_1byte =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_1byte,
INT32_PTR_TYPE, "bound_check_1byte_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (!(func_ctx->heap_base_addr =
LLVMBuildLoad(comp_ctx->builder, func_ctx->heap_base_addr,
"heap_base_addr"))) {
aot_set_last_error("llvm build load failed");
if (mem_space_unchanged) {
if (!(func_ctx->mem_bound_check_1byte =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_1byte,
"bound_check_1byte"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_2bytes));
if (!(func_ctx->mem_bound_check_2bytes =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "bound_check_2bytes_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->mem_bound_check_2bytes =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_2bytes,
INT32_PTR_TYPE, "bound_check_2bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (mem_space_unchanged) {
if (!(func_ctx->mem_bound_check_2bytes =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_2bytes,
"bound_check_2bytes"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_4bytes));
if (!(func_ctx->mem_bound_check_4bytes =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "bound_check_4bytes_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->mem_bound_check_4bytes =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_4bytes,
INT32_PTR_TYPE, "bound_check_4bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (mem_space_unchanged) {
if (!(func_ctx->mem_bound_check_4bytes =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_4bytes,
"bound_check_4bytes"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_8bytes));
if (!(func_ctx->mem_bound_check_8bytes =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "bound_check_8bytes_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->mem_bound_check_8bytes =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_8bytes,
INT32_PTR_TYPE, "bound_check_8bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (mem_space_unchanged) {
if (!(func_ctx->mem_bound_check_8bytes =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_8bytes,
"bound_check_8bytes"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
/* Load heap base offset */
offset = I32_CONST(offsetof(AOTModuleInstance, heap_base_offset));
@ -265,46 +314,6 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false;
}
/* Load heap data size */
offset = I32_CONST(offsetof(AOTModuleInstance, heap_data_size));
if (!(func_ctx->heap_data_size =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "heap_data_size_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->heap_data_size =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->heap_data_size,
INT32_PTR_TYPE, "heap_data_size_tmp"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (!(func_ctx->heap_data_size =
LLVMBuildLoad(comp_ctx->builder, func_ctx->heap_data_size,
"heap_data_size"))) {
aot_set_last_error("llvm build load failed");
return false;
}
if (!(func_ctx->heap_bound_1_byte =
LLVMBuildSub(comp_ctx->builder,
func_ctx->heap_data_size, I32_ONE,
"heap_bound_1_byte"))
|| !(func_ctx->heap_bound_2_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->heap_data_size, I32_TWO,
"heap_bound_2_bytes"))
|| !(func_ctx->heap_bound_4_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->heap_data_size, I32_FOUR,
"heap_bound_4_bytes"))
|| !(func_ctx->heap_bound_8_bytes =
LLVMBuildSub(comp_ctx->builder,
func_ctx->heap_data_size, I32_EIGHT,
"heap_bound_8_bytes"))) {
aot_set_last_error("llvm build sub failed");
return false;
}
return true;
}
@ -313,7 +322,7 @@ create_table_base(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
{
LLVMValueRef offset;
offset = I32_CONST(offsetof(AOTModuleInstance, global_table_heap_data.bytes)
offset = I32_CONST(offsetof(AOTModuleInstance, global_table_data.bytes)
+ comp_ctx->comp_data->global_data_size);
func_ctx->table_base = LLVMBuildInBoundsGEP(comp_ctx->builder,
func_ctx->aot_inst,
@ -918,6 +927,7 @@ aot_create_comp_context(AOTCompData *comp_data,
/* Create LLVM execution engine */
LLVMInitializeMCJITCompilerOptions(&jit_options, sizeof(jit_options));
jit_options.OptLevel = LLVMCodeGenLevelAggressive;
jit_options.EnableFastISel = true;
/*jit_options.CodeModel = LLVMCodeModelSmall;*/
if (LLVMCreateMCJITCompilerForModule
(&comp_ctx->exec_engine, comp_ctx->module,

View File

@ -94,20 +94,13 @@ typedef struct AOTFuncContext {
LLVMValueRef table_base;
LLVMValueRef argv_buf;
LLVMValueRef mem_data_size;
LLVMValueRef mem_base_addr;
LLVMValueRef mem_bound_1_byte;
LLVMValueRef mem_bound_2_bytes;
LLVMValueRef mem_bound_4_bytes;
LLVMValueRef mem_bound_8_bytes;
LLVMValueRef heap_base_offset;
LLVMValueRef heap_base_addr;
LLVMValueRef heap_data_size;
LLVMValueRef heap_bound_1_byte;
LLVMValueRef heap_bound_2_bytes;
LLVMValueRef heap_bound_4_bytes;
LLVMValueRef heap_bound_8_bytes;
LLVMValueRef mem_base_addr;
LLVMValueRef total_mem_size;
LLVMValueRef mem_bound_check_1byte;
LLVMValueRef mem_bound_check_2bytes;
LLVMValueRef mem_bound_check_4bytes;
LLVMValueRef mem_bound_check_8bytes;
LLVMValueRef cur_exception;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -46,26 +46,54 @@ typedef struct iovec_app {
} iovec_app_t;
typedef struct WASIContext {
void *curfds;
void *prestats;
void *argv_environ;
int32 curfds_offset;
int32 prestats_offset;
int32 argv_environ_offset;
} *wasi_ctx_t;
wasi_ctx_t
wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst);
static struct fd_table *
wasi_ctx_get_curfds(wasm_module_inst_t module_inst,
wasi_ctx_t wasi_ctx)
{
return (struct fd_table *)
wasm_runtime_addr_app_to_native(module_inst,
wasi_ctx->curfds_offset);
}
static struct argv_environ_values *
wasi_ctx_get_argv_environ(wasm_module_inst_t module_inst,
wasi_ctx_t wasi_ctx)
{
return (struct argv_environ_values *)
wasm_runtime_addr_app_to_native(module_inst,
wasi_ctx->argv_environ_offset);
}
static struct fd_prestats *
wasi_ctx_get_prestats(wasm_module_inst_t module_inst,
wasi_ctx_t wasi_ctx)
{
return (struct fd_prestats *)
wasm_runtime_addr_app_to_native(module_inst,
wasi_ctx->prestats_offset);
}
static wasi_errno_t
wasi_args_get(wasm_exec_env_t exec_env, int32 *argv_offsets, char *argv_buf)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct argv_environ_values *argv_environ =
wasi_ctx_get_argv_environ(module_inst, wasi_ctx);
size_t argc, argv_buf_size, i;
char **argv;
uint64 total_size;
wasi_errno_t err;
err = wasmtime_ssp_args_sizes_get(wasi_ctx->argv_environ,
&argc, &argv_buf_size);
err = wasmtime_ssp_args_sizes_get(argv_environ, &argc, &argv_buf_size);
if (err)
return err;
@ -81,7 +109,7 @@ wasi_args_get(wasm_exec_env_t exec_env, int32 *argv_offsets, char *argv_buf)
|| !(argv = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_args_get(wasi_ctx->argv_environ, argv, argv_buf);
err = wasmtime_ssp_args_get(argv_environ, argv, argv_buf);
if (err) {
wasm_runtime_free(argv);
return err;
@ -101,6 +129,7 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct argv_environ_values *argv_environ;
size_t argc, argv_buf_size;
wasi_errno_t err;
@ -108,7 +137,11 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env,
|| !validate_native_addr(argv_buf_size_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_args_sizes_get(wasi_ctx->argv_environ,
argv_environ = (struct argv_environ_values *)
wasm_runtime_addr_app_to_native(module_inst,
wasi_ctx->argv_environ_offset);
err = wasmtime_ssp_args_sizes_get(argv_environ,
&argc, &argv_buf_size);
if (err)
return err;
@ -151,12 +184,14 @@ wasi_environ_get(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct argv_environ_values *argv_environ =
wasi_ctx_get_argv_environ(module_inst, wasi_ctx);
size_t environ_count, environ_buf_size, i;
uint64 total_size;
char **environs;
wasi_errno_t err;
err = wasmtime_ssp_environ_sizes_get(wasi_ctx->argv_environ,
err = wasmtime_ssp_environ_sizes_get(argv_environ,
&environ_count, &environ_buf_size);
if (err)
return err;
@ -174,7 +209,7 @@ wasi_environ_get(wasm_exec_env_t exec_env,
|| !(environs = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_environ_get(wasi_ctx->argv_environ, environs, environ_buf);
err = wasmtime_ssp_environ_get(argv_environ, environs, environ_buf);
if (err) {
wasm_runtime_free(environs);
return err;
@ -194,6 +229,8 @@ wasi_environ_sizes_get(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct argv_environ_values *argv_environ =
wasi_ctx_get_argv_environ(module_inst, wasi_ctx);
size_t environ_count, environ_buf_size;
wasi_errno_t err;
@ -201,7 +238,7 @@ wasi_environ_sizes_get(wasm_exec_env_t exec_env,
|| !validate_native_addr(environ_buf_size_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_environ_sizes_get(wasi_ctx->argv_environ,
err = wasmtime_ssp_environ_sizes_get(argv_environ,
&environ_count, &environ_buf_size);
if (err)
return err;
@ -218,13 +255,14 @@ wasi_fd_prestat_get(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
wasi_prestat_t prestat;
wasi_errno_t err;
if (!validate_native_addr(prestat_app, sizeof(wasi_prestat_app_t)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_prestat_get(wasi_ctx->prestats, fd, &prestat);
err = wasmtime_ssp_fd_prestat_get(prestats, fd, &prestat);
if (err)
return err;
@ -239,8 +277,9 @@ wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
return wasmtime_ssp_fd_prestat_dir_name(wasi_ctx->prestats,
return wasmtime_ssp_fd_prestat_dir_name(prestats,
fd, path, path_len);
}
@ -249,8 +288,10 @@ wasi_fd_close(wasm_exec_env_t exec_env, wasi_fd_t fd)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
return wasmtime_ssp_fd_close(wasi_ctx->curfds, wasi_ctx->prestats, fd);
return wasmtime_ssp_fd_close(curfds, prestats, fd);
}
static wasi_errno_t
@ -258,8 +299,9 @@ wasi_fd_datasync(wasm_exec_env_t exec_env, wasi_fd_t fd)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_fd_datasync(wasi_ctx->curfds, fd);
return wasmtime_ssp_fd_datasync(curfds, fd);
}
static wasi_errno_t
@ -269,6 +311,7 @@ wasi_fd_pread(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
wasi_iovec_t *iovec, *iovec_begin;
uint64 total_size;
size_t nread;
@ -298,7 +341,7 @@ wasi_fd_pread(wasm_exec_env_t exec_env,
iovec->buf_len = iovec_app->buf_len;
}
err = wasmtime_ssp_fd_pread(wasi_ctx->curfds, fd, iovec_begin,
err = wasmtime_ssp_fd_pread(curfds, fd, iovec_begin,
iovs_len, offset, &nread);
if (err)
goto fail;
@ -320,6 +363,7 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
wasi_ciovec_t *ciovec, *ciovec_begin;
uint64 total_size;
size_t nwritten;
@ -349,7 +393,7 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env,
ciovec->buf_len = iovec_app->buf_len;
}
err = wasmtime_ssp_fd_pwrite(wasi_ctx->curfds, fd, ciovec_begin,
err = wasmtime_ssp_fd_pwrite(curfds, fd, ciovec_begin,
iovs_len, offset, &nwritten);
if (err)
goto fail;
@ -371,6 +415,7 @@ wasi_fd_read(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
wasi_iovec_t *iovec, *iovec_begin;
uint64 total_size;
size_t nread;
@ -400,7 +445,7 @@ wasi_fd_read(wasm_exec_env_t exec_env,
iovec->buf_len = iovec_app->buf_len;
}
err = wasmtime_ssp_fd_read(wasi_ctx->curfds, fd,
err = wasmtime_ssp_fd_read(curfds, fd,
iovec_begin, iovs_len, &nread);
if (err)
goto fail;
@ -420,9 +465,10 @@ wasi_fd_renumber(wasm_exec_env_t exec_env, wasi_fd_t from, wasi_fd_t to)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
return wasmtime_ssp_fd_renumber(wasi_ctx->curfds,
wasi_ctx->prestats, from, to);
return wasmtime_ssp_fd_renumber(curfds, prestats, from, to);
}
static wasi_errno_t
@ -432,12 +478,12 @@ wasi_fd_seek(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_seek(wasi_ctx->curfds, fd,
offset, whence, newoffset);
return wasmtime_ssp_fd_seek(curfds, fd, offset, whence, newoffset);
}
static wasi_errno_t
@ -446,11 +492,12 @@ wasi_fd_tell(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_tell(wasi_ctx->curfds, fd, newoffset);
return wasmtime_ssp_fd_tell(curfds, fd, newoffset);
}
static wasi_errno_t
@ -459,13 +506,14 @@ wasi_fd_fdstat_get(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
wasi_fdstat_t fdstat;
wasi_errno_t err;
if (!validate_native_addr(fdstat_app, sizeof(wasi_fdstat_t)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_fdstat_get(wasi_ctx->curfds, fd, &fdstat);
err = wasmtime_ssp_fd_fdstat_get(curfds, fd, &fdstat);
if (err)
return err;
@ -479,8 +527,9 @@ wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_fd_fdstat_set_flags(wasi_ctx->curfds, fd, flags);
return wasmtime_ssp_fd_fdstat_set_flags(curfds, fd, flags);
}
static wasi_errno_t
@ -491,8 +540,9 @@ wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_fd_fdstat_set_rights(wasi_ctx->curfds, fd,
return wasmtime_ssp_fd_fdstat_set_rights(curfds, fd,
fs_rights_base, fs_rights_inheriting);
}
@ -501,8 +551,9 @@ wasi_fd_sync(wasm_exec_env_t exec_env, wasi_fd_t fd)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_fd_sync(wasi_ctx->curfds, fd);
return wasmtime_ssp_fd_sync(curfds, fd);
}
static wasi_errno_t
@ -512,6 +563,7 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
wasi_ciovec_t *ciovec, *ciovec_begin;
uint64 total_size;
size_t nwritten;
@ -541,7 +593,7 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
ciovec->buf_len = iovec_app->buf_len;
}
err = wasmtime_ssp_fd_write(wasi_ctx->curfds, fd,
err = wasmtime_ssp_fd_write(curfds, fd,
ciovec_begin, iovs_len, &nwritten);
if (err)
goto fail;
@ -565,8 +617,9 @@ wasi_fd_advise(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_fd_advise(wasi_ctx->curfds, fd, offset, len, advice);
return wasmtime_ssp_fd_advise(curfds, fd, offset, len, advice);
}
static wasi_errno_t
@ -577,8 +630,9 @@ wasi_fd_allocate(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_fd_allocate(wasi_ctx->curfds, fd, offset, len);
return wasmtime_ssp_fd_allocate(curfds, fd, offset, len);
}
static wasi_errno_t
@ -587,8 +641,9 @@ wasi_path_create_directory(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_path_create_directory(wasi_ctx->curfds, fd,
return wasmtime_ssp_path_create_directory(curfds, fd,
path, path_len);
}
@ -602,8 +657,10 @@ wasi_path_link(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
return wasmtime_ssp_path_link(wasi_ctx->curfds, wasi_ctx->prestats,
return wasmtime_ssp_path_link(curfds, prestats,
old_fd, old_flags, old_path, old_path_len,
new_fd, new_path, new_path_len);
}
@ -621,20 +678,21 @@ wasi_path_open(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
wasi_fd_t fd = -1; /* set fd_app -1 if path open failed */
wasi_errno_t err;
if (!validate_native_addr(fd_app, sizeof(wasi_fd_t)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_path_open(wasi_ctx->curfds,
dirfd, dirflags,
path, path_len,
oflags,
fs_rights_base,
fs_rights_inheriting,
fs_flags,
&fd);
err = wasmtime_ssp_path_open(curfds,
dirfd, dirflags,
path, path_len,
oflags,
fs_rights_base,
fs_rights_inheriting,
fs_flags,
&fd);
*fd_app = fd;
return err;
@ -649,13 +707,14 @@ wasi_fd_readdir(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
size_t bufused;
wasi_errno_t err;
if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_readdir(wasi_ctx->curfds, fd,
err = wasmtime_ssp_fd_readdir(curfds, fd,
buf, buf_len, cookie, &bufused);
if (err)
return err;
@ -673,13 +732,14 @@ wasi_path_readlink(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
size_t bufused;
wasi_errno_t err;
if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_path_readlink(wasi_ctx->curfds, fd,
err = wasmtime_ssp_path_readlink(curfds, fd,
path, path_len,
buf, buf_len, &bufused);
if (err)
@ -696,8 +756,9 @@ wasi_path_rename(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_path_rename(wasi_ctx->curfds,
return wasmtime_ssp_path_rename(curfds,
old_fd, old_path, old_path_len,
new_fd, new_path, new_path_len);
}
@ -708,11 +769,12 @@ wasi_fd_filestat_get(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_filestat_get(wasi_ctx->curfds, fd, filestat);
return wasmtime_ssp_fd_filestat_get(curfds, fd, filestat);
}
static wasi_errno_t
@ -724,8 +786,9 @@ wasi_fd_filestat_set_times(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_fd_filestat_set_times(wasi_ctx->curfds, fd,
return wasmtime_ssp_fd_filestat_set_times(curfds, fd,
st_atim, st_mtim, fstflags);
}
@ -736,8 +799,9 @@ wasi_fd_filestat_set_size(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_fd_filestat_set_size(wasi_ctx->curfds, fd, st_size);
return wasmtime_ssp_fd_filestat_set_size(curfds, fd, st_size);
}
static wasi_errno_t
@ -749,11 +813,12 @@ wasi_path_filestat_get(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_path_filestat_get(wasi_ctx->curfds, fd,
return wasmtime_ssp_path_filestat_get(curfds, fd,
flags, path, path_len, filestat);
}
@ -768,8 +833,9 @@ wasi_path_filestat_set_times(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_path_filestat_set_times(wasi_ctx->curfds, fd,
return wasmtime_ssp_path_filestat_set_times(curfds, fd,
flags, path, path_len,
st_atim, st_mtim, fstflags);
}
@ -781,8 +847,10 @@ wasi_path_symlink(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
struct fd_prestats *prestats = wasi_ctx_get_prestats(module_inst, wasi_ctx);
return wasmtime_ssp_path_symlink(wasi_ctx->curfds, wasi_ctx->prestats,
return wasmtime_ssp_path_symlink(curfds, prestats,
old_path, old_path_len, fd,
new_path, new_path_len);
}
@ -793,8 +861,9 @@ wasi_path_unlink_file(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_path_unlink_file(wasi_ctx->curfds, fd, path, path_len);
return wasmtime_ssp_path_unlink_file(curfds, fd, path, path_len);
}
static wasi_errno_t
@ -803,8 +872,9 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_path_remove_directory(wasi_ctx->curfds, fd, path, path_len);
return wasmtime_ssp_path_remove_directory(curfds, fd, path, path_len);
}
static wasi_errno_t
@ -814,6 +884,7 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
size_t nevents;
wasi_errno_t err;
@ -822,7 +893,7 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env,
|| !validate_native_addr(nevents_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_poll_oneoff(wasi_ctx->curfds, in, out,
err = wasmtime_ssp_poll_oneoff(curfds, in, out,
nsubscriptions, &nevents);
if (err)
return err;
@ -864,6 +935,7 @@ wasi_sock_recv(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
wasi_iovec_t *iovec, *iovec_begin;
uint64 total_size;
size_t ro_datalen;
@ -894,7 +966,7 @@ wasi_sock_recv(wasm_exec_env_t exec_env,
iovec->buf_len = ri_data->buf_len;
}
err = wasmtime_ssp_sock_recv(wasi_ctx->curfds, sock,
err = wasmtime_ssp_sock_recv(curfds, sock,
iovec_begin, ri_data_len,
ri_flags, &ro_datalen,
ro_flags);
@ -920,6 +992,7 @@ wasi_sock_send(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
wasi_ciovec_t *ciovec, *ciovec_begin;
uint64 total_size;
size_t so_datalen;
@ -949,7 +1022,7 @@ wasi_sock_send(wasm_exec_env_t exec_env,
ciovec->buf_len = si_data->buf_len;
}
err = wasmtime_ssp_sock_send(wasi_ctx->curfds, sock,
err = wasmtime_ssp_sock_send(curfds, sock,
ciovec_begin, si_data_len,
si_flags, &so_datalen);
if (err)
@ -971,8 +1044,9 @@ wasi_sock_shutdown(wasm_exec_env_t exec_env,
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_shutdown(wasi_ctx->curfds, sock, how);
return wasmtime_ssp_sock_shutdown(curfds, sock, how);
}
static wasi_errno_t

View File

@ -404,10 +404,11 @@ gc_realloc_vo_internal(void *vheap, void *ptr, gc_size_t size,
#endif
{
gc_heap_t* heap = (gc_heap_t*) vheap;
hmu_t *hmu = NULL, *hmu_old = NULL;
hmu_t *hmu = NULL, *hmu_old = NULL, *hmu_next;
gc_object_t ret = (gc_object_t) NULL, obj_old = (gc_object_t)ptr;
gc_size_t tot_size, tot_size_unaligned, tot_size_old = 0;
gc_size_t tot_size, tot_size_unaligned, tot_size_old = 0, tot_size_next;
gc_size_t obj_size, obj_size_old;
hmu_type_t ut;
/* hmu header + prefix + obj + suffix */
tot_size_unaligned = HMU_SIZE + OBJ_PREFIX_SIZE + size + OBJ_SUFFIX_SIZE;
@ -427,6 +428,32 @@ gc_realloc_vo_internal(void *vheap, void *ptr, gc_size_t size,
os_mutex_lock(&heap->lock);
if (hmu_old) {
hmu_next = (hmu_t*)((char *)hmu_old + tot_size_old);
if (hmu_is_in_heap(heap, hmu_next)) {
ut = hmu_get_ut(hmu_next);
tot_size_next = hmu_get_size(hmu_next);
if (ut == HMU_FC
&& tot_size <= tot_size_old + tot_size_next) {
/* current node and next node meets requirement */
unlink_hmu(heap, hmu_next);
hmu_set_size(hmu_old, tot_size);
memset((char*)hmu_old + tot_size_old, 0, tot_size - tot_size_old);
#if BH_ENABLE_GC_VERIFY != 0
hmu_init_prefix_and_suffix(hmu_old, tot_size, file, line);
#endif
if (tot_size < tot_size_old + tot_size_next) {
hmu_next = (hmu_t*)((char*)hmu_old + tot_size);
tot_size_next = tot_size_old + tot_size_next - tot_size;
gci_add_fc(heap, hmu_next, tot_size_next);
}
os_mutex_unlock(&heap->lock);
return obj_old;
}
}
}
hmu = alloc_hmu_ex(heap, tot_size);
if (!hmu)
goto finish;

View File

@ -72,6 +72,35 @@ gc_init_with_pool(char *buf, gc_size_t buf_size);
int
gc_destroy_with_pool(gc_handle_t handle);
/**
* Migrate heap from one place to another place
*
* @param handle handle of the new heap
* @param handle_old handle of the old heap
*
* @return GC_SUCCESS if success, GC_ERROR otherwise
*/
int
gc_migrate(gc_handle_t handle, gc_handle_t handle_old);
/**
* Re-initialize lock of heap
*
* @param handle the heap handle
*
* @return GC_SUCCESS if success, GC_ERROR otherwise
*/
int
gc_reinit_lock(gc_handle_t handle);
/**
* Destroy lock of heap
*
* @param handle the heap handle
*/
void
gc_destroy_lock(gc_handle_t handle);
/**
* Get Heap Stats
*

View File

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

View File

@ -35,7 +35,6 @@ gc_init_with_pool(char *buf, gc_size_t buf_size)
}
/* init all data structures*/
heap->max_size = heap_max_size;
heap->current_size = heap_max_size;
heap->base_addr = (gc_uint8*)base_addr;
heap->heap_id = (gc_handle_t)heap;
@ -82,11 +81,72 @@ gc_destroy_with_pool(gc_handle_t handle)
{
gc_heap_t *heap = (gc_heap_t *) handle;
os_mutex_destroy(&heap->lock);
memset(heap->base_addr, 0, heap->max_size);
memset(heap->base_addr, 0, heap->current_size);
memset(heap, 0, sizeof(gc_heap_t));
return GC_SUCCESS;
}
static void
adjust_ptr(uint8 **p_ptr, intptr_t offset)
{
if (*p_ptr)
*p_ptr += offset;
}
int
gc_migrate(gc_handle_t handle, gc_handle_t handle_old)
{
gc_heap_t *heap = (gc_heap_t *) handle;
intptr_t offset = (uint8*)handle - (uint8*)handle_old;
hmu_t *cur = NULL, *end = NULL;
hmu_tree_node_t *tree_node;
gc_size_t size;
os_mutex_init(&heap->lock);
if (offset == 0)
return 0;
heap->heap_id = (gc_handle_t)heap;
heap->base_addr += offset;
adjust_ptr((uint8**)&heap->kfc_tree_root.left, offset);
adjust_ptr((uint8**)&heap->kfc_tree_root.right, offset);
adjust_ptr((uint8**)&heap->kfc_tree_root.parent, offset);
cur = (hmu_t*)heap->base_addr;
end = (hmu_t*)((char*)heap->base_addr + heap->current_size);
while (cur < end) {
size = hmu_get_size(cur);
bh_assert(size > 0);
if (!HMU_IS_FC_NORMAL(size)) {
tree_node = (hmu_tree_node_t *)cur;
adjust_ptr((uint8**)&tree_node->left, offset);
adjust_ptr((uint8**)&tree_node->right, offset);
adjust_ptr((uint8**)&tree_node->parent, offset);
}
cur = (hmu_t*)((char *)cur + size);
}
bh_assert(cur == end);
return 0;
}
int
gc_reinit_lock(gc_handle_t handle)
{
gc_heap_t *heap = (gc_heap_t *) handle;
return os_mutex_init(&heap->lock);
}
void
gc_destroy_lock(gc_handle_t handle)
{
gc_heap_t *heap = (gc_heap_t *) handle;
os_mutex_destroy(&heap->lock);
}
#if BH_ENABLE_GC_VERIFY != 0
void
gci_verify_heap(gc_heap_t *heap)

View File

@ -37,6 +37,26 @@ void mem_allocator_free(mem_allocator_t allocator, void *ptr)
gc_free_vo((gc_handle_t) allocator, ptr);
}
int
mem_allocator_migrate(mem_allocator_t allocator,
mem_allocator_t allocator_old)
{
return gc_migrate((gc_handle_t) allocator,
(gc_handle_t) allocator_old);
}
int
mem_allocator_reinit_lock(mem_allocator_t allocator)
{
return gc_reinit_lock((gc_handle_t) allocator);
}
void
mem_allocator_destroy_lock(mem_allocator_t allocator)
{
gc_destroy_lock((gc_handle_t) allocator);
}
#else /* else of DEFAULT_MEM_ALLOCATOR */
#include "tlsf/tlsf.h"
@ -141,5 +161,27 @@ mem_allocator_free(mem_allocator_t allocator, void *ptr)
}
}
int
mem_allocator_migrate(mem_allocator_t allocator,
mem_allocator_t allocator_old)
{
return tlsf_migrate((mem_allocator_tlsf *) allocator,
(mem_allocator_tlsf *) allocator_old);
}
int
mem_allocator_init_lock(mem_allocator_t allocator)
{
mem_allocator_tlsf *allocator_tlsf = (mem_allocator_tlsf *)allocator;
return os_mutex_init(&allocator_tlsf->lock);
}
void
mem_allocator_destroy_lock(mem_allocator_t allocator)
{
mem_allocator_tlsf *allocator_tlsf = (mem_allocator_tlsf *)allocator;
os_mutex_destroy(&allocator_tlsf->lock);
}
#endif /* end of DEFAULT_MEM_ALLOCATOR */

View File

@ -29,6 +29,16 @@ mem_allocator_realloc(mem_allocator_t allocator, void *ptr, uint32_t size);
void
mem_allocator_free(mem_allocator_t allocator, void *ptr);
int
mem_allocator_migrate(mem_allocator_t allocator,
mem_allocator_t allocator_old);
int
mem_allocator_reinit_lock(mem_allocator_t allocator);
void
mem_allocator_destroy_lock(mem_allocator_t allocator);
#ifdef __cplusplus
}
#endif

View File

@ -129,7 +129,7 @@ Run the test.wasm or test.aot with WAMR mini product build:
You will get the following output:
```
Hello world!
buf ptr: 0x400002b0
buf ptr: 0xffffc2c8
buf: 1234
```
If you would like to run the test app on Zephyr, we have embedded a test sample into its OS image. You will need to execute:

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

View File

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