Implement multi-module feature and bulk-memory feature (#271)

Refine wasm loader and aot loader
Fix potential issue of os_mmap/os_munmap
Update document
This commit is contained in:
wenyongh
2020-06-02 14:53:06 +08:00
committed by GitHub
parent e81f72d41f
commit 752826a667
57 changed files with 4902 additions and 818 deletions

View File

@ -68,42 +68,62 @@ table_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
uint32 i, global_index, global_data_offset, base_offset, length;
AOTTableInitData *table_seg;
if (module->table_init_data_count > 0) {
for (i = 0; i < module->table_init_data_count; i++) {
table_seg = module->table_init_data_list[i];
bh_assert(table_seg->offset.init_expr_type ==
INIT_EXPR_TYPE_I32_CONST
|| table_seg->offset.init_expr_type ==
INIT_EXPR_TYPE_GET_GLOBAL);
for (i = 0; i < module->table_init_data_count; i++) {
table_seg = module->table_init_data_list[i];
bh_assert(table_seg->offset.init_expr_type ==
INIT_EXPR_TYPE_I32_CONST
|| table_seg->offset.init_expr_type ==
INIT_EXPR_TYPE_GET_GLOBAL);
/* Resolve table data base offset */
if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
global_index = table_seg->offset.u.global_index;
bh_assert(global_index <
module->import_global_count + module->global_count);
/* TODO: && globals[table_seg->offset.u.global_index].type ==
VALUE_TYPE_I32*/
if (global_index < module->import_global_count)
global_data_offset =
module->import_globals[global_index].data_offset;
else
global_data_offset =
module->globals[global_index - module->import_global_count]
.data_offset;
base_offset = *(uint32*)
((uint8*)module_inst->global_data.ptr + global_data_offset);
}
/* Resolve table data base offset */
if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
global_index = table_seg->offset.u.global_index;
bh_assert(global_index <
module->import_global_count + module->global_count);
/* TODO: && globals[table_seg->offset.u.global_index].type ==
VALUE_TYPE_I32*/
if (global_index < module->import_global_count)
global_data_offset =
module->import_globals[global_index].data_offset;
else
base_offset = (uint32)table_seg->offset.u.i32;
global_data_offset =
module->globals[global_index - module->import_global_count]
.data_offset;
/* Copy table data */
length = table_seg->func_index_count;
if (base_offset < module_inst->table_size) {
memcpy((uint32*)module_inst->table_data.ptr + base_offset,
table_seg->func_indexes, length * sizeof(uint32));
}
base_offset = *(uint32*)
((uint8*)module_inst->global_data.ptr + global_data_offset);
}
else
base_offset = (uint32)table_seg->offset.u.i32;
/* Copy table data */
bh_assert(module_inst->table_data.ptr);
/* base_offset only since length might negative */
if (base_offset > module_inst->table_size) {
LOG_DEBUG("base_offset(%d) > table_size(%d)", base_offset,
module_inst->table_size);
set_error_buf(error_buf, error_buf_size,
"elements segment does not fit");
return false;
}
/* base_offset + length(could be zero) */
length = table_seg->func_index_count;
if (base_offset + length > module_inst->table_size) {
LOG_DEBUG("base_offset(%d) + length(%d) > table_size(%d)",
base_offset, length, module_inst->table_size);
set_error_buf(error_buf, error_buf_size,
"elements segment does not fit");
return false;
}
/**
* Check function index in the current module inst for now.
* will check the linked table inst owner in future
*/
memcpy((uint32 *)module_inst->table_data.ptr + base_offset,
table_seg->func_indexes,
length * sizeof(uint32));
}
return true;
@ -169,50 +189,64 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
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];
bh_assert(data_seg->offset.init_expr_type ==
INIT_EXPR_TYPE_I32_CONST
|| data_seg->offset.init_expr_type ==
INIT_EXPR_TYPE_GET_GLOBAL);
for (i = 0; i < module->mem_init_data_count; i++) {
data_seg = module->mem_init_data_list[i];
#if WASM_ENABLE_BULK_MEMORY != 0
if (data_seg->is_passive)
continue;
#endif
/* Resolve memory data base offset */
if (data_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
global_index = data_seg->offset.u.global_index;
bh_assert(global_index <
module->import_global_count + module->global_count);
/* TODO: && globals[data_seg->offset.u.global_index].type ==
VALUE_TYPE_I32*/
if (global_index < module->import_global_count)
global_data_offset =
module->import_globals[global_index].data_offset;
else
global_data_offset =
module->globals[global_index - module->import_global_count]
.data_offset;
bh_assert(data_seg->offset.init_expr_type ==
INIT_EXPR_TYPE_I32_CONST
|| data_seg->offset.init_expr_type ==
INIT_EXPR_TYPE_GET_GLOBAL);
base_offset = *(uint32*)
((uint8*)module_inst->global_data.ptr + global_data_offset);
}
/* Resolve memory data base offset */
if (data_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
global_index = data_seg->offset.u.global_index;
bh_assert(global_index <
module->import_global_count + module->global_count);
/* TODO: && globals[data_seg->offset.u.global_index].type ==
VALUE_TYPE_I32*/
if (global_index < module->import_global_count)
global_data_offset =
module->import_globals[global_index].data_offset;
else
base_offset = (uint32)data_seg->offset.u.i32;
global_data_offset =
module->globals[global_index - module->import_global_count]
.data_offset;
length = data_seg->byte_count;
/* Check memory data */
if (length > 0
&& (base_offset >= module_inst->memory_data_size
|| base_offset + length > module_inst->memory_data_size)) {
set_error_buf(error_buf, error_buf_size,
"AOT module instantiate failed: data segment out of range.");
goto fail2;
}
/* Copy memory data */
memcpy((uint8*)module_inst->memory_data.ptr + base_offset,
data_seg->bytes, length);
base_offset = *(uint32*)
((uint8*)module_inst->global_data.ptr + global_data_offset);
} else {
base_offset = (uint32)data_seg->offset.u.i32;
}
/* Copy memory data */
bh_assert(module_inst->memory_data.ptr);
/* Check memory data */
/* check offset since length might negative */
if (base_offset > module_inst->memory_data_size) {
LOG_DEBUG("base_offset(%d) > memory_data_size(%d)", base_offset,
module_inst->memory_data_size);
set_error_buf(error_buf, error_buf_size,
"data segment does not fit");
goto fail2;
}
/* check offset + length(could be zero) */
length = data_seg->byte_count;
if (base_offset + length > module_inst->memory_data_size) {
LOG_DEBUG("base_offset(%d) + length(%d) > memory_data_size(%d)",
base_offset, length, module_inst->memory_data_size);
set_error_buf(error_buf, error_buf_size,
"data segment does not fit");
goto fail2;
}
memcpy((uint8*)module_inst->memory_data.ptr + base_offset,
data_seg->bytes, length);
}
return true;
@ -952,3 +986,61 @@ aot_call_indirect(WASMExecEnv *exec_env,
func_type, signature, attachment,
argv, argc, argv);
}
#if WASM_ENABLE_BULK_MEMORY != 0
bool
aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index,
uint32 offset, uint32 len, uint32 dst)
{
AOTModule *aot_module;
uint8 *data = NULL;
uint8 *maddr;
uint64 seg_len = 0;
aot_module = (AOTModule *)module_inst->aot_module.ptr;
if (aot_module->is_jit_mode) {
#if WASM_ENABLE_JIT != 0
seg_len = aot_module->wasm_module->data_segments[seg_index]->data_length;
data = aot_module->wasm_module->data_segments[seg_index]->data;
#endif
}
else {
seg_len = aot_module->mem_init_data_list[seg_index]->byte_count;
data = aot_module->mem_init_data_list[seg_index]->bytes;
}
if (!aot_validate_app_addr(module_inst, dst, len))
return false;
if ((uint64)offset + (uint64)len > seg_len) {
aot_set_exception(module_inst, "out of bounds memory access");
return false;
}
maddr = aot_addr_app_to_native(module_inst, dst);
bh_memcpy_s(maddr, module_inst->memory_data_size - dst,
data + offset, len);
return true;
}
bool
aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index)
{
AOTModule *aot_module = (AOTModule *)(module_inst->aot_module.ptr);
if (aot_module->is_jit_mode) {
#if WASM_ENABLE_JIT != 0
aot_module->wasm_module->data_segments[seg_index]->data_length = 0;
/* Currently we can't free the dropped data segment
as they are stored in wasm bytecode */
#endif
}
else {
aot_module->mem_init_data_list[seg_index]->byte_count = 0;
/* Currently we can't free the dropped data segment
as the mem_init_data_count is a continuous array */
}
return true;
}
#endif /* WASM_ENABLE_BULK_MEMORY */