mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-08 20:56:13 +00:00
Refine the wasm-c-api native func call process of aot mode (#640)
This commit is contained in:
parent
1b34606940
commit
ba922b0d0d
|
@ -13,6 +13,7 @@
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
#include "../libraries/thread-mgr/thread_manager.h"
|
#include "../libraries/thread-mgr/thread_manager.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "../common/wasm_c_api_internal.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
|
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
|
||||||
|
@ -1097,6 +1098,18 @@ fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
aot_create_exec_env_singleton(AOTModuleInstance *module_inst)
|
||||||
|
{
|
||||||
|
WASMExecEnv *exec_env =
|
||||||
|
wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
|
||||||
|
module_inst->default_wasm_stack_size);
|
||||||
|
if (exec_env)
|
||||||
|
module_inst->exec_env_singleton.ptr = exec_env;
|
||||||
|
|
||||||
|
return exec_env ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
|
aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
|
||||||
{
|
{
|
||||||
|
@ -1127,6 +1140,10 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
|
||||||
if (module_inst->func_type_indexes.ptr)
|
if (module_inst->func_type_indexes.ptr)
|
||||||
wasm_runtime_free(module_inst->func_type_indexes.ptr);
|
wasm_runtime_free(module_inst->func_type_indexes.ptr);
|
||||||
|
|
||||||
|
if (module_inst->exec_env_singleton.ptr)
|
||||||
|
wasm_exec_env_destroy((WASMExecEnv *)
|
||||||
|
module_inst->exec_env_singleton.ptr);
|
||||||
|
|
||||||
wasm_runtime_free(module_inst);
|
wasm_runtime_free(module_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1287,6 +1304,9 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
|
WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
|
||||||
uint32 page_size = os_getpagesize();
|
uint32 page_size = os_getpagesize();
|
||||||
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
||||||
|
uint16 param_count = func_type->param_count;
|
||||||
|
uint16 result_count = func_type->result_count;
|
||||||
|
const uint8 *types = func_type->types;
|
||||||
#if BH_PLATFORM_WINDOWS
|
#if BH_PLATFORM_WINDOWS
|
||||||
const char *exce;
|
const char *exce;
|
||||||
int result;
|
int result;
|
||||||
|
@ -1316,9 +1336,31 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
|
|
||||||
aot_exec_env = exec_env;
|
aot_exec_env = exec_env;
|
||||||
if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
|
if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
|
||||||
ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
|
/* Quick call with func_ptr if the function signature is simple */
|
||||||
signature, attachment,
|
if (!signature && param_count == 1 && types[0] == VALUE_TYPE_I32) {
|
||||||
argv, argc, argv_ret);
|
if (result_count == 0) {
|
||||||
|
void (*NativeFunc)(WASMExecEnv*, uint32) =
|
||||||
|
(void (*)(WASMExecEnv*, uint32))func_ptr;
|
||||||
|
NativeFunc(exec_env, argv[0]);
|
||||||
|
ret = aot_get_exception(module_inst) ? false : true;
|
||||||
|
}
|
||||||
|
else if (result_count == 1 && types[param_count] == VALUE_TYPE_I32) {
|
||||||
|
uint32 (*NativeFunc)(WASMExecEnv*, uint32) =
|
||||||
|
(uint32 (*)(WASMExecEnv*, uint32))func_ptr;
|
||||||
|
argv_ret[0] = NativeFunc(exec_env, argv[0]);
|
||||||
|
ret = aot_get_exception(module_inst) ? false : true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
|
||||||
|
signature, attachment,
|
||||||
|
argv, argc, argv_ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
|
||||||
|
signature, attachment,
|
||||||
|
argv, argc, argv_ret);
|
||||||
|
}
|
||||||
#ifdef BH_PLATFORM_WINDOWS
|
#ifdef BH_PLATFORM_WINDOWS
|
||||||
if ((exce = aot_get_exception(module_inst))
|
if ((exce = aot_get_exception(module_inst))
|
||||||
&& strstr(exce, "native stack overflow")) {
|
&& strstr(exce, "native stack overflow")) {
|
||||||
|
@ -1339,8 +1381,10 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
|
||||||
if (!exec_env->jmpbuf_stack_top) {
|
if (!exec_env->jmpbuf_stack_top) {
|
||||||
*p_aot_exec_env = NULL;
|
*p_aot_exec_env = NULL;
|
||||||
}
|
}
|
||||||
os_sigreturn();
|
if (!ret) {
|
||||||
os_signal_unmask();
|
os_sigreturn();
|
||||||
|
os_signal_unmask();
|
||||||
|
}
|
||||||
(void)jmpbuf_node_pop;
|
(void)jmpbuf_node_pop;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -2157,6 +2201,140 @@ aot_is_wasm_type_equal(AOTModuleInstance *module_inst,
|
||||||
return wasm_type_equal(type1, type2);
|
return wasm_type_equal(type1, type2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
argv_to_params(wasm_val_t *out_params, const uint32 *argv,
|
||||||
|
AOTFuncType *func_type)
|
||||||
|
{
|
||||||
|
wasm_val_t *param = out_params;
|
||||||
|
uint32 i = 0, *u32;
|
||||||
|
|
||||||
|
for (i = 0; i < func_type->param_count; i++, param++) {
|
||||||
|
switch (func_type->types[i]) {
|
||||||
|
case VALUE_TYPE_I32:
|
||||||
|
param->kind = WASM_I32;
|
||||||
|
param->of.i32 = *argv++;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_I64:
|
||||||
|
param->kind = WASM_I64;
|
||||||
|
u32 = (uint32*)¶m->of.i64;
|
||||||
|
u32[0] = *argv++;
|
||||||
|
u32[1] = *argv++;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_F32:
|
||||||
|
param->kind = WASM_F32;
|
||||||
|
param->of.f32 = *(float32 *)argv++;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_F64:
|
||||||
|
param->kind = WASM_F64;
|
||||||
|
u32 = (uint32*)¶m->of.i64;
|
||||||
|
u32[0] = *argv++;
|
||||||
|
u32[1] = *argv++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
results_to_argv(uint32 *out_argv, const wasm_val_t *results,
|
||||||
|
AOTFuncType *func_type)
|
||||||
|
{
|
||||||
|
const wasm_val_t *result = results;
|
||||||
|
uint32 *argv = out_argv, *u32, i;
|
||||||
|
uint8 *result_types = func_type->types + func_type->param_count;
|
||||||
|
|
||||||
|
for (i = 0; i < func_type->result_count; i++, result++) {
|
||||||
|
switch (result_types[i]) {
|
||||||
|
case VALUE_TYPE_I32:
|
||||||
|
case VALUE_TYPE_F32:
|
||||||
|
*(int32*)argv++ = result->of.i32;
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_I64:
|
||||||
|
case VALUE_TYPE_F64:
|
||||||
|
u32 = (uint32*)&result->of.i64;
|
||||||
|
*argv++ = u32[0];
|
||||||
|
*argv++ = u32[1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
invoke_wasm_c_api_native(AOTModuleInstance *module_inst, void *func_ptr,
|
||||||
|
AOTFuncType *func_type, uint32 argc, uint32 *argv,
|
||||||
|
bool with_env, void *wasm_c_api_env)
|
||||||
|
{
|
||||||
|
wasm_val_t params_buf[16], results_buf[4];
|
||||||
|
wasm_val_t *params = params_buf, *results = results_buf;
|
||||||
|
wasm_trap_t *trap = NULL;
|
||||||
|
bool ret = false;
|
||||||
|
char fmt[16];
|
||||||
|
|
||||||
|
if (func_type->param_count > 16
|
||||||
|
&& !(params = wasm_runtime_malloc(sizeof(wasm_val_t)
|
||||||
|
* func_type->param_count))) {
|
||||||
|
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!argv_to_params(params, argv, func_type)) {
|
||||||
|
aot_set_exception(module_inst, "unsupported param type");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!with_env) {
|
||||||
|
wasm_func_callback_t callback = (wasm_func_callback_t)func_ptr;
|
||||||
|
trap = callback(params, results);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wasm_func_callback_with_env_t callback =
|
||||||
|
(wasm_func_callback_with_env_t)func_ptr;
|
||||||
|
trap = callback(wasm_c_api_env, params, results);
|
||||||
|
}
|
||||||
|
if (trap) {
|
||||||
|
if (trap->message->data) {
|
||||||
|
snprintf(fmt, sizeof(fmt), "%%%us", (uint32)trap->message->size);
|
||||||
|
snprintf(module_inst->cur_exception,
|
||||||
|
sizeof(module_inst->cur_exception),
|
||||||
|
fmt, trap->message->data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
aot_set_exception(module_inst,
|
||||||
|
"native function throw unknown exception");
|
||||||
|
}
|
||||||
|
wasm_trap_delete(trap);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func_type->result_count > 4
|
||||||
|
&& !(results = wasm_runtime_malloc(sizeof(wasm_val_t)
|
||||||
|
* func_type->result_count))) {
|
||||||
|
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!results_to_argv(argv, results, func_type)) {
|
||||||
|
aot_set_exception(module_inst, "unsupported result type");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (params != params_buf)
|
||||||
|
wasm_runtime_free(params);
|
||||||
|
if (results != results_buf)
|
||||||
|
wasm_runtime_free(results);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
|
aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
|
||||||
uint32 argc, uint32 *argv)
|
uint32 argc, uint32 *argv)
|
||||||
|
@ -2174,19 +2352,6 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
|
||||||
void *attachment;
|
void *attachment;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
|
||||||
uint32 page_size = os_getpagesize();
|
|
||||||
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
|
||||||
/* Check native stack overflow firstly to ensure we have enough
|
|
||||||
native stack to run the following codes before actually calling
|
|
||||||
the aot function in invokeNative function. */
|
|
||||||
if ((uint8*)&module_inst < exec_env->native_stack_boundary
|
|
||||||
+ page_size * (guard_page_count + 1)) {
|
|
||||||
aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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;
|
||||||
|
@ -2198,14 +2363,21 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
signature = import_func->signature;
|
|
||||||
attachment = import_func->attachment;
|
attachment = import_func->attachment;
|
||||||
if (!import_func->call_conv_raw) {
|
if (import_func->call_conv_wasm_c_api) {
|
||||||
|
return invoke_wasm_c_api_native(module_inst, func_ptr,
|
||||||
|
func_type, argc, argv,
|
||||||
|
import_func->wasm_c_api_with_env,
|
||||||
|
attachment);
|
||||||
|
}
|
||||||
|
else if (!import_func->call_conv_raw) {
|
||||||
|
signature = import_func->signature;
|
||||||
return wasm_runtime_invoke_native(exec_env, func_ptr,
|
return wasm_runtime_invoke_native(exec_env, func_ptr,
|
||||||
func_type, signature, attachment,
|
func_type, signature, attachment,
|
||||||
argv, argc, argv);
|
argv, argc, argv);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
signature = import_func->signature;
|
||||||
return wasm_runtime_invoke_native_raw(exec_env, func_ptr,
|
return wasm_runtime_invoke_native_raw(exec_env, func_ptr,
|
||||||
func_type, signature, attachment,
|
func_type, signature, attachment,
|
||||||
argv, argc, argv);
|
argv, argc, argv);
|
||||||
|
|
|
@ -346,13 +346,15 @@ typedef struct AOTModuleInstance {
|
||||||
/* function performance profiling info list */
|
/* function performance profiling info list */
|
||||||
AOTPointer func_perf_profilings;
|
AOTPointer func_perf_profilings;
|
||||||
|
|
||||||
|
AOTPointer exec_env_singleton;
|
||||||
|
|
||||||
/* others */
|
/* others */
|
||||||
uint32 temp_ret;
|
uint32 temp_ret;
|
||||||
uint32 llvm_stack;
|
uint32 llvm_stack;
|
||||||
uint32 default_wasm_stack_size;
|
uint32 default_wasm_stack_size;
|
||||||
|
|
||||||
/* reserved */
|
/* reserved */
|
||||||
uint32 reserved[11];
|
uint32 reserved[9];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* +------------------------------+ <-- memories.ptr
|
* +------------------------------+ <-- memories.ptr
|
||||||
|
@ -522,6 +524,10 @@ bool
|
||||||
aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
|
aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
|
||||||
AOTFunctionInstance *function,
|
AOTFunctionInstance *function,
|
||||||
unsigned argc, uint32 argv[]);
|
unsigned argc, uint32 argv[]);
|
||||||
|
|
||||||
|
bool
|
||||||
|
aot_create_exec_env_singleton(AOTModuleInstance *module_inst);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set AOT module instance exception with exception string
|
* Set AOT module instance exception with exception string
|
||||||
*
|
*
|
||||||
|
|
|
@ -2335,14 +2335,12 @@ wasm_func_call(const wasm_func_t *func,
|
||||||
/* a int64 or float64 parameter means 2 */
|
/* a int64 or float64 parameter means 2 */
|
||||||
uint32 argc = 0;
|
uint32 argc = 0;
|
||||||
/* a parameter list and a return value list */
|
/* a parameter list and a return value list */
|
||||||
uint32 *argv = NULL;
|
uint32 argv_buf[32], *argv = argv_buf;
|
||||||
WASMFunctionInstanceCommon *func_comm_rt = NULL;
|
WASMFunctionInstanceCommon *func_comm_rt = NULL;
|
||||||
|
WASMExecEnv *exec_env = NULL;
|
||||||
size_t param_count, result_count, alloc_count;
|
size_t param_count, result_count, alloc_count;
|
||||||
|
|
||||||
if (!func || !func->type || !func->inst_comm_rt
|
bh_assert(func && func->type && func->inst_comm_rt);
|
||||||
|| !valid_module_type(func->inst_comm_rt->module_type)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_trap = NULL;
|
cur_trap = NULL;
|
||||||
|
|
||||||
|
@ -2355,20 +2353,23 @@ wasm_func_call(const wasm_func_t *func,
|
||||||
|
|
||||||
#if WASM_ENABLE_AOT != 0
|
#if WASM_ENABLE_AOT != 0
|
||||||
if (func->inst_comm_rt->module_type == Wasm_Module_AoT) {
|
if (func->inst_comm_rt->module_type == Wasm_Module_AoT) {
|
||||||
AOTModuleInstance *inst_aot = (AOTModuleInstance *)func->inst_comm_rt;
|
if (!(func_comm_rt = func->func_comm_rt)) {
|
||||||
AOTModule *module_aot = (AOTModule *)inst_aot->aot_module.ptr;
|
AOTModuleInstance *inst_aot = (AOTModuleInstance *)func->inst_comm_rt;
|
||||||
|
AOTModule *module_aot = (AOTModule *)inst_aot->aot_module.ptr;
|
||||||
|
uint32 export_i = 0, export_func_j = 0;
|
||||||
|
|
||||||
uint32 export_i = 0, export_func_j = 0;
|
for (; export_i < module_aot->export_count; ++export_i) {
|
||||||
for (; export_i < module_aot->export_count; ++export_i) {
|
AOTExport *export = module_aot->exports + export_i;
|
||||||
AOTExport *export = module_aot->exports + export_i;
|
if (export->kind == EXPORT_KIND_FUNC) {
|
||||||
if (export->kind == EXPORT_KIND_FUNC) {
|
if (export->index == func->func_idx_rt) {
|
||||||
if (export->index == func->func_idx_rt) {
|
func_comm_rt =
|
||||||
func_comm_rt =
|
(AOTFunctionInstance *)inst_aot->export_funcs.ptr
|
||||||
(AOTFunctionInstance *)inst_aot->export_funcs.ptr
|
+ export_func_j;
|
||||||
+ export_func_j;
|
((wasm_func_t*)func)->func_comm_rt = func_comm_rt;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
export_func_j++;
|
||||||
}
|
}
|
||||||
export_func_j++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2381,7 +2382,7 @@ wasm_func_call(const wasm_func_t *func,
|
||||||
param_count = wasm_func_param_arity(func);
|
param_count = wasm_func_param_arity(func);
|
||||||
result_count = wasm_func_result_arity(func);
|
result_count = wasm_func_result_arity(func);
|
||||||
alloc_count = (param_count > result_count) ? param_count : result_count;
|
alloc_count = (param_count > result_count) ? param_count : result_count;
|
||||||
if (alloc_count) {
|
if (alloc_count > sizeof(argv_buf)/sizeof(uint64)) {
|
||||||
if (!(argv = malloc_internal(sizeof(uint64) * alloc_count))) {
|
if (!(argv = malloc_internal(sizeof(uint64) * alloc_count))) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
@ -2394,8 +2395,12 @@ wasm_func_call(const wasm_func_t *func,
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wasm_runtime_create_exec_env_and_call_wasm(
|
exec_env = wasm_runtime_get_exec_env_singleton(func->inst_comm_rt);
|
||||||
func->inst_comm_rt, func_comm_rt, argc, argv)) {
|
if (!exec_env) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wasm_runtime_call_wasm(exec_env, func_comm_rt, argc, argv)) {
|
||||||
if (wasm_runtime_get_exception(func->inst_comm_rt)) {
|
if (wasm_runtime_get_exception(func->inst_comm_rt)) {
|
||||||
LOG_DEBUG(wasm_runtime_get_exception(func->inst_comm_rt));
|
LOG_DEBUG(wasm_runtime_get_exception(func->inst_comm_rt));
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -2410,11 +2415,13 @@ wasm_func_call(const wasm_func_t *func,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FREEIF(argv);
|
if (argv != argv_buf)
|
||||||
|
wasm_runtime_free(argv);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
FREEIF(argv);
|
if (argv != argv_buf)
|
||||||
|
wasm_runtime_free(argv);
|
||||||
if (cur_trap) {
|
if (cur_trap) {
|
||||||
return cur_trap;
|
return cur_trap;
|
||||||
}
|
}
|
||||||
|
@ -3392,9 +3399,14 @@ aot_link_func(const wasm_instance_t *inst,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
import_aot_func->call_conv_raw = true;
|
import_aot_func->call_conv_wasm_c_api = true;
|
||||||
import_aot_func->attachment = cloned;
|
import_aot_func->wasm_c_api_with_env = import->with_env;
|
||||||
import_aot_func->func_ptr_linked = native_func_trampoline;
|
if (import->with_env) {
|
||||||
|
import_aot_func->func_ptr_linked = import->u.cb_env.cb;
|
||||||
|
import_aot_func->attachment = import->u.cb_env.env;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
import_aot_func->func_ptr_linked = import->u.cb;
|
||||||
import->func_idx_rt = import_func_idx_rt;
|
import->func_idx_rt = import_func_idx_rt;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -3668,6 +3680,10 @@ wasm_instance_new(wasm_store_t *store,
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!wasm_runtime_create_exec_env_singleton(instance->inst_comm_rt)) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
/* fill with inst */
|
/* fill with inst */
|
||||||
for (i = 0; imports && i < (uint32)import_count; ++i) {
|
for (i = 0; imports && i < (uint32)import_count; ++i) {
|
||||||
wasm_extern_t *import = (wasm_extern_t *)imports[i];
|
wasm_extern_t *import = (wasm_extern_t *)imports[i];
|
||||||
|
|
|
@ -112,6 +112,7 @@ struct wasm_func_t {
|
||||||
*/
|
*/
|
||||||
uint16 func_idx_rt;
|
uint16 func_idx_rt;
|
||||||
WASMModuleInstanceCommon *inst_comm_rt;
|
WASMModuleInstanceCommon *inst_comm_rt;
|
||||||
|
WASMFunctionInstanceCommon *func_comm_rt;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wasm_global_t {
|
struct wasm_global_t {
|
||||||
|
|
|
@ -1397,6 +1397,35 @@ wasm_runtime_create_exec_env_and_call_wasm(WASMModuleInstanceCommon *module_inst
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_runtime_create_exec_env_singleton(WASMModuleInstanceCommon *module_inst)
|
||||||
|
{
|
||||||
|
#if WASM_ENABLE_INTERP != 0
|
||||||
|
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||||
|
return wasm_create_exec_env_singleton((WASMModuleInstance *)module_inst);
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_AOT != 0
|
||||||
|
if (module_inst->module_type == Wasm_Module_AoT)
|
||||||
|
return aot_create_exec_env_singleton((AOTModuleInstance *)module_inst);
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
WASMExecEnv *
|
||||||
|
wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst)
|
||||||
|
{
|
||||||
|
#if WASM_ENABLE_INTERP != 0
|
||||||
|
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||||
|
return ((WASMModuleInstance *)module_inst)->exec_env_singleton;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_AOT != 0
|
||||||
|
if (module_inst->module_type == Wasm_Module_AoT)
|
||||||
|
return (WASMExecEnv *)
|
||||||
|
((AOTModuleInstance *)module_inst)->exec_env_singleton.ptr;
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst,
|
wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst,
|
||||||
const char *exception)
|
const char *exception)
|
||||||
|
|
|
@ -467,6 +467,12 @@ wasm_runtime_create_exec_env_and_call_wasm(WASMModuleInstanceCommon *module_inst
|
||||||
WASMFunctionInstanceCommon *function,
|
WASMFunctionInstanceCommon *function,
|
||||||
uint32 argc, uint32 argv[]);
|
uint32 argc, uint32 argv[]);
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_runtime_create_exec_env_singleton(WASMModuleInstanceCommon *module_inst);
|
||||||
|
|
||||||
|
WASMExecEnv *
|
||||||
|
wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst);
|
||||||
|
|
||||||
/* See wasm_export.h for description */
|
/* See wasm_export.h for description */
|
||||||
WASM_RUNTIME_API_EXTERN bool
|
WASM_RUNTIME_API_EXTERN bool
|
||||||
wasm_application_execute_main(WASMModuleInstanceCommon *module_inst,
|
wasm_application_execute_main(WASMModuleInstanceCommon *module_inst,
|
||||||
|
|
|
@ -290,6 +290,7 @@ aot_create_import_funcs(const WASMModule *module)
|
||||||
import_funcs[i].signature = import_func->signature;
|
import_funcs[i].signature = import_func->signature;
|
||||||
import_funcs[i].attachment = import_func->attachment;
|
import_funcs[i].attachment = import_func->attachment;
|
||||||
import_funcs[i].call_conv_raw = import_func->call_conv_raw;
|
import_funcs[i].call_conv_raw = import_func->call_conv_raw;
|
||||||
|
import_funcs[i].call_conv_wasm_c_api = false;
|
||||||
/* 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]) {
|
||||||
|
|
|
@ -148,6 +148,8 @@ typedef struct AOTImportFunc {
|
||||||
/* attachment */
|
/* attachment */
|
||||||
void *attachment;
|
void *attachment;
|
||||||
bool call_conv_raw;
|
bool call_conv_raw;
|
||||||
|
bool call_conv_wasm_c_api;
|
||||||
|
bool wasm_c_api_with_env;
|
||||||
} AOTImportFunc;
|
} AOTImportFunc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2130,3 +2130,103 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
extern void
|
||||||
|
wasm_set_ref_types_flag(bool enable);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8*
|
||||||
|
aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size,
|
||||||
|
uint32 opt_level, uint32 size_level,
|
||||||
|
uint32 *p_aot_file_size)
|
||||||
|
{
|
||||||
|
WASMModuleCommon *wasm_module = NULL;
|
||||||
|
AOTCompData *comp_data = NULL;
|
||||||
|
AOTCompContext *comp_ctx = NULL;
|
||||||
|
RuntimeInitArgs init_args;
|
||||||
|
AOTCompOption option = { 0 };
|
||||||
|
uint8 *aot_file_buf = NULL;
|
||||||
|
uint32 aot_file_size;
|
||||||
|
char error_buf[128];
|
||||||
|
|
||||||
|
option.is_jit_mode = false;
|
||||||
|
option.opt_level = opt_level;
|
||||||
|
option.size_level = size_level;
|
||||||
|
option.output_format = AOT_FORMAT_FILE;
|
||||||
|
/* default value, enable or disable depends on the platform */
|
||||||
|
option.bounds_checks = 2;
|
||||||
|
option.enable_simd = true;
|
||||||
|
option.enable_aux_stack_check = true;
|
||||||
|
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||||
|
option.enable_bulk_memory = true;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
option.enable_thread_mgr = true;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_TAIL_CALL != 0
|
||||||
|
option.enable_tail_call = true;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_SIMD != 0
|
||||||
|
option.enable_simd = true;
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
option.enable_ref_types = true;
|
||||||
|
#endif
|
||||||
|
#if (WASM_ENABLE_PERF_PROFILING != 0) || (WASM_ENABLE_DUMP_CALL_STACK != 0)
|
||||||
|
option.enable_aux_stack_frame = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
wasm_set_ref_types_flag(option.enable_ref_types);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||||
|
|
||||||
|
init_args.mem_alloc_type = Alloc_With_Allocator;
|
||||||
|
init_args.mem_alloc_option.allocator.malloc_func = malloc;
|
||||||
|
init_args.mem_alloc_option.allocator.realloc_func = realloc;
|
||||||
|
init_args.mem_alloc_option.allocator.free_func = free;
|
||||||
|
|
||||||
|
/* load WASM module */
|
||||||
|
if (!(wasm_module = (WASMModuleCommon*)
|
||||||
|
wasm_load(wasm_file_buf, wasm_file_size,
|
||||||
|
error_buf, sizeof(error_buf)))) {
|
||||||
|
os_printf("%s\n", error_buf);
|
||||||
|
aot_set_last_error(error_buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(comp_data = aot_create_comp_data((WASMModule*)wasm_module))) {
|
||||||
|
os_printf("%s\n", aot_get_last_error());
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(comp_ctx = aot_create_comp_context(comp_data, &option))) {
|
||||||
|
os_printf("%s\n", aot_get_last_error());
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aot_compile_wasm(comp_ctx)) {
|
||||||
|
os_printf("%s\n", aot_get_last_error());
|
||||||
|
goto fail3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(aot_file_buf = aot_emit_aot_file_buf(comp_ctx, comp_data,
|
||||||
|
&aot_file_size))) {
|
||||||
|
os_printf("%s\n", aot_get_last_error());
|
||||||
|
goto fail3;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p_aot_file_size = aot_file_size;
|
||||||
|
|
||||||
|
fail3:
|
||||||
|
/* Destroy compiler context */
|
||||||
|
aot_destroy_comp_context(comp_ctx);
|
||||||
|
fail2:
|
||||||
|
/* Destroy compile data */
|
||||||
|
aot_destroy_comp_data(comp_data);
|
||||||
|
fail1:
|
||||||
|
wasm_runtime_unload(wasm_module);
|
||||||
|
|
||||||
|
return aot_file_buf;
|
||||||
|
}
|
||||||
|
|
|
@ -368,9 +368,19 @@ aot_emit_aot_file(AOTCompContext *comp_ctx,
|
||||||
AOTCompData *comp_data,
|
AOTCompData *comp_data,
|
||||||
const char *file_name);
|
const char *file_name);
|
||||||
|
|
||||||
|
uint8_t*
|
||||||
|
aot_emit_aot_file_buf(AOTCompContext *comp_ctx,
|
||||||
|
AOTCompData *comp_data,
|
||||||
|
uint32_t *p_aot_file_size);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name);
|
aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name);
|
||||||
|
|
||||||
|
uint8_t*
|
||||||
|
aot_compile_wasm_file(const uint8_t *wasm_file_buf, uint32_t wasm_file_size,
|
||||||
|
uint32_t opt_level, uint32_t size_level,
|
||||||
|
uint32_t *p_aot_file_size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* end of extern "C" */
|
} /* end of extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2208,20 +2208,17 @@ fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
uint8*
|
||||||
aot_emit_aot_file(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|
aot_emit_aot_file_buf(AOTCompContext *comp_ctx,
|
||||||
const char *file_name)
|
AOTCompData *comp_data,
|
||||||
|
uint32 *p_aot_file_size)
|
||||||
{
|
{
|
||||||
AOTObjectData *obj_data = aot_obj_data_create(comp_ctx);
|
AOTObjectData *obj_data = aot_obj_data_create(comp_ctx);
|
||||||
uint8 *aot_file_buf, *buf, *buf_end;
|
uint8 *aot_file_buf, *buf, *buf_end;
|
||||||
uint32 aot_file_size, offset = 0;
|
uint32 aot_file_size, offset = 0;
|
||||||
bool ret = false;
|
|
||||||
FILE *file;
|
|
||||||
|
|
||||||
if (!obj_data)
|
if (!obj_data)
|
||||||
return false;
|
return NULL;
|
||||||
|
|
||||||
bh_print_time("Begin to emit AOT file");
|
|
||||||
|
|
||||||
aot_file_size = get_aot_file_size(comp_ctx, comp_data, obj_data);
|
aot_file_size = get_aot_file_size(comp_ctx, comp_data, obj_data);
|
||||||
|
|
||||||
|
@ -2251,25 +2248,52 @@ aot_emit_aot_file(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write buffer to file */
|
*p_aot_file_size = aot_file_size;
|
||||||
if (!(file = fopen(file_name, "wb"))) {
|
|
||||||
aot_set_last_error("open or create aot file failed.");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
if (!fwrite(aot_file_buf, aot_file_size, 1, file)) {
|
|
||||||
aot_set_last_error("write to aot file failed.");
|
|
||||||
goto fail3;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = true;
|
aot_obj_data_destroy(obj_data);
|
||||||
|
return aot_file_buf;
|
||||||
fail3:
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
fail2:
|
fail2:
|
||||||
wasm_runtime_free(aot_file_buf);
|
wasm_runtime_free(aot_file_buf);
|
||||||
|
|
||||||
fail1:
|
fail1:
|
||||||
aot_obj_data_destroy(obj_data);
|
aot_obj_data_destroy(obj_data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
aot_emit_aot_file(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|
||||||
|
const char *file_name)
|
||||||
|
{
|
||||||
|
uint8 *aot_file_buf;
|
||||||
|
uint32 aot_file_size;
|
||||||
|
bool ret = false;
|
||||||
|
FILE *file;
|
||||||
|
|
||||||
|
bh_print_time("Begin to emit AOT file");
|
||||||
|
|
||||||
|
if (!(aot_file_buf = aot_emit_aot_file_buf(comp_ctx, comp_data,
|
||||||
|
&aot_file_size))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write buffer to file */
|
||||||
|
if (!(file = fopen(file_name, "wb"))) {
|
||||||
|
aot_set_last_error("open or create aot file failed.");
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
if (!fwrite(aot_file_buf, aot_file_size, 1, file)) {
|
||||||
|
aot_set_last_error("write to aot file failed.");
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
fail2:
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
fail1:
|
||||||
|
wasm_runtime_free(aot_file_buf);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,11 @@ aot_emit_aot_file(aot_comp_context_t comp_ctx,
|
||||||
void
|
void
|
||||||
aot_destroy_aot_file(uint8_t *aot_file);
|
aot_destroy_aot_file(uint8_t *aot_file);
|
||||||
|
|
||||||
|
uint8_t*
|
||||||
|
aot_compile_wasm_file(const uint8_t *wasm_file_buf, uint32_t wasm_file_size,
|
||||||
|
uint32_t opt_level, uint32_t size_level,
|
||||||
|
uint32_t *p_aot_file_size);
|
||||||
|
|
||||||
char*
|
char*
|
||||||
aot_get_last_error();
|
aot_get_last_error();
|
||||||
|
|
||||||
|
|
|
@ -1574,6 +1574,9 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
|
||||||
wasm_externref_cleanup((WASMModuleInstanceCommon*)module_inst);
|
wasm_externref_cleanup((WASMModuleInstanceCommon*)module_inst);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (module_inst->exec_env_singleton)
|
||||||
|
wasm_exec_env_destroy(module_inst->exec_env_singleton);
|
||||||
|
|
||||||
wasm_runtime_free(module_inst);
|
wasm_runtime_free(module_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1701,6 +1704,18 @@ wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_create_exec_env_singleton(WASMModuleInstance *module_inst)
|
||||||
|
{
|
||||||
|
WASMExecEnv *exec_env =
|
||||||
|
wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
|
||||||
|
module_inst->default_wasm_stack_size);
|
||||||
|
if (exec_env)
|
||||||
|
module_inst->exec_env_singleton = exec_env;
|
||||||
|
|
||||||
|
return exec_env ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_set_exception(WASMModuleInstance *module_inst,
|
wasm_set_exception(WASMModuleInstance *module_inst,
|
||||||
const char *exception)
|
const char *exception)
|
||||||
|
|
|
@ -198,6 +198,8 @@ struct WASMModuleInstance {
|
||||||
WASIContext *wasi_ctx;
|
WASIContext *wasi_ctx;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
WASMExecEnv *exec_env_singleton;
|
||||||
|
|
||||||
uint32 temp_ret;
|
uint32 temp_ret;
|
||||||
uint32 llvm_stack;
|
uint32 llvm_stack;
|
||||||
|
|
||||||
|
@ -318,6 +320,9 @@ wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst,
|
||||||
WASMFunctionInstance *function,
|
WASMFunctionInstance *function,
|
||||||
unsigned argc, uint32 argv[]);
|
unsigned argc, uint32 argv[]);
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_create_exec_env_singleton(WASMModuleInstance *module_inst);
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_set_exception(WASMModuleInstance *module, const char *exception);
|
wasm_set_exception(WASMModuleInstance *module, const char *exception);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user