diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 935016b6f..bc0961def 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -13,6 +13,7 @@ #if WASM_ENABLE_THREAD_MGR != 0 #include "../libraries/thread-mgr/thread_manager.h" #endif +#include "../common/wasm_c_api_internal.h" static void set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) @@ -1097,6 +1098,18 @@ fail: 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 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) 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); } @@ -1287,6 +1304,9 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr, WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop; uint32 page_size = os_getpagesize(); 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 const char *exce; int result; @@ -1316,9 +1336,31 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr, aot_exec_env = exec_env; if (os_setjmp(jmpbuf_node.jmpbuf) == 0) { - ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type, - signature, attachment, - argv, argc, argv_ret); + /* Quick call with func_ptr if the function signature is simple */ + if (!signature && param_count == 1 && types[0] == VALUE_TYPE_I32) { + 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 if ((exce = aot_get_exception(module_inst)) && 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) { *p_aot_exec_env = NULL; } - os_sigreturn(); - os_signal_unmask(); + if (!ret) { + os_sigreturn(); + os_signal_unmask(); + } (void)jmpbuf_node_pop; return ret; } @@ -2157,6 +2201,140 @@ aot_is_wasm_type_equal(AOTModuleInstance *module_inst, 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 aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, uint32 *argv) @@ -2174,19 +2352,6 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, void *attachment; 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); import_func = aot_module->import_funcs + func_idx; @@ -2198,14 +2363,21 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, return false; } - signature = import_func->signature; 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, func_type, signature, attachment, argv, argc, argv); } else { + signature = import_func->signature; return wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type, signature, attachment, argv, argc, argv); diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 4d4dc7b1f..237764b59 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -346,13 +346,15 @@ typedef struct AOTModuleInstance { /* function performance profiling info list */ AOTPointer func_perf_profilings; + AOTPointer exec_env_singleton; + /* others */ uint32 temp_ret; uint32 llvm_stack; uint32 default_wasm_stack_size; /* reserved */ - uint32 reserved[11]; + uint32 reserved[9]; /* * +------------------------------+ <-- memories.ptr @@ -522,6 +524,10 @@ bool aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst, AOTFunctionInstance *function, unsigned argc, uint32 argv[]); + +bool +aot_create_exec_env_singleton(AOTModuleInstance *module_inst); + /** * Set AOT module instance exception with exception string * diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index db20479a8..c53388267 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -2335,14 +2335,12 @@ wasm_func_call(const wasm_func_t *func, /* a int64 or float64 parameter means 2 */ uint32 argc = 0; /* a parameter list and a return value list */ - uint32 *argv = NULL; + uint32 argv_buf[32], *argv = argv_buf; WASMFunctionInstanceCommon *func_comm_rt = NULL; + WASMExecEnv *exec_env = NULL; size_t param_count, result_count, alloc_count; - if (!func || !func->type || !func->inst_comm_rt - || !valid_module_type(func->inst_comm_rt->module_type)) { - return NULL; - } + bh_assert(func && func->type && func->inst_comm_rt); cur_trap = NULL; @@ -2355,20 +2353,23 @@ wasm_func_call(const wasm_func_t *func, #if WASM_ENABLE_AOT != 0 if (func->inst_comm_rt->module_type == Wasm_Module_AoT) { - AOTModuleInstance *inst_aot = (AOTModuleInstance *)func->inst_comm_rt; - AOTModule *module_aot = (AOTModule *)inst_aot->aot_module.ptr; + if (!(func_comm_rt = func->func_comm_rt)) { + 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) { - AOTExport *export = module_aot->exports + export_i; - if (export->kind == EXPORT_KIND_FUNC) { - if (export->index == func->func_idx_rt) { - func_comm_rt = - (AOTFunctionInstance *)inst_aot->export_funcs.ptr - + export_func_j; - break; + for (; export_i < module_aot->export_count; ++export_i) { + AOTExport *export = module_aot->exports + export_i; + if (export->kind == EXPORT_KIND_FUNC) { + if (export->index == func->func_idx_rt) { + func_comm_rt = + (AOTFunctionInstance *)inst_aot->export_funcs.ptr + + export_func_j; + ((wasm_func_t*)func)->func_comm_rt = func_comm_rt; + 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); result_count = wasm_func_result_arity(func); 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))) { goto failed; } @@ -2394,8 +2395,12 @@ wasm_func_call(const wasm_func_t *func, goto failed; } - if (!wasm_runtime_create_exec_env_and_call_wasm( - func->inst_comm_rt, func_comm_rt, argc, argv)) { + exec_env = wasm_runtime_get_exec_env_singleton(func->inst_comm_rt); + 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)) { LOG_DEBUG(wasm_runtime_get_exception(func->inst_comm_rt)); 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; failed: - FREEIF(argv); + if (argv != argv_buf) + wasm_runtime_free(argv); if (cur_trap) { return cur_trap; } @@ -3392,9 +3399,14 @@ aot_link_func(const wasm_instance_t *inst, return false; } - import_aot_func->call_conv_raw = true; - import_aot_func->attachment = cloned; - import_aot_func->func_ptr_linked = native_func_trampoline; + import_aot_func->call_conv_wasm_c_api = true; + import_aot_func->wasm_c_api_with_env = import->with_env; + 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; return true; @@ -3668,6 +3680,10 @@ wasm_instance_new(wasm_store_t *store, goto failed; } + if (!wasm_runtime_create_exec_env_singleton(instance->inst_comm_rt)) { + goto failed; + } + /* fill with inst */ for (i = 0; imports && i < (uint32)import_count; ++i) { wasm_extern_t *import = (wasm_extern_t *)imports[i]; diff --git a/core/iwasm/common/wasm_c_api_internal.h b/core/iwasm/common/wasm_c_api_internal.h index b308968be..073eead86 100644 --- a/core/iwasm/common/wasm_c_api_internal.h +++ b/core/iwasm/common/wasm_c_api_internal.h @@ -112,6 +112,7 @@ struct wasm_func_t { */ uint16 func_idx_rt; WASMModuleInstanceCommon *inst_comm_rt; + WASMFunctionInstanceCommon *func_comm_rt; }; struct wasm_global_t { diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index c4c7e778e..1999dacb5 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1397,6 +1397,35 @@ wasm_runtime_create_exec_env_and_call_wasm(WASMModuleInstanceCommon *module_inst 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 wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst, const char *exception) diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 2ad46f744..4ed886222 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -467,6 +467,12 @@ wasm_runtime_create_exec_env_and_call_wasm(WASMModuleInstanceCommon *module_inst WASMFunctionInstanceCommon *function, 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 */ WASM_RUNTIME_API_EXTERN bool wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, diff --git a/core/iwasm/compilation/aot.c b/core/iwasm/compilation/aot.c index 1bb67f3f1..3ab580cc5 100644 --- a/core/iwasm/compilation/aot.c +++ b/core/iwasm/compilation/aot.c @@ -290,6 +290,7 @@ aot_create_import_funcs(const WASMModule *module) 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; + import_funcs[i].call_conv_wasm_c_api = false; /* Resolve function type index */ for (j = 0; j < module->type_count; j++) if (import_func->func_type == module->types[j]) { diff --git a/core/iwasm/compilation/aot.h b/core/iwasm/compilation/aot.h index 015c84a7d..44f98cf1e 100644 --- a/core/iwasm/compilation/aot.h +++ b/core/iwasm/compilation/aot.h @@ -148,6 +148,8 @@ typedef struct AOTImportFunc { /* attachment */ void *attachment; bool call_conv_raw; + bool call_conv_wasm_c_api; + bool wasm_c_api_with_env; } AOTImportFunc; /** diff --git a/core/iwasm/compilation/aot_compiler.c b/core/iwasm/compilation/aot_compiler.c index 781e1f9fb..3232448ee 100644 --- a/core/iwasm/compilation/aot_compiler.c +++ b/core/iwasm/compilation/aot_compiler.c @@ -2130,3 +2130,103 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name) 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; +} diff --git a/core/iwasm/compilation/aot_compiler.h b/core/iwasm/compilation/aot_compiler.h index 182e180db..feb2eaff4 100644 --- a/core/iwasm/compilation/aot_compiler.h +++ b/core/iwasm/compilation/aot_compiler.h @@ -368,9 +368,19 @@ aot_emit_aot_file(AOTCompContext *comp_ctx, AOTCompData *comp_data, const char *file_name); +uint8_t* +aot_emit_aot_file_buf(AOTCompContext *comp_ctx, + AOTCompData *comp_data, + uint32_t *p_aot_file_size); + bool 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 } /* end of extern "C" */ #endif diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 8102f846c..64c04e2a3 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -2208,20 +2208,17 @@ fail: return NULL; } -bool -aot_emit_aot_file(AOTCompContext *comp_ctx, AOTCompData *comp_data, - const char *file_name) +uint8* +aot_emit_aot_file_buf(AOTCompContext *comp_ctx, + AOTCompData *comp_data, + uint32 *p_aot_file_size) { AOTObjectData *obj_data = aot_obj_data_create(comp_ctx); uint8 *aot_file_buf, *buf, *buf_end; uint32 aot_file_size, offset = 0; - bool ret = false; - FILE *file; if (!obj_data) - return false; - - bh_print_time("Begin to emit AOT file"); + return NULL; 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; } - /* write buffer to file */ - 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; - } + *p_aot_file_size = aot_file_size; - ret = true; - -fail3: - fclose(file); + aot_obj_data_destroy(obj_data); + return aot_file_buf; fail2: wasm_runtime_free(aot_file_buf); fail1: 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; } diff --git a/core/iwasm/include/aot_export.h b/core/iwasm/include/aot_export.h index 8adf663a3..d209044ce 100644 --- a/core/iwasm/include/aot_export.h +++ b/core/iwasm/include/aot_export.h @@ -77,6 +77,11 @@ aot_emit_aot_file(aot_comp_context_t comp_ctx, void 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* aot_get_last_error(); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 08c2bd241..d3874dfa7 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1574,6 +1574,9 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) wasm_externref_cleanup((WASMModuleInstanceCommon*)module_inst); #endif + if (module_inst->exec_env_singleton) + wasm_exec_env_destroy(module_inst->exec_env_singleton); + wasm_runtime_free(module_inst); } @@ -1701,6 +1704,18 @@ wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst, 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 wasm_set_exception(WASMModuleInstance *module_inst, const char *exception) diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 5f45f183c..55c13c282 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -198,6 +198,8 @@ struct WASMModuleInstance { WASIContext *wasi_ctx; #endif + WASMExecEnv *exec_env_singleton; + uint32 temp_ret; uint32 llvm_stack; @@ -318,6 +320,9 @@ wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst, WASMFunctionInstance *function, unsigned argc, uint32 argv[]); +bool +wasm_create_exec_env_singleton(WASMModuleInstance *module_inst); + void wasm_set_exception(WASMModuleInstance *module, const char *exception);