Implement multi-value feature and import binarydump tool (#308)

This commit is contained in:
Weining
2020-07-10 16:29:15 +08:00
committed by GitHub
parent 16a284a67c
commit 1a85051415
25 changed files with 2660 additions and 812 deletions

View File

@ -551,11 +551,19 @@ load_func_types(const uint8 **p_buf, const uint8 *buf_end,
/* Create each function type */
for (i = 0; i < module->func_type_count; i++) {
uint32 param_count, result_count;
uint32 param_cell_num, ret_cell_num;
uint64 size1;
read_uint32(buf, buf_end, param_count);
read_uint32(buf, buf_end, result_count);
if (param_count > UINT16_MAX || result_count > UINT16_MAX) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"param count or result count too large");
return false;
}
size1 = (uint64)param_count + (uint64)result_count;
size = offsetof(AOTFuncType, types) + size1;
if (!(func_types[i] = loader_malloc
@ -563,9 +571,22 @@ load_func_types(const uint8 **p_buf, const uint8 *buf_end,
return false;
}
func_types[i]->param_count = param_count;
func_types[i]->result_count = result_count;
func_types[i]->param_count = (uint16)param_count;
func_types[i]->result_count = (uint16)result_count;
read_byte_array(buf, buf_end, func_types[i]->types, (uint32)size1);
param_cell_num = wasm_get_cell_num(func_types[i]->types, param_count);
ret_cell_num = wasm_get_cell_num(func_types[i]->types + param_count,
result_count);
if (param_cell_num > UINT16_MAX || ret_cell_num > UINT16_MAX) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"param count or result count too large");
return false;
}
func_types[i]->param_cell_num = (uint16)param_cell_num;
func_types[i]->ret_cell_num = (uint16)ret_cell_num;
}
*p_buf = buf;

View File

@ -722,9 +722,77 @@ aot_call_function(WASMExecEnv *exec_env,
{
AOTModuleInstance *module_inst = (AOTModuleInstance*)exec_env->module_inst;
AOTFuncType *func_type = function->func_type;
bool ret = invoke_native_internal(exec_env, function->func_ptr,
func_type, NULL, NULL, argv, argc, argv);
return ret && !aot_get_exception(module_inst) ? true : false;
uint32 result_count = func_type->result_count;
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
bool ret;
if (ext_ret_count > 0) {
uint32 cell_num = 0, i;
uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
uint32 argv1_buf[32], *argv1 = argv1_buf, *ext_rets = NULL;
uint32 *argv_ret = argv;
uint32 ext_ret_cell = wasm_get_cell_num(ext_ret_types, ext_ret_count);
uint64 size;
/* Allocate memory all arguments */
size = sizeof(uint32) * (uint64)argc /* original arguments */
+ sizeof(void*) * (uint64)ext_ret_count /* extra result values' addr */
+ sizeof(uint32) * (uint64)ext_ret_cell; /* extra result values */
if (size > sizeof(argv1_buf)
&& !(argv1 = runtime_malloc(size, module_inst->cur_exception,
sizeof(module_inst->cur_exception)))) {
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
return false;
}
/* Copy original arguments */
bh_memcpy_s(argv1, (uint32)size, argv, sizeof(uint32) * argc);
/* Get the extra result value's address */
ext_rets = argv1 + argc + sizeof(void*)/sizeof(uint32) * ext_ret_count;
/* Append each extra result value's address to original arguments */
for (i = 0; i < ext_ret_count; i++) {
*(uintptr_t*)(argv1 + argc + sizeof(void*) / sizeof(uint32) * i) =
(uintptr_t)(ext_rets + cell_num);
cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
}
ret = invoke_native_internal(exec_env, function->func_ptr,
func_type, NULL, NULL, argv1, argc, argv);
if (!ret || aot_get_exception(module_inst)) {
if (argv1 != argv1_buf)
wasm_runtime_free(argv1);
return false;
}
/* Get extra result values */
switch (func_type->types[func_type->param_count]) {
case VALUE_TYPE_I32:
case VALUE_TYPE_F32:
argv_ret++;
break;
case VALUE_TYPE_I64:
case VALUE_TYPE_F64:
argv_ret += 2;
break;
default:
bh_assert(0);
break;
}
ext_rets = argv1 + argc + sizeof(void*)/sizeof(uint32) * ext_ret_count;
bh_memcpy_s(argv_ret, sizeof(uint32) * cell_num,
ext_rets, sizeof(uint32) * cell_num);
if (argv1 != argv1_buf)
wasm_runtime_free(argv1);
return true;
}
else {
ret = invoke_native_internal(exec_env, function->func_ptr,
func_type, NULL, NULL, argv, argc, argv);
return ret && !aot_get_exception(module_inst) ? true : false;
}
}
bool
@ -1183,10 +1251,12 @@ aot_call_indirect(WASMExecEnv *exec_env,
void **func_ptrs = (void**)module_inst->func_ptrs.ptr, *func_ptr;
uint32 table_size = module_inst->table_size;
uint32 func_idx, func_type_idx1;
uint32 ext_ret_count;
AOTImportFunc *import_func;
const char *signature = NULL;
void *attachment = NULL;
char buf[128];
bool ret;
/* this function is called from native code, so exec_env->handle and
exec_env->native_stack_boundary must have been set, we don't set
@ -1241,9 +1311,77 @@ aot_call_indirect(WASMExecEnv *exec_env,
}
}
return invoke_native_internal(exec_env, func_ptr,
func_type, signature, attachment,
argv, argc, argv);
ext_ret_count = func_type->result_count > 1
? func_type->result_count - 1 : 0;
if (ext_ret_count > 0) {
uint32 argv1_buf[32], *argv1 = argv1_buf;
uint32 *ext_rets = NULL, *argv_ret = argv;
uint32 cell_num = 0, i;
uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
uint32 ext_ret_cell = wasm_get_cell_num(ext_ret_types, ext_ret_count);
uint64 size;
/* Allocate memory all arguments */
size = sizeof(uint32) * (uint64)argc /* original arguments */
+ sizeof(void*) * (uint64)ext_ret_count /* extra result values' addr */
+ sizeof(uint32) * (uint64)ext_ret_cell; /* extra result values */
if (size > sizeof(argv1_buf)
&& !(argv1 = runtime_malloc(size, module_inst->cur_exception,
sizeof(module_inst->cur_exception)))) {
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
return false;
}
/* Copy original arguments */
bh_memcpy_s(argv1, (uint32)size, argv, sizeof(uint32) * argc);
/* Get the extra result value's address */
ext_rets = argv1 + argc + sizeof(void*)/sizeof(uint32) * ext_ret_count;
/* Append each extra result value's address to original arguments */
for (i = 0; i < ext_ret_count; i++) {
*(uintptr_t*)(argv1 + argc + sizeof(void*) / sizeof(uint32) * i) =
(uintptr_t)(ext_rets + cell_num);
cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
}
ret = invoke_native_internal(exec_env, func_ptr,
func_type, signature, attachment,
argv1, argc, argv);
if (!ret || aot_get_exception(module_inst)) {
if (argv1 != argv1_buf)
wasm_runtime_free(argv1);
return false;
}
/* Get extra result values */
switch (func_type->types[func_type->param_count]) {
case VALUE_TYPE_I32:
case VALUE_TYPE_F32:
argv_ret++;
break;
case VALUE_TYPE_I64:
case VALUE_TYPE_F64:
argv_ret += 2;
break;
default:
bh_assert(0);
break;
}
ext_rets = argv1 + argc + sizeof(void*)/sizeof(uint32) * ext_ret_count;
bh_memcpy_s(argv_ret, sizeof(uint32) * cell_num,
ext_rets, sizeof(uint32) * cell_num);
if (argv1 != argv1_buf)
wasm_runtime_free(argv1);
return true;
}
else {
return invoke_native_internal(exec_env, func_ptr,
func_type, signature, attachment,
argv, argc, argv);
}
}
#if WASM_ENABLE_BULK_MEMORY != 0