mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-09-08 18:59:35 +00:00
Implement register/call native API with raw (unextracted) arguments (#222)
This commit is contained in:
parent
d9890d2ccb
commit
c1a0e6d877
|
@ -786,7 +786,9 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
if (!(import_funcs[i].func_ptr_linked =
|
if (!(import_funcs[i].func_ptr_linked =
|
||||||
wasm_native_resolve_symbol(module_name, field_name,
|
wasm_native_resolve_symbol(module_name, field_name,
|
||||||
import_funcs[i].func_type,
|
import_funcs[i].func_type,
|
||||||
&import_funcs[i].signature))) {
|
&import_funcs[i].signature,
|
||||||
|
&import_funcs[i].attachment,
|
||||||
|
&import_funcs[i].call_conv_raw))) {
|
||||||
LOG_WARNING("warning: fail to link import function (%s, %s)\n",
|
LOG_WARNING("warning: fail to link import function (%s, %s)\n",
|
||||||
module_name, field_name);
|
module_name, field_name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -457,7 +457,7 @@ aot_call_function(WASMExecEnv *exec_env,
|
||||||
AOTModuleInstance *module_inst = (AOTModuleInstance*)exec_env->module_inst;
|
AOTModuleInstance *module_inst = (AOTModuleInstance*)exec_env->module_inst;
|
||||||
AOTFuncType *func_type = function->func_type;
|
AOTFuncType *func_type = function->func_type;
|
||||||
bool ret = wasm_runtime_invoke_native(exec_env, function->func_ptr,
|
bool ret = wasm_runtime_invoke_native(exec_env, function->func_ptr,
|
||||||
func_type, NULL, argv, argc, argv);
|
func_type, NULL, NULL, argv, argc, argv);
|
||||||
return ret && !aot_get_exception(module_inst) ? true : false;
|
return ret && !aot_get_exception(module_inst) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,7 +824,8 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
|
||||||
void **func_ptrs = (void**)module_inst->func_ptrs.ptr;
|
void **func_ptrs = (void**)module_inst->func_ptrs.ptr;
|
||||||
void *func_ptr = func_ptrs[func_idx];
|
void *func_ptr = func_ptrs[func_idx];
|
||||||
AOTImportFunc *import_func;
|
AOTImportFunc *import_func;
|
||||||
const char *signature = NULL;
|
const char *signature;
|
||||||
|
void *attachment;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
bh_assert(func_idx < aot_module->import_func_count);
|
bh_assert(func_idx < aot_module->import_func_count);
|
||||||
|
@ -839,9 +840,17 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
|
||||||
}
|
}
|
||||||
|
|
||||||
signature = import_func->signature;
|
signature = import_func->signature;
|
||||||
return wasm_runtime_invoke_native(exec_env, func_ptr,
|
attachment = import_func->attachment;
|
||||||
func_type, signature,
|
if (!import_func->call_conv_raw) {
|
||||||
frame_lp, argc, argv_ret);
|
return wasm_runtime_invoke_native(exec_env, func_ptr,
|
||||||
|
func_type, signature, attachment,
|
||||||
|
frame_lp, argc, argv_ret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return wasm_runtime_invoke_native_raw(exec_env, func_ptr,
|
||||||
|
func_type, signature, attachment,
|
||||||
|
frame_lp, argc, argv_ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -860,6 +869,7 @@ aot_call_indirect(WASMExecEnv *exec_env,
|
||||||
uint32 func_idx, func_type_idx1;
|
uint32 func_idx, func_type_idx1;
|
||||||
AOTImportFunc *import_func;
|
AOTImportFunc *import_func;
|
||||||
const char *signature = NULL;
|
const char *signature = NULL;
|
||||||
|
void *attachment = NULL;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
if (table_elem_idx >= table_size) {
|
if (table_elem_idx >= table_size) {
|
||||||
|
@ -879,12 +889,6 @@ aot_call_indirect(WASMExecEnv *exec_env,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (func_idx < aot_module->import_func_count) {
|
|
||||||
/* Call native function */
|
|
||||||
import_func = aot_module->import_funcs + func_idx;
|
|
||||||
signature = import_func->signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(func_ptr = func_ptrs[func_idx])) {
|
if (!(func_ptr = func_ptrs[func_idx])) {
|
||||||
bh_assert(func_idx < aot_module->import_func_count);
|
bh_assert(func_idx < aot_module->import_func_count);
|
||||||
import_func = aot_module->import_funcs + func_idx;
|
import_func = aot_module->import_funcs + func_idx;
|
||||||
|
@ -895,8 +899,20 @@ aot_call_indirect(WASMExecEnv *exec_env,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (func_idx < aot_module->import_func_count) {
|
||||||
|
/* Call native function */
|
||||||
|
import_func = aot_module->import_funcs + func_idx;
|
||||||
|
signature = import_func->signature;
|
||||||
|
if (import_func->call_conv_raw) {
|
||||||
|
attachment = import_func->attachment;
|
||||||
|
return wasm_runtime_invoke_native_raw(exec_env, func_ptr,
|
||||||
|
func_type, signature, attachment,
|
||||||
|
frame_lp, argc, argv_ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return wasm_runtime_invoke_native(exec_env, func_ptr,
|
return wasm_runtime_invoke_native(exec_env, func_ptr,
|
||||||
func_type, signature,
|
func_type, signature, attachment,
|
||||||
frame_lp, argc, argv_ret);
|
frame_lp, argc, argv_ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,11 @@ typedef struct WASMExecEnv {
|
||||||
uint32 *argv_buf;
|
uint32 *argv_buf;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* attachment for native function */
|
||||||
|
void *attachment;
|
||||||
|
|
||||||
|
void *user_data;
|
||||||
|
|
||||||
/* Current interpreter frame of current thread */
|
/* Current interpreter frame of current thread */
|
||||||
struct WASMInterpFrame *cur_frame;
|
struct WASMInterpFrame *cur_frame;
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ sort_symbol_ptr(NativeSymbol *native_symbols, uint32 n_native_symbols)
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
|
lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
|
||||||
const char *symbol, const char **p_signature)
|
const char *symbol, const char **p_signature, void **p_attachment)
|
||||||
{
|
{
|
||||||
int low = 0, mid, ret;
|
int low = 0, mid, ret;
|
||||||
int high = n_native_symbols - 1;
|
int high = n_native_symbols - 1;
|
||||||
|
@ -120,6 +120,7 @@ lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
|
||||||
ret = strcmp(symbol, native_symbols[mid].symbol);
|
ret = strcmp(symbol, native_symbols[mid].symbol);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
*p_signature = native_symbols[mid].signature;
|
*p_signature = native_symbols[mid].signature;
|
||||||
|
*p_attachment = native_symbols[mid].attachment;
|
||||||
return native_symbols[mid].func_ptr;
|
return native_symbols[mid].func_ptr;
|
||||||
}
|
}
|
||||||
else if (ret < 0)
|
else if (ret < 0)
|
||||||
|
@ -133,11 +134,12 @@ lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
|
||||||
|
|
||||||
void*
|
void*
|
||||||
wasm_native_resolve_symbol(const char *module_name, const char *field_name,
|
wasm_native_resolve_symbol(const char *module_name, const char *field_name,
|
||||||
const WASMType *func_type, const char **p_signature)
|
const WASMType *func_type, const char **p_signature,
|
||||||
|
void **p_attachment, bool *p_call_conv_raw)
|
||||||
{
|
{
|
||||||
NativeSymbolsNode *node, *node_next;
|
NativeSymbolsNode *node, *node_next;
|
||||||
const char *signature = NULL;
|
const char *signature = NULL;
|
||||||
void *func_ptr = NULL;
|
void *func_ptr = NULL, *attachment;
|
||||||
|
|
||||||
node = g_native_symbols_list;
|
node = g_native_symbols_list;
|
||||||
while (node) {
|
while (node) {
|
||||||
|
@ -145,11 +147,12 @@ wasm_native_resolve_symbol(const char *module_name, const char *field_name,
|
||||||
if (!strcmp(node->module_name, module_name)) {
|
if (!strcmp(node->module_name, module_name)) {
|
||||||
if ((func_ptr = lookup_symbol(node->native_symbols,
|
if ((func_ptr = lookup_symbol(node->native_symbols,
|
||||||
node->n_native_symbols,
|
node->n_native_symbols,
|
||||||
field_name, &signature))
|
field_name, &signature, &attachment))
|
||||||
|| (field_name[0] == '_'
|
|| (field_name[0] == '_'
|
||||||
&& (func_ptr = lookup_symbol(node->native_symbols,
|
&& (func_ptr = lookup_symbol(node->native_symbols,
|
||||||
node->n_native_symbols,
|
node->n_native_symbols,
|
||||||
field_name + 1, &signature))))
|
field_name + 1,
|
||||||
|
&signature, &attachment))))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
node = node_next;
|
node = node_next;
|
||||||
|
@ -172,15 +175,19 @@ wasm_native_resolve_symbol(const char *module_name, const char *field_name,
|
||||||
else
|
else
|
||||||
/* signature is empty */
|
/* signature is empty */
|
||||||
*p_signature = NULL;
|
*p_signature = NULL;
|
||||||
|
|
||||||
|
*p_attachment = attachment;
|
||||||
|
*p_call_conv_raw = node->call_conv_raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return func_ptr;
|
return func_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static bool
|
||||||
wasm_native_register_natives(const char *module_name,
|
register_natives(const char *module_name,
|
||||||
NativeSymbol *native_symbols,
|
NativeSymbol *native_symbols,
|
||||||
uint32 n_native_symbols)
|
uint32 n_native_symbols,
|
||||||
|
bool call_conv_raw)
|
||||||
{
|
{
|
||||||
NativeSymbolsNode *node;
|
NativeSymbolsNode *node;
|
||||||
|
|
||||||
|
@ -190,6 +197,7 @@ wasm_native_register_natives(const char *module_name,
|
||||||
node->module_name = module_name;
|
node->module_name = module_name;
|
||||||
node->native_symbols = native_symbols;
|
node->native_symbols = native_symbols;
|
||||||
node->n_native_symbols = n_native_symbols;
|
node->n_native_symbols = n_native_symbols;
|
||||||
|
node->call_conv_raw = call_conv_raw;
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
|
|
||||||
if (g_native_symbols_list_end) {
|
if (g_native_symbols_list_end) {
|
||||||
|
@ -204,6 +212,22 @@ wasm_native_register_natives(const char *module_name,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_native_register_natives(const char *module_name,
|
||||||
|
NativeSymbol *native_symbols,
|
||||||
|
uint32 n_native_symbols)
|
||||||
|
{
|
||||||
|
return register_natives(module_name, native_symbols, n_native_symbols, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_native_register_natives_raw(const char *module_name,
|
||||||
|
NativeSymbol *native_symbols,
|
||||||
|
uint32 n_native_symbols)
|
||||||
|
{
|
||||||
|
return register_natives(module_name, native_symbols, n_native_symbols, true);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_native_init()
|
wasm_native_init()
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,7 @@ typedef struct NativeSymbolsNode {
|
||||||
const char *module_name;
|
const char *module_name;
|
||||||
NativeSymbol *native_symbols;
|
NativeSymbol *native_symbols;
|
||||||
uint32 n_native_symbols;
|
uint32 n_native_symbols;
|
||||||
|
bool call_conv_raw;
|
||||||
} NativeSymbolsNode, *NativeSymbolsList;
|
} NativeSymbolsNode, *NativeSymbolsList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,13 +51,19 @@ wasm_native_lookup_libc_builtin_global(const char *module_name,
|
||||||
*/
|
*/
|
||||||
void*
|
void*
|
||||||
wasm_native_resolve_symbol(const char *module_name, const char *field_name,
|
wasm_native_resolve_symbol(const char *module_name, const char *field_name,
|
||||||
const WASMType *func_type, const char **p_signature);
|
const WASMType *func_type, const char **p_signature,
|
||||||
|
void **p_attachment, bool *p_call_conv_raw);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_native_register_natives(const char *module_name,
|
wasm_native_register_natives(const char *module_name,
|
||||||
NativeSymbol *native_symbols,
|
NativeSymbol *native_symbols,
|
||||||
uint32 n_native_symbols);
|
uint32 n_native_symbols);
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_native_register_natives_raw(const char *module_name,
|
||||||
|
NativeSymbol *native_symbols,
|
||||||
|
uint32 n_native_symbols);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_native_init();
|
wasm_native_init();
|
||||||
|
|
||||||
|
|
|
@ -233,6 +233,24 @@ wasm_runtime_get_module_inst(WASMExecEnv *exec_env)
|
||||||
return wasm_exec_env_get_module_inst(exec_env);
|
return wasm_exec_env_get_module_inst(exec_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
wasm_runtime_get_function_attachment(WASMExecEnv *exec_env)
|
||||||
|
{
|
||||||
|
return exec_env->attachment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data)
|
||||||
|
{
|
||||||
|
exec_env->user_data = user_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
wasm_runtime_get_user_data(WASMExecEnv *exec_env)
|
||||||
|
{
|
||||||
|
return exec_env->user_data;
|
||||||
|
}
|
||||||
|
|
||||||
WASMFunctionInstanceCommon *
|
WASMFunctionInstanceCommon *
|
||||||
wasm_runtime_lookup_function(WASMModuleInstanceCommon * const module_inst,
|
wasm_runtime_lookup_function(WASMModuleInstanceCommon * const module_inst,
|
||||||
const char *name,
|
const char *name,
|
||||||
|
@ -1421,6 +1439,120 @@ wasm_runtime_register_natives(const char *module_name,
|
||||||
native_symbols, n_native_symbols);
|
native_symbols, n_native_symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_runtime_register_natives_raw(const char *module_name,
|
||||||
|
NativeSymbol *native_symbols,
|
||||||
|
uint32 n_native_symbols)
|
||||||
|
{
|
||||||
|
return wasm_native_register_natives_raw(module_name,
|
||||||
|
native_symbols, n_native_symbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
|
const WASMType *func_type, const char *signature,
|
||||||
|
void *attachment,
|
||||||
|
uint32 *argv, uint32 argc, uint32 *argv_ret)
|
||||||
|
{
|
||||||
|
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
|
||||||
|
typedef void (*NativeRawFuncPtr)(WASMExecEnv*, uint64*);
|
||||||
|
NativeRawFuncPtr invokeNativeRaw = (NativeRawFuncPtr)func_ptr;
|
||||||
|
uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size;
|
||||||
|
uint32 *argv_src = argv, i, argc1, ptr_len;
|
||||||
|
int32 arg_i32;
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
argc1 = func_type->param_count;
|
||||||
|
if (argc1 > sizeof(argv_buf) / sizeof(uint64)) {
|
||||||
|
size = sizeof(uint64) * (uint64)argc1;
|
||||||
|
if (size >= UINT32_MAX
|
||||||
|
|| !(argv1 = wasm_runtime_malloc((uint32)size))) {
|
||||||
|
wasm_runtime_set_exception(exec_env->module_inst,
|
||||||
|
"allocate memory failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset(argv1, 0, (uint32)size);
|
||||||
|
}
|
||||||
|
|
||||||
|
argv_dst = argv1;
|
||||||
|
|
||||||
|
/* Traverse secondly to fill in each argument */
|
||||||
|
for (i = 0; i < func_type->param_count; i++, argv_dst++) {
|
||||||
|
switch (func_type->types[i]) {
|
||||||
|
case VALUE_TYPE_I32:
|
||||||
|
{
|
||||||
|
*(int32*)argv_dst = arg_i32 = (int32)*argv_src++;
|
||||||
|
if (signature) {
|
||||||
|
if (signature[i + 1] == '*') {
|
||||||
|
/* param is a pointer */
|
||||||
|
if (signature[i + 2] == '~')
|
||||||
|
/* pointer with length followed */
|
||||||
|
ptr_len = *argv_src;
|
||||||
|
else
|
||||||
|
/* pointer without length followed */
|
||||||
|
ptr_len = 1;
|
||||||
|
|
||||||
|
if (!wasm_runtime_validate_app_addr(module, arg_i32, ptr_len))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
*(uintptr_t*)argv_dst = (uintptr_t)
|
||||||
|
wasm_runtime_addr_app_to_native(module, arg_i32);
|
||||||
|
}
|
||||||
|
else if (signature[i + 1] == '$') {
|
||||||
|
/* param is a string */
|
||||||
|
if (!wasm_runtime_validate_app_str_addr(module, arg_i32))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
*(uintptr_t*)argv_dst = (uintptr_t)
|
||||||
|
wasm_runtime_addr_app_to_native(module, arg_i32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VALUE_TYPE_I64:
|
||||||
|
case VALUE_TYPE_F64:
|
||||||
|
bh_memcpy_s(argv_dst, sizeof(uint64), argv_src, sizeof(uint32) * 2);
|
||||||
|
argv_src += 2;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_F32:
|
||||||
|
*(float32*)argv_dst = *(float32*)argv_src++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bh_assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exec_env->attachment = attachment;
|
||||||
|
invokeNativeRaw(exec_env, argv1);
|
||||||
|
exec_env->attachment = NULL;
|
||||||
|
|
||||||
|
if (func_type->result_count > 0) {
|
||||||
|
switch (func_type->types[func_type->param_count]) {
|
||||||
|
case VALUE_TYPE_I32:
|
||||||
|
argv_ret[0] = *(uint32*)argv1;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_F32:
|
||||||
|
*(float32*)argv_ret = *(float32*)argv1;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_I64:
|
||||||
|
case VALUE_TYPE_F64:
|
||||||
|
bh_memcpy_s(argv_ret, sizeof(uint32) * 2, argv1, sizeof(uint64));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bh_assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (argv1 != argv_buf)
|
||||||
|
wasm_runtime_free(argv1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of wasm_runtime_invoke_native()
|
* Implementation of wasm_runtime_invoke_native()
|
||||||
*/
|
*/
|
||||||
|
@ -1469,6 +1601,7 @@ static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
|
||||||
bool
|
bool
|
||||||
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
const WASMType *func_type, const char *signature,
|
const WASMType *func_type, const char *signature,
|
||||||
|
void *attachment,
|
||||||
uint32 *argv, uint32 argc, uint32 *argv_ret)
|
uint32 *argv, uint32 argc, uint32 *argv_ret)
|
||||||
{
|
{
|
||||||
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
|
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
|
||||||
|
@ -1634,6 +1767,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exec_env->attachment = attachment;
|
||||||
if (func_type->result_count == 0) {
|
if (func_type->result_count == 0) {
|
||||||
invokeNative_Void(func_ptr, argv1, n_stacks);
|
invokeNative_Void(func_ptr, argv1, n_stacks);
|
||||||
}
|
}
|
||||||
|
@ -1656,6 +1790,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
exec_env->attachment = NULL;
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
|
@ -1689,6 +1824,7 @@ static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
|
||||||
bool
|
bool
|
||||||
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
const WASMType *func_type, const char *signature,
|
const WASMType *func_type, const char *signature,
|
||||||
|
void *attachment,
|
||||||
uint32 *argv, uint32 argc, uint32 *argv_ret)
|
uint32 *argv, uint32 argc, uint32 *argv_ret)
|
||||||
{
|
{
|
||||||
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
|
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
|
||||||
|
@ -1774,6 +1910,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
argc1 = j;
|
argc1 = j;
|
||||||
|
exec_env->attachment = attachment;
|
||||||
if (func_type->result_count == 0) {
|
if (func_type->result_count == 0) {
|
||||||
invokeNative_Void(func_ptr, argv1, argc1);
|
invokeNative_Void(func_ptr, argv1, argc1);
|
||||||
}
|
}
|
||||||
|
@ -1796,6 +1933,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
exec_env->attachment = NULL;
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
|
@ -1844,6 +1982,7 @@ static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)(uintptr_t)invokeNative;
|
||||||
bool
|
bool
|
||||||
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
const WASMType *func_type, const char *signature,
|
const WASMType *func_type, const char *signature,
|
||||||
|
void *attachment,
|
||||||
uint32 *argv, uint32 argc, uint32 *argv_ret)
|
uint32 *argv, uint32 argc, uint32 *argv_ret)
|
||||||
{
|
{
|
||||||
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
|
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
|
||||||
|
@ -1938,6 +2077,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exec_env->attachment = attachment;
|
||||||
if (func_type->result_count == 0) {
|
if (func_type->result_count == 0) {
|
||||||
invokeNative_Void(func_ptr, argv1, n_stacks);
|
invokeNative_Void(func_ptr, argv1, n_stacks);
|
||||||
}
|
}
|
||||||
|
@ -1960,6 +2100,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
exec_env->attachment = NULL;
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
fail:
|
fail:
|
||||||
|
|
|
@ -113,6 +113,18 @@ wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env);
|
||||||
WASMModuleInstanceCommon *
|
WASMModuleInstanceCommon *
|
||||||
wasm_runtime_get_module_inst(WASMExecEnv *exec_env);
|
wasm_runtime_get_module_inst(WASMExecEnv *exec_env);
|
||||||
|
|
||||||
|
/* See wasm_export.h for description */
|
||||||
|
void *
|
||||||
|
wasm_runtime_get_function_attachment(wasm_exec_env_t exec_env);
|
||||||
|
|
||||||
|
/* See wasm_export.h for description */
|
||||||
|
void
|
||||||
|
wasm_runtime_set_user_data(wasm_exec_env_t exec_env, void *user_data);
|
||||||
|
|
||||||
|
/* See wasm_export.h for description */
|
||||||
|
void *
|
||||||
|
wasm_runtime_get_user_data(wasm_exec_env_t exec_env);
|
||||||
|
|
||||||
/* See wasm_export.h for description */
|
/* See wasm_export.h for description */
|
||||||
bool
|
bool
|
||||||
wasm_runtime_call_wasm(WASMExecEnv *exec_env,
|
wasm_runtime_call_wasm(WASMExecEnv *exec_env,
|
||||||
|
@ -275,11 +287,24 @@ wasm_runtime_register_natives(const char *module_name,
|
||||||
NativeSymbol *native_symbols,
|
NativeSymbol *native_symbols,
|
||||||
uint32 n_native_symbols);
|
uint32 n_native_symbols);
|
||||||
|
|
||||||
|
/* See wasm_export.h for description */
|
||||||
|
bool
|
||||||
|
wasm_runtime_register_natives_raw(const char *module_name,
|
||||||
|
NativeSymbol *native_symbols,
|
||||||
|
uint32 n_native_symbols);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
const WASMType *func_type, const char *signature,
|
const WASMType *func_type, const char *signature,
|
||||||
|
void *attachment,
|
||||||
uint32 *argv, uint32 argc, uint32 *ret);
|
uint32 *argv, uint32 argc, uint32 *ret);
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
|
const WASMType *func_type, const char *signature,
|
||||||
|
void *attachment,
|
||||||
|
uint32 *argv, uint32 argc, uint32 *ret);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,6 +265,8 @@ aot_create_import_funcs(const WASMModule *module)
|
||||||
import_funcs[i].func_ptr_linked = import_func->func_ptr_linked;
|
import_funcs[i].func_ptr_linked = import_func->func_ptr_linked;
|
||||||
import_funcs[i].func_type = import_func->func_type;
|
import_funcs[i].func_type = import_func->func_type;
|
||||||
import_funcs[i].signature = import_func->signature;
|
import_funcs[i].signature = import_func->signature;
|
||||||
|
import_funcs[i].attachment = import_func->attachment;
|
||||||
|
import_funcs[i].call_conv_raw = import_func->call_conv_raw;
|
||||||
/* Resolve function type index */
|
/* Resolve function type index */
|
||||||
for (j = 0; j < module->type_count; j++)
|
for (j = 0; j < module->type_count; j++)
|
||||||
if (import_func->func_type == module->types[j]) {
|
if (import_func->func_type == module->types[j]) {
|
||||||
|
|
|
@ -85,6 +85,9 @@ typedef struct AOTImportFunc {
|
||||||
void *func_ptr_linked;
|
void *func_ptr_linked;
|
||||||
/* signature from registered native symbols */
|
/* signature from registered native symbols */
|
||||||
const char *signature;
|
const char *signature;
|
||||||
|
/* attachment */
|
||||||
|
void *attachment;
|
||||||
|
bool call_conv_raw;
|
||||||
} AOTImportFunc;
|
} AOTImportFunc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,15 +16,23 @@ typedef struct NativeSymbol {
|
||||||
const char *symbol;
|
const char *symbol;
|
||||||
void *func_ptr;
|
void *func_ptr;
|
||||||
const char *signature;
|
const char *signature;
|
||||||
|
/* attachment which can be retrieved in native API by
|
||||||
|
calling wasm_runtime_get_function_attachment(exec_env) */
|
||||||
|
void *attachment;
|
||||||
} NativeSymbol;
|
} NativeSymbol;
|
||||||
|
|
||||||
#define EXPORT_WASM_API(symbol) {#symbol, (void*)symbol, NULL}
|
#define EXPORT_WASM_API(symbol) {#symbol, (void*)symbol, NULL, NULL}
|
||||||
#define EXPORT_WASM_API2(symbol) {#symbol, (void*)symbol##_wrapper, NULL}
|
#define EXPORT_WASM_API2(symbol) {#symbol, (void*)symbol##_wrapper, NULL, NULL}
|
||||||
|
|
||||||
#define EXPORT_WASM_API_WITH_SIG(symbol, signature) \
|
#define EXPORT_WASM_API_WITH_SIG(symbol, signature) \
|
||||||
{#symbol, (void*)symbol, signature}
|
{#symbol, (void*)symbol, signature, NULL}
|
||||||
#define EXPORT_WASM_API_WITH_SIG2(symbol, signature) \
|
#define EXPORT_WASM_API_WITH_SIG2(symbol, signature) \
|
||||||
{#symbol, (void*)symbol##_wrapper, signature}
|
{#symbol, (void*)symbol##_wrapper, signature, NULL}
|
||||||
|
|
||||||
|
#define EXPORT_WASM_API_WITH_ATT(symbol, signature, attachment) \
|
||||||
|
{#symbol, (void*)symbol, signature, attachment}
|
||||||
|
#define EXPORT_WASM_API_WITH_ATT2(symbol, signature, attachment) \
|
||||||
|
{#symbol, (void*)symbol##_wrapper, signature, attachment}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the exported APIs of base lib
|
* Get the exported APIs of base lib
|
||||||
|
|
|
@ -36,6 +36,11 @@ extern "C" {
|
||||||
#define module_free(offset) \
|
#define module_free(offset) \
|
||||||
wasm_runtime_module_free(module_inst, offset)
|
wasm_runtime_module_free(module_inst, offset)
|
||||||
|
|
||||||
|
#define native_raw_return_type(type, args) type *raw_ret = (type*)(args)
|
||||||
|
|
||||||
|
#define native_raw_get_arg(type, name, args) type name = *((type*)(args++))
|
||||||
|
|
||||||
|
#define native_raw_set_return(val) *raw_ret = (val)
|
||||||
|
|
||||||
|
|
||||||
/* Uninstantiated WASM module loaded from WASM binary file
|
/* Uninstantiated WASM module loaded from WASM binary file
|
||||||
|
@ -561,6 +566,49 @@ bool wasm_runtime_register_natives(const char *module_name,
|
||||||
NativeSymbol *native_symbols,
|
NativeSymbol *native_symbols,
|
||||||
uint32_t n_native_symbols);
|
uint32_t n_native_symbols);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register native functions with same module name, similar to
|
||||||
|
* wasm_runtime_register_natives, the difference is that runtime passes raw
|
||||||
|
* arguments to native API, which means that the native API should be defined as:
|
||||||
|
* void foo(wasm_exec_env_t exec_env, uint64 *args);
|
||||||
|
* and native API should extract arguments one by one from args array with macro
|
||||||
|
* native_raw_get_arg
|
||||||
|
* and write the return value back to args[0] with macro
|
||||||
|
* native_raw_return_type and native_raw_set_return
|
||||||
|
*/
|
||||||
|
bool wasm_runtime_register_natives_raw(const char *module_name,
|
||||||
|
NativeSymbol *native_symbols,
|
||||||
|
uint32_t n_native_symbols);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get attachment of native function from execution environment
|
||||||
|
*
|
||||||
|
* @param exec_env the execution environment to retrieve
|
||||||
|
*
|
||||||
|
* @return the attachment of native function
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
wasm_runtime_get_function_attachment(wasm_exec_env_t exec_env);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set user data to execution environment.
|
||||||
|
*
|
||||||
|
* @param exec_env the execution environment
|
||||||
|
* @param user_data the user data to be set
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
wasm_runtime_set_user_data(wasm_exec_env_t exec_env,
|
||||||
|
void *user_data);
|
||||||
|
/**
|
||||||
|
* Get the user data within execution environment.
|
||||||
|
*
|
||||||
|
* @param exec_env the execution environment
|
||||||
|
*
|
||||||
|
* @return the user data (NULL if not set yet)
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
wasm_runtime_get_user_data(wasm_exec_env_t exec_env);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -137,8 +137,11 @@ typedef struct WASMFunctionImport {
|
||||||
WASMType *func_type;
|
WASMType *func_type;
|
||||||
/* function pointer after linked */
|
/* function pointer after linked */
|
||||||
void *func_ptr_linked;
|
void *func_ptr_linked;
|
||||||
/* signature from registered native symbols */
|
/* signature from registered native symbols */
|
||||||
const char *signature;
|
const char *signature;
|
||||||
|
/* attachment */
|
||||||
|
void *attachment;
|
||||||
|
bool call_conv_raw;
|
||||||
} WASMFunctionImport;
|
} WASMFunctionImport;
|
||||||
|
|
||||||
typedef struct WASMGlobalImport {
|
typedef struct WASMGlobalImport {
|
||||||
|
|
|
@ -748,9 +748,18 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = wasm_runtime_invoke_native(exec_env, func_import->func_ptr_linked,
|
if (!func_import->call_conv_raw) {
|
||||||
func_import->func_type, func_import->signature,
|
ret = wasm_runtime_invoke_native(exec_env, func_import->func_ptr_linked,
|
||||||
frame->lp, cur_func->param_cell_num, argv_ret);
|
func_import->func_type, func_import->signature,
|
||||||
|
func_import->attachment,
|
||||||
|
frame->lp, cur_func->param_cell_num, argv_ret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = wasm_runtime_invoke_native_raw(exec_env, func_import->func_ptr_linked,
|
||||||
|
func_import->func_type, func_import->signature,
|
||||||
|
func_import->attachment,
|
||||||
|
frame->lp, cur_func->param_cell_num, argv_ret);
|
||||||
|
}
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -651,6 +651,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
|
||||||
WASMFunctionInstance *cur_func,
|
WASMFunctionInstance *cur_func,
|
||||||
WASMInterpFrame *prev_frame)
|
WASMInterpFrame *prev_frame)
|
||||||
{
|
{
|
||||||
|
WASMFunctionImport *func_import = cur_func->u.func_import;
|
||||||
unsigned local_cell_num = 2;
|
unsigned local_cell_num = 2;
|
||||||
WASMInterpFrame *frame;
|
WASMInterpFrame *frame;
|
||||||
uint32 argv_ret[2];
|
uint32 argv_ret[2];
|
||||||
|
@ -667,20 +668,27 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
|
||||||
|
|
||||||
wasm_exec_env_set_cur_frame(exec_env, frame);
|
wasm_exec_env_set_cur_frame(exec_env, frame);
|
||||||
|
|
||||||
if (!cur_func->u.func_import->func_ptr_linked) {
|
if (!func_import->func_ptr_linked) {
|
||||||
char buf[128];
|
char buf[128];
|
||||||
snprintf(buf,
|
snprintf(buf,
|
||||||
sizeof(buf), "fail to call unlinked import function (%s, %s)",
|
sizeof(buf), "fail to call unlinked import function (%s, %s)",
|
||||||
cur_func->u.func_import->module_name,
|
func_import->module_name, func_import->field_name);
|
||||||
cur_func->u.func_import->field_name);
|
|
||||||
wasm_set_exception((WASMModuleInstance*)module_inst, buf);
|
wasm_set_exception((WASMModuleInstance*)module_inst, buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = wasm_runtime_invoke_native(exec_env, cur_func->u.func_import->func_ptr_linked,
|
if (!func_import->call_conv_raw) {
|
||||||
cur_func->u.func_import->func_type,
|
ret = wasm_runtime_invoke_native(exec_env, func_import->func_ptr_linked,
|
||||||
cur_func->u.func_import->signature,
|
func_import->func_type, func_import->signature,
|
||||||
frame->lp, cur_func->param_cell_num, argv_ret);
|
func_import->attachment,
|
||||||
|
frame->lp, cur_func->param_cell_num, argv_ret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = wasm_runtime_invoke_native_raw(exec_env, func_import->func_ptr_linked,
|
||||||
|
func_import->func_type, func_import->signature,
|
||||||
|
func_import->attachment,
|
||||||
|
frame->lp, cur_func->param_cell_num, argv_ret);
|
||||||
|
}
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -721,7 +721,9 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
if (!(import->u.function.func_ptr_linked =
|
if (!(import->u.function.func_ptr_linked =
|
||||||
wasm_native_resolve_symbol(module_name, field_name,
|
wasm_native_resolve_symbol(module_name, field_name,
|
||||||
import->u.function.func_type,
|
import->u.function.func_type,
|
||||||
&import->u.function.signature))) {
|
&import->u.function.signature,
|
||||||
|
&import->u.function.attachment,
|
||||||
|
&import->u.function.call_conv_raw))) {
|
||||||
#if WASM_ENABLE_WAMR_COMPILER == 0 /* Output warning except running aot compiler */
|
#if WASM_ENABLE_WAMR_COMPILER == 0 /* Output warning except running aot compiler */
|
||||||
LOG_WARNING("warning: fail to link import function (%s, %s)\n",
|
LOG_WARNING("warning: fail to link import function (%s, %s)\n",
|
||||||
module_name, field_name);
|
module_name, field_name);
|
||||||
|
|
|
@ -1000,7 +1000,7 @@ print_i32_wrapper(wasm_exec_env_t exec_env, int32 i32)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||||
{ #func_name, func_name##_wrapper, signature }
|
{ #func_name, func_name##_wrapper, signature, NULL }
|
||||||
|
|
||||||
static NativeSymbol native_symbols_libc_builtin[] = {
|
static NativeSymbol native_symbols_libc_builtin[] = {
|
||||||
REG_NATIVE_FUNC(printf, "($*)i"),
|
REG_NATIVE_FUNC(printf, "($*)i"),
|
||||||
|
|
|
@ -982,7 +982,7 @@ wasi_sched_yield(wasm_exec_env_t exec_env)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||||
{ #func_name, wasi_##func_name, signature }
|
{ #func_name, wasi_##func_name, signature, NULL }
|
||||||
|
|
||||||
static NativeSymbol native_symbols_libc_wasi[] = {
|
static NativeSymbol native_symbols_libc_wasi[] = {
|
||||||
REG_NATIVE_FUNC(args_get, "(**)i"),
|
REG_NATIVE_FUNC(args_get, "(**)i"),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user