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:
@ -137,6 +137,8 @@ typedef struct WASMFunctionImport {
|
||||
WASMType *func_type;
|
||||
/* function pointer after linked */
|
||||
void *func_ptr_linked;
|
||||
/* signature from registered native symbols */
|
||||
const char *signature;
|
||||
} WASMFunctionImport;
|
||||
|
||||
typedef struct WASMGlobalImport {
|
||||
@ -288,8 +290,7 @@ typedef struct WASMModule {
|
||||
auxiliary stack top pointer */
|
||||
uint32 llvm_aux_stack_global_index;
|
||||
|
||||
/* Whether there is possible memory grow, e.g.
|
||||
memory.grow opcode or call enlargeMemory */
|
||||
/* Whether there is possible memory grow, e.g. memory.grow opcode */
|
||||
bool possible_memory_grow;
|
||||
|
||||
StringList const_str_list;
|
||||
|
||||
@ -726,9 +726,11 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
|
||||
WASMFunctionInstance *cur_func,
|
||||
WASMInterpFrame *prev_frame)
|
||||
{
|
||||
WASMFunctionImport *func_import = cur_func->u.func_import;
|
||||
unsigned local_cell_num = 2;
|
||||
WASMInterpFrame *frame;
|
||||
uint32 argv_ret[2];
|
||||
char buf[128];
|
||||
bool ret;
|
||||
|
||||
if (!(frame = ALLOC_FRAME(exec_env,
|
||||
@ -742,19 +744,16 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
|
||||
|
||||
wasm_exec_env_set_cur_frame(exec_env, frame);
|
||||
|
||||
if (!cur_func->u.func_import->func_ptr_linked) {
|
||||
char buf[128];
|
||||
snprintf(buf,
|
||||
sizeof(buf), "fail to call unlinked import function (%s, %s)",
|
||||
cur_func->u.func_import->module_name,
|
||||
cur_func->u.func_import->field_name);
|
||||
wasm_set_exception((WASMModuleInstance*)module_inst, buf);
|
||||
if (!func_import->func_ptr_linked) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
"fail to call unlinked import function (%s, %s)",
|
||||
func_import->module_name, func_import->field_name);
|
||||
wasm_set_exception(module_inst, buf);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = wasm_runtime_invoke_native(cur_func->u.func_import->func_ptr_linked,
|
||||
cur_func->u.func_import->func_type,
|
||||
exec_env,
|
||||
ret = wasm_runtime_invoke_native(exec_env, func_import->func_ptr_linked,
|
||||
func_import->func_type, func_import->signature,
|
||||
frame->lp, cur_func->param_cell_num, argv_ret);
|
||||
|
||||
if (!ret)
|
||||
|
||||
@ -556,36 +556,6 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory,
|
||||
return true;
|
||||
}
|
||||
|
||||
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_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
@ -737,13 +707,10 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
}
|
||||
import->u.function.func_type = module->types[type_index];
|
||||
|
||||
if (!module->possible_memory_grow
|
||||
&& !strcmp(module_name, "env")
|
||||
&& !(strcmp(field_name, "enlargeMemory")))
|
||||
module->possible_memory_grow = true;
|
||||
|
||||
if (!(import->u.function.func_ptr_linked =
|
||||
resolve_sym(module_name, field_name))) {
|
||||
wasm_native_resolve_symbol(module_name, field_name,
|
||||
import->u.function.func_type,
|
||||
&import->u.function.signature))) {
|
||||
#if WASM_ENABLE_WAMR_COMPILER == 0 /* Output warning except running aot compiler */
|
||||
LOG_WARNING("warning: fail to link import function (%s, %s)\n",
|
||||
module_name, field_name);
|
||||
@ -3016,7 +2983,8 @@ handle_next_reachable_block:
|
||||
POP_TYPE(func_type->types[idx]);
|
||||
}
|
||||
|
||||
PUSH_TYPE(func_type->types[func_type->param_count]);
|
||||
if (func_type->result_count > 0)
|
||||
PUSH_TYPE(func_type->types[func_type->param_count]);
|
||||
|
||||
func->has_op_func_call = true;
|
||||
break;
|
||||
|
||||
@ -849,75 +849,15 @@ wasm_deinstantiate(WASMModuleInstance *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;
|
||||
}
|
||||
|
||||
WASMFunctionInstance*
|
||||
wasm_lookup_function(const WASMModuleInstance *module_inst,
|
||||
const char *name, const char *signature)
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < module_inst->export_func_count; i++)
|
||||
if (!strcmp(module_inst->export_functions[i].name, name)
|
||||
&& check_function_type(
|
||||
module_inst->export_functions[i].function->u.func->func_type,
|
||||
signature))
|
||||
if (!strcmp(module_inst->export_functions[i].name, name))
|
||||
return module_inst->export_functions[i].function;
|
||||
(void)signature;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -972,10 +912,13 @@ wasm_get_exception(WASMModuleInstance *module_inst)
|
||||
}
|
||||
|
||||
int32
|
||||
wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size)
|
||||
wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
|
||||
void **p_native_addr)
|
||||
{
|
||||
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;
|
||||
@ -998,9 +941,10 @@ int32
|
||||
wasm_module_dup_data(WASMModuleInstance *module_inst,
|
||||
const char *src, uint32 size)
|
||||
{
|
||||
int32 buffer_offset = wasm_module_malloc(module_inst, size);
|
||||
char *buffer;
|
||||
int32 buffer_offset = wasm_module_malloc(module_inst, size,
|
||||
(void**)&buffer);
|
||||
if (buffer_offset != 0) {
|
||||
char *buffer;
|
||||
buffer = wasm_addr_app_to_native(module_inst, buffer_offset);
|
||||
bh_memcpy_s(buffer, size, src, size);
|
||||
}
|
||||
|
||||
@ -222,7 +222,8 @@ const char*
|
||||
wasm_get_exception(WASMModuleInstance *module);
|
||||
|
||||
int32
|
||||
wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size);
|
||||
wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
|
||||
void **p_native_addr);
|
||||
|
||||
void
|
||||
wasm_module_free(WASMModuleInstance *module_inst, int32 ptr);
|
||||
|
||||
Reference in New Issue
Block a user