Implement native function pointer check, addr conversion and register, update documents (#185)
Modified WASM runtime API: - wasm_runtime_module_malloc() - wasm_runtime_lookup_function() Introduced runtime API - wasm_runtime_register_natives()
This commit is contained in:
@ -735,42 +735,13 @@ fail:
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_import_funcs(AOTImportFunc *import_funcs, bool is_jit_mode)
|
||||
destroy_import_funcs(AOTImportFunc *import_funcs,
|
||||
bool is_jit_mode)
|
||||
{
|
||||
if (!is_jit_mode)
|
||||
wasm_free(import_funcs);
|
||||
}
|
||||
|
||||
static void*
|
||||
resolve_sym(const char *module_name, const char *field_name)
|
||||
{
|
||||
void *sym;
|
||||
|
||||
#if WASM_ENABLE_LIBC_BUILTIN != 0
|
||||
if ((sym = wasm_native_lookup_libc_builtin_func(module_name,
|
||||
field_name)))
|
||||
return sym;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
if ((sym = wasm_native_lookup_libc_wasi_func(module_name,
|
||||
field_name)))
|
||||
return sym;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_BASE_LIB != 0
|
||||
if ((sym = wasm_native_lookup_base_lib_func(module_name,
|
||||
field_name)))
|
||||
return sym;
|
||||
#endif
|
||||
|
||||
if ((sym = wasm_native_lookup_extension_lib_func(module_name,
|
||||
field_name)))
|
||||
return sym;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
load_import_funcs(const uint8 **p_buf, const uint8 *buf_end,
|
||||
AOTModule *module,
|
||||
@ -804,13 +775,16 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end,
|
||||
"invalid function type index.");
|
||||
return false;
|
||||
}
|
||||
import_funcs[i].func_type = module->func_types[import_funcs[i].func_type_index];
|
||||
read_string(buf, buf_end, import_funcs[i].module_name);
|
||||
read_string(buf, buf_end, import_funcs[i].func_name);
|
||||
|
||||
module_name = import_funcs[i].module_name;
|
||||
field_name = import_funcs[i].func_name;
|
||||
if (!(import_funcs[i].func_ptr_linked =
|
||||
resolve_sym(module_name, field_name))) {
|
||||
wasm_native_resolve_symbol(module_name, field_name,
|
||||
import_funcs[i].func_type,
|
||||
&import_funcs[i].signature))) {
|
||||
LOG_WARNING("warning: fail to link import function (%s, %s)\n",
|
||||
module_name, field_name);
|
||||
}
|
||||
@ -2053,46 +2027,61 @@ aot_unload(AOTModule *module)
|
||||
#if WASM_ENABLE_JIT != 0
|
||||
if (module->comp_data)
|
||||
aot_destroy_comp_data(module->comp_data);
|
||||
|
||||
if (module->comp_ctx)
|
||||
aot_destroy_comp_context(module->comp_ctx);
|
||||
|
||||
if (module->wasm_module)
|
||||
wasm_loader_unload(module->wasm_module);
|
||||
#endif
|
||||
|
||||
if (module->mem_init_data_list)
|
||||
destroy_mem_init_data_list(module->mem_init_data_list,
|
||||
module->mem_init_data_count,
|
||||
module->is_jit_mode);
|
||||
|
||||
if (module->table_init_data_list)
|
||||
destroy_table_init_data_list(module->table_init_data_list,
|
||||
module->table_init_data_count,
|
||||
module->is_jit_mode);
|
||||
|
||||
if (module->func_types)
|
||||
destroy_func_types(module->func_types,
|
||||
module->func_type_count,
|
||||
module->is_jit_mode);
|
||||
|
||||
if (module->import_globals)
|
||||
destroy_import_globals(module->import_globals,
|
||||
module->is_jit_mode);
|
||||
|
||||
if (module->globals)
|
||||
destroy_globals(module->globals,
|
||||
module->is_jit_mode);
|
||||
|
||||
if (module->import_funcs)
|
||||
destroy_import_funcs(module->import_funcs,
|
||||
module->is_jit_mode);
|
||||
|
||||
if (module->export_funcs)
|
||||
destroy_export_funcs(module->export_funcs,
|
||||
module->is_jit_mode);
|
||||
|
||||
if (module->func_type_indexes)
|
||||
wasm_free(module->func_type_indexes);
|
||||
|
||||
if (module->func_ptrs)
|
||||
wasm_free(module->func_ptrs);
|
||||
|
||||
if (module->const_str_set)
|
||||
bh_hash_map_destroy(module->const_str_set);
|
||||
|
||||
if (module->code)
|
||||
bh_munmap(module->code, module->code_size);
|
||||
|
||||
if (module->data_sections)
|
||||
destroy_object_data_sections(module->data_sections,
|
||||
module->data_section_count);
|
||||
|
||||
wasm_free(module);
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ typedef struct {
|
||||
REG_SYM(aot_set_exception_with_id), \
|
||||
REG_SYM(aot_get_exception), \
|
||||
REG_SYM(aot_is_wasm_type_equal), \
|
||||
REG_SYM(aot_invoke_native), \
|
||||
REG_SYM(wasm_runtime_enlarge_memory), \
|
||||
REG_SYM(wasm_runtime_set_exception), \
|
||||
REG_SYM(fmin), \
|
||||
|
||||
@ -28,7 +28,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
|
||||
/* Initialize import global data */
|
||||
for (i = 0; i < module->import_global_count; i++, import_global++) {
|
||||
bh_assert(import_global->data_offset ==
|
||||
p - (uint8*)module_inst->global_data.ptr);
|
||||
(uint32)(p - (uint8*)module_inst->global_data.ptr));
|
||||
memcpy(p, &import_global->global_data_linked, import_global->size);
|
||||
p += import_global->size;
|
||||
}
|
||||
@ -36,7 +36,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
|
||||
/* Initialize defined global data */
|
||||
for (i = 0; i < module->global_count; i++, global++) {
|
||||
bh_assert(global->data_offset ==
|
||||
p - (uint8*)module_inst->global_data.ptr);
|
||||
(uint32)(p - (uint8*)module_inst->global_data.ptr));
|
||||
init_expr = &global->init_expr;
|
||||
switch (init_expr->init_expr_type) {
|
||||
case INIT_EXPR_TYPE_GET_GLOBAL:
|
||||
@ -53,7 +53,8 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
|
||||
p += global->size;
|
||||
}
|
||||
|
||||
bh_assert(module_inst->global_data_size == p - (uint8*)module_inst->global_data.ptr);
|
||||
bh_assert(module_inst->global_data_size ==
|
||||
(uint32)(p - (uint8*)module_inst->global_data.ptr));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -420,65 +421,6 @@ aot_deinstantiate(AOTModuleInstance *module_inst)
|
||||
wasm_free(module_inst);
|
||||
}
|
||||
|
||||
static bool
|
||||
check_type(uint8 type, const char *p)
|
||||
{
|
||||
const char *str = "i32";
|
||||
|
||||
if (strlen(p) < 3)
|
||||
return false;
|
||||
|
||||
switch (type) {
|
||||
case VALUE_TYPE_I32:
|
||||
str = "i32";
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
str = "i64";
|
||||
break;
|
||||
case VALUE_TYPE_F32:
|
||||
str = "f32";
|
||||
break;
|
||||
case VALUE_TYPE_F64:
|
||||
str = "f64";
|
||||
break;
|
||||
}
|
||||
if (strncmp(p, str, 3))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_function_type(const WASMType *type,
|
||||
const char *signature)
|
||||
{
|
||||
uint32 i;
|
||||
const char *p = signature;
|
||||
|
||||
if (!p || *p++ != '(')
|
||||
return false;
|
||||
|
||||
for (i = 0; i < type->param_count; i++) {
|
||||
if (!check_type(type->types[i], p))
|
||||
return false;
|
||||
p += 3;
|
||||
}
|
||||
|
||||
if (*p++ != ')')
|
||||
return false;
|
||||
|
||||
if (type->result_count) {
|
||||
if (!check_type(type->types[type->param_count], p))
|
||||
return false;
|
||||
p += 3;
|
||||
}
|
||||
|
||||
if (*p != '\0')
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AOTFunctionInstance*
|
||||
aot_lookup_function(const AOTModuleInstance *module_inst,
|
||||
const char *name, const char *signature)
|
||||
@ -486,13 +428,10 @@ aot_lookup_function(const AOTModuleInstance *module_inst,
|
||||
uint32 i;
|
||||
AOTModule *module = (AOTModule*)module_inst->aot_module.ptr;
|
||||
|
||||
for (i = 0; i < module->export_func_count; i++) {
|
||||
if (!strcmp(module->export_funcs[i].func_name, name)
|
||||
&& check_function_type(module->export_funcs[i].func_type,
|
||||
signature))
|
||||
for (i = 0; i < module->export_func_count; i++)
|
||||
if (!strcmp(module->export_funcs[i].func_name, name))
|
||||
return &module->export_funcs[i];
|
||||
}
|
||||
|
||||
(void)signature;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -517,8 +456,8 @@ aot_call_function(WASMExecEnv *exec_env,
|
||||
{
|
||||
AOTModuleInstance *module_inst = (AOTModuleInstance*)exec_env->module_inst;
|
||||
AOTFuncType *func_type = function->func_type;
|
||||
bool ret = wasm_runtime_invoke_native(function->func_ptr, func_type,
|
||||
exec_env, argv, argc, argv);
|
||||
bool ret = wasm_runtime_invoke_native(exec_env, function->func_ptr,
|
||||
func_type, NULL, argv, argc, argv);
|
||||
return ret && !aot_get_exception(module_inst) ? true : false;
|
||||
}
|
||||
|
||||
@ -612,11 +551,14 @@ aot_clear_exception(AOTModuleInstance *module_inst)
|
||||
}
|
||||
|
||||
int32
|
||||
aot_module_malloc(AOTModuleInstance *module_inst, uint32 size)
|
||||
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;
|
||||
if (!addr) {
|
||||
aot_set_exception(module_inst, "out of memory");
|
||||
return 0;
|
||||
@ -641,10 +583,11 @@ int32
|
||||
aot_module_dup_data(AOTModuleInstance *module_inst,
|
||||
const char *src, uint32 size)
|
||||
{
|
||||
int32 buffer_offset = aot_module_malloc(module_inst, size);
|
||||
char *buffer;
|
||||
int32 buffer_offset = aot_module_malloc(module_inst, size,
|
||||
(void**)&buffer);
|
||||
|
||||
if (buffer_offset != 0) {
|
||||
char *buffer;
|
||||
buffer = aot_addr_app_to_native(module_inst, buffer_offset);
|
||||
memcpy(buffer, src, size);
|
||||
}
|
||||
@ -858,3 +801,35 @@ aot_is_wasm_type_equal(AOTModuleInstance *module_inst,
|
||||
|
||||
return wasm_type_equal(type1, type2);
|
||||
}
|
||||
|
||||
void
|
||||
aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
|
||||
uint32 *frame_lp, uint32 argc, uint32 *argv_ret)
|
||||
{
|
||||
AOTModuleInstance *module_inst = (AOTModuleInstance*)
|
||||
wasm_runtime_get_module_inst(exec_env);
|
||||
AOTModule *aot_module = (AOTModule*)module_inst->aot_module.ptr;
|
||||
uint32 *func_type_indexes = (uint32*)module_inst->func_type_indexes.ptr;
|
||||
uint32 func_type_idx = func_type_indexes[func_idx];
|
||||
AOTFuncType *func_type = aot_module->func_types[func_type_idx];
|
||||
void **func_ptrs = (void**)module_inst->func_ptrs.ptr;
|
||||
void *func_ptr = func_ptrs[func_idx];
|
||||
AOTImportFunc *import_func;
|
||||
const char *signature = NULL;
|
||||
char buf[128];
|
||||
|
||||
if (func_idx < aot_module->import_func_count) {
|
||||
import_func = aot_module->import_funcs + func_idx;
|
||||
if (!func_ptr) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
"fail to call unlinked import function (%s, %s)",
|
||||
import_func->module_name, import_func->func_name);
|
||||
aot_set_exception(module_inst, buf);
|
||||
return;
|
||||
}
|
||||
signature = import_func->signature;
|
||||
}
|
||||
wasm_runtime_invoke_native(exec_env, func_ptr,
|
||||
func_type, signature, frame_lp, argc, argv_ret);
|
||||
}
|
||||
|
||||
|
||||
@ -141,7 +141,7 @@ typedef struct AOTModule {
|
||||
/* is jit mode or not */
|
||||
bool is_jit_mode;
|
||||
|
||||
#if WASM_ENABLE_JIT
|
||||
#if WASM_ENABLE_JIT != 0
|
||||
WASMModule *wasm_module;
|
||||
AOTCompContext *comp_ctx;
|
||||
AOTCompData *comp_data;
|
||||
@ -379,7 +379,8 @@ void
|
||||
aot_clear_exception(AOTModuleInstance *module_inst);
|
||||
|
||||
int32
|
||||
aot_module_malloc(AOTModuleInstance *module_inst, uint32 size);
|
||||
aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
|
||||
void **p_native_addr);
|
||||
|
||||
void
|
||||
aot_module_free(AOTModuleInstance *module_inst, int32 ptr);
|
||||
@ -431,6 +432,13 @@ bool
|
||||
aot_is_wasm_type_equal(AOTModuleInstance *module_inst,
|
||||
uint32 type1_idx, uint32 type2_idx);
|
||||
|
||||
/**
|
||||
* Invoke native function from aot code
|
||||
*/
|
||||
void
|
||||
aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
|
||||
uint32 *frame_lp, uint32 argc, uint32 *argv_ret);
|
||||
|
||||
uint32
|
||||
aot_get_plt_table_size();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user