mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-31 05:11:19 +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
	 Wenyong Huang
						Wenyong Huang