Skip to content

Commit 9d52960

Browse files
authored
Fix wasm-c-api import func link issue in wasm_instance_new (#1787)
When a wasm module is duplicated instantiated with wasm_instance_new, the function import info of the previous instantiation may be overwritten by the later instantiation, which may cause unexpected behavior. Store the function import info into the module instance to fix the issue.
1 parent d974452 commit 9d52960

File tree

8 files changed

+128
-24
lines changed

8 files changed

+128
-24
lines changed

core/iwasm/aot/aot_runtime.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,7 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
987987
(uint64)module->memory_count * sizeof(AOTMemoryInstance);
988988
uint64 total_size, table_size = 0;
989989
uint8 *p;
990-
uint32 i;
990+
uint32 i, extra_info_offset;
991991

992992
/* Check heap size */
993993
heap_size = align_uint(heap_size, 8);
@@ -1015,6 +1015,11 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
10151015
}
10161016
total_size += table_size;
10171017

1018+
/* The offset of AOTModuleInstanceExtra, make it 8-byte aligned */
1019+
total_size = (total_size + 7LL) & ~7LL;
1020+
extra_info_offset = (uint32)total_size;
1021+
total_size += sizeof(AOTModuleInstanceExtra);
1022+
10181023
/* Allocate module instance, global data, table data and heap data */
10191024
if (!(module_inst =
10201025
runtime_malloc(total_size, error_buf, error_buf_size))) {
@@ -1023,6 +1028,8 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
10231028

10241029
module_inst->module_type = Wasm_Module_AoT;
10251030
module_inst->module = (void *)module;
1031+
module_inst->e =
1032+
(WASMModuleInstanceExtra *)((uint8 *)module_inst + extra_info_offset);
10261033

10271034
/* Initialize global info */
10281035
p = (uint8 *)module_inst + module_inst_struct_size
@@ -1179,6 +1186,10 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
11791186
if (module_inst->exec_env_singleton)
11801187
wasm_exec_env_destroy((WASMExecEnv *)module_inst->exec_env_singleton);
11811188

1189+
if (((AOTModuleInstanceExtra *)module_inst->e)->c_api_func_imports)
1190+
wasm_runtime_free(
1191+
((AOTModuleInstanceExtra *)module_inst->e)->c_api_func_imports);
1192+
11821193
wasm_runtime_free(module_inst);
11831194
}
11841195

@@ -1750,6 +1761,10 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
17501761
AOTModuleInstance *module_inst =
17511762
(AOTModuleInstance *)wasm_runtime_get_module_inst(exec_env);
17521763
AOTModule *aot_module = (AOTModule *)module_inst->module;
1764+
AOTModuleInstanceExtra *module_inst_extra =
1765+
(AOTModuleInstanceExtra *)module_inst->e;
1766+
CApiFuncImport *c_api_func_import =
1767+
module_inst_extra->c_api_func_imports + func_idx;
17531768
uint32 *func_type_indexes = module_inst->func_type_indexes;
17541769
uint32 func_type_idx = func_type_indexes[func_idx];
17551770
AOTFuncType *func_type = aot_module->func_types[func_type_idx];
@@ -1764,6 +1779,9 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
17641779
bh_assert(func_idx < aot_module->import_func_count);
17651780

17661781
import_func = aot_module->import_funcs + func_idx;
1782+
if (import_func->call_conv_wasm_c_api)
1783+
func_ptr = c_api_func_import->func_ptr_linked;
1784+
17671785
if (!func_ptr) {
17681786
snprintf(buf, sizeof(buf),
17691787
"failed to call unlinked import function (%s, %s)",
@@ -1776,7 +1794,7 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
17761794
if (import_func->call_conv_wasm_c_api) {
17771795
ret = wasm_runtime_invoke_c_api_native(
17781796
(WASMModuleInstanceCommon *)module_inst, func_ptr, func_type, argc,
1779-
argv, import_func->wasm_c_api_with_env, attachment);
1797+
argv, c_api_func_import->with_env_arg, c_api_func_import->env_arg);
17801798
}
17811799
else if (!import_func->call_conv_raw) {
17821800
signature = import_func->signature;

core/iwasm/aot/aot_runtime.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ typedef struct AOTFunctionInstance {
7373
} u;
7474
} AOTFunctionInstance;
7575

76+
typedef struct AOTModuleInstanceExtra {
77+
CApiFuncImport *c_api_func_imports;
78+
} AOTModuleInstanceExtra;
79+
7680
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
7781
/* clang-format off */
7882
typedef struct AOTUnwindInfo {

core/iwasm/common/wasm_c_api.c

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4282,15 +4282,13 @@ interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp,
42824282
return false;
42834283

42844284
imported_func_interp->u.function.call_conv_wasm_c_api = true;
4285-
imported_func_interp->u.function.wasm_c_api_with_env = import->with_env;
4286-
if (import->with_env) {
4285+
/* only set func_ptr_linked to avoid unlink warning during instantiation,
4286+
func_ptr_linked, with_env and env will be stored in module instance's
4287+
c_api_func_imports later and used when calling import function */
4288+
if (import->with_env)
42874289
imported_func_interp->u.function.func_ptr_linked = import->u.cb_env.cb;
4288-
imported_func_interp->u.function.attachment = import->u.cb_env.env;
4289-
}
4290-
else {
4290+
else
42914291
imported_func_interp->u.function.func_ptr_linked = import->u.cb;
4292-
imported_func_interp->u.function.attachment = NULL;
4293-
}
42944292
import->func_idx_rt = func_idx_rt;
42954293

42964294
return true;
@@ -4496,15 +4494,13 @@ aot_link_func(const wasm_instance_t *inst, const AOTModule *module_aot,
44964494
return false;
44974495

44984496
import_aot_func->call_conv_wasm_c_api = true;
4499-
import_aot_func->wasm_c_api_with_env = import->with_env;
4500-
if (import->with_env) {
4497+
/* only set func_ptr_linked to avoid unlink warning during instantiation,
4498+
func_ptr_linked, with_env and env will be stored in module instance's
4499+
c_api_func_imports later and used when calling import function */
4500+
if (import->with_env)
45014501
import_aot_func->func_ptr_linked = import->u.cb_env.cb;
4502-
import_aot_func->attachment = import->u.cb_env.env;
4503-
}
4504-
else {
4502+
else
45054503
import_aot_func->func_ptr_linked = import->u.cb;
4506-
import_aot_func->attachment = NULL;
4507-
}
45084504
import->func_idx_rt = import_func_idx_rt;
45094505

45104506
return true;
@@ -4718,10 +4714,12 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
47184714
{
47194715
char sub_error_buf[128] = { 0 };
47204716
char error_buf[256] = { 0 };
4721-
uint32 import_count = 0;
47224717
bool import_count_verified = false;
47234718
wasm_instance_t *instance = NULL;
4724-
uint32 i = 0;
4719+
WASMModuleInstance *inst_rt;
4720+
CApiFuncImport *func_import = NULL, **p_func_imports = NULL;
4721+
uint32 i = 0, import_count = 0, import_func_count = 0;
4722+
uint64 total_size;
47254723
bool processed = false;
47264724

47274725
bh_assert(singleton_engine);
@@ -4804,6 +4802,56 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
48044802
goto failed;
48054803
}
48064804

4805+
inst_rt = (WASMModuleInstance *)instance->inst_comm_rt;
4806+
#if WASM_ENABLE_INTERP != 0
4807+
if (instance->inst_comm_rt->module_type == Wasm_Module_Bytecode) {
4808+
p_func_imports = &inst_rt->e->c_api_func_imports;
4809+
import_func_count = inst_rt->module->import_function_count;
4810+
}
4811+
#endif
4812+
#if WASM_ENABLE_AOT != 0
4813+
if (instance->inst_comm_rt->module_type == Wasm_Module_AoT) {
4814+
p_func_imports =
4815+
&((AOTModuleInstanceExtra *)inst_rt->e)->c_api_func_imports;
4816+
import_func_count = ((AOTModule *)inst_rt->module)->import_func_count;
4817+
}
4818+
#endif
4819+
bh_assert(p_func_imports);
4820+
4821+
/* create the c-api func import list */
4822+
total_size = (uint64)sizeof(CApiFuncImport) * import_func_count;
4823+
if (total_size > 0
4824+
&& !(*p_func_imports = func_import = malloc_internal(total_size))) {
4825+
snprintf(sub_error_buf, sizeof(sub_error_buf),
4826+
"Failed to create wasm-c-api func imports");
4827+
goto failed;
4828+
}
4829+
4830+
/* fill in c-api func import list */
4831+
for (i = 0; i < import_count; i++) {
4832+
wasm_func_t *func_host;
4833+
wasm_extern_t *in;
4834+
4835+
in = imports->data[i];
4836+
if (wasm_extern_kind(in) != WASM_EXTERN_FUNC)
4837+
continue;
4838+
4839+
func_host = wasm_extern_as_func(in);
4840+
4841+
func_import->with_env_arg = func_host->with_env;
4842+
if (func_host->with_env) {
4843+
func_import->func_ptr_linked = func_host->u.cb_env.cb;
4844+
func_import->env_arg = func_host->u.cb_env.env;
4845+
}
4846+
else {
4847+
func_import->func_ptr_linked = func_host->u.cb;
4848+
func_import->env_arg = NULL;
4849+
}
4850+
4851+
func_import++;
4852+
}
4853+
bh_assert((uint32)(func_import - *p_func_imports) == import_func_count);
4854+
48074855
/* fill with inst */
48084856
for (i = 0; imports && imports->data && i < (uint32)import_count; ++i) {
48094857
wasm_extern_t *import = imports->data[i];

core/iwasm/interpreter/wasm.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ typedef struct WASMFunctionImport {
189189
WASMFunction *import_func_linked;
190190
#endif
191191
bool call_conv_wasm_c_api;
192-
bool wasm_c_api_with_env;
193192
} WASMFunctionImport;
194193

195194
typedef struct WASMGlobalImport {

core/iwasm/interpreter/wasm_interp_classic.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
838838
WASMInterpFrame *prev_frame)
839839
{
840840
WASMFunctionImport *func_import = cur_func->u.func_import;
841+
CApiFuncImport *c_api_func_import = NULL;
841842
unsigned local_cell_num = 2;
842843
WASMInterpFrame *frame;
843844
uint32 argv_ret[2], cur_func_index;
@@ -858,7 +859,13 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
858859

859860
cur_func_index = (uint32)(cur_func - module_inst->e->functions);
860861
bh_assert(cur_func_index < module_inst->module->import_function_count);
861-
native_func_pointer = module_inst->import_func_ptrs[cur_func_index];
862+
if (!func_import->call_conv_wasm_c_api) {
863+
native_func_pointer = module_inst->import_func_ptrs[cur_func_index];
864+
}
865+
else {
866+
c_api_func_import = module_inst->e->c_api_func_imports + cur_func_index;
867+
native_func_pointer = c_api_func_import->func_ptr_linked;
868+
}
862869

863870
if (!native_func_pointer) {
864871
snprintf(buf, sizeof(buf),
@@ -872,7 +879,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
872879
ret = wasm_runtime_invoke_c_api_native(
873880
(WASMModuleInstanceCommon *)module_inst, native_func_pointer,
874881
func_import->func_type, cur_func->param_cell_num, frame->lp,
875-
func_import->wasm_c_api_with_env, func_import->attachment);
882+
c_api_func_import->with_env_arg, c_api_func_import->env_arg);
876883
if (ret) {
877884
argv_ret[0] = frame->lp[0];
878885
argv_ret[1] = frame->lp[1];

core/iwasm/interpreter/wasm_interp_fast.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
902902
WASMInterpFrame *prev_frame)
903903
{
904904
WASMFunctionImport *func_import = cur_func->u.func_import;
905+
CApiFuncImport *c_api_func_import = NULL;
905906
unsigned local_cell_num = 2;
906907
WASMInterpFrame *frame;
907908
uint32 argv_ret[2], cur_func_index;
@@ -921,7 +922,13 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
921922

922923
cur_func_index = (uint32)(cur_func - module_inst->e->functions);
923924
bh_assert(cur_func_index < module_inst->module->import_function_count);
924-
native_func_pointer = module_inst->import_func_ptrs[cur_func_index];
925+
if (!func_import->call_conv_wasm_c_api) {
926+
native_func_pointer = module_inst->import_func_ptrs[cur_func_index];
927+
}
928+
else {
929+
c_api_func_import = module_inst->e->c_api_func_imports + cur_func_index;
930+
native_func_pointer = c_api_func_import->func_ptr_linked;
931+
}
925932

926933
if (!native_func_pointer) {
927934
char buf[128];
@@ -936,7 +943,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
936943
ret = wasm_runtime_invoke_c_api_native(
937944
(WASMModuleInstanceCommon *)module_inst, native_func_pointer,
938945
func_import->func_type, cur_func->param_cell_num, frame->lp,
939-
func_import->wasm_c_api_with_env, func_import->attachment);
946+
c_api_func_import->with_env_arg, c_api_func_import->env_arg);
940947
if (ret) {
941948
argv_ret[0] = frame->lp[0];
942949
argv_ret[1] = frame->lp[1];

core/iwasm/interpreter/wasm_runtime.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1948,6 +1948,9 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
19481948
os_mutex_destroy(&module_inst->e->mem_lock);
19491949
#endif
19501950

1951+
if (module_inst->e->c_api_func_imports)
1952+
wasm_runtime_free(module_inst->e->c_api_func_imports);
1953+
19511954
wasm_runtime_free(module_inst);
19521955
}
19531956

@@ -2849,6 +2852,7 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
28492852
WASMType *func_type;
28502853
void *func_ptr;
28512854
WASMFunctionImport *import_func;
2855+
CApiFuncImport *c_api_func_import = NULL;
28522856
const char *signature;
28532857
void *attachment;
28542858
char buf[96];
@@ -2870,6 +2874,11 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
28702874
bh_assert(func_idx < module->import_function_count);
28712875

28722876
import_func = &module->import_functions[func_idx].u.function;
2877+
if (import_func->call_conv_wasm_c_api) {
2878+
c_api_func_import = module_inst->e->c_api_func_imports + func_idx;
2879+
func_ptr = c_api_func_import->func_ptr_linked;
2880+
}
2881+
28732882
if (!func_ptr) {
28742883
snprintf(buf, sizeof(buf),
28752884
"failed to call unlinked import function (%s, %s)",
@@ -2882,7 +2891,7 @@ llvm_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
28822891
if (import_func->call_conv_wasm_c_api) {
28832892
ret = wasm_runtime_invoke_c_api_native(
28842893
(WASMModuleInstanceCommon *)module_inst, func_ptr, func_type, argc,
2885-
argv, import_func->wasm_c_api_with_env, attachment);
2894+
argv, c_api_func_import->with_env_arg, c_api_func_import->env_arg);
28862895
}
28872896
else if (!import_func->call_conv_raw) {
28882897
signature = import_func->signature;

core/iwasm/interpreter/wasm_runtime.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,16 @@ typedef struct WASMExportMemInstance {
192192
WASMMemoryInstance *memory;
193193
} WASMExportMemInstance;
194194

195+
/* wasm-c-api import function info */
196+
typedef struct CApiFuncImport {
197+
/* host func pointer after linked */
198+
void *func_ptr_linked;
199+
/* whether the host func has env argument */
200+
bool with_env_arg;
201+
/* the env argument of the host func */
202+
void *env_arg;
203+
} CApiFuncImport;
204+
195205
/* Extra info of WASM module instance for interpreter/jit mode */
196206
typedef struct WASMModuleInstanceExtra {
197207
WASMGlobalInstance *globals;
@@ -205,6 +215,8 @@ typedef struct WASMModuleInstanceExtra {
205215
WASMFunctionInstance *free_function;
206216
WASMFunctionInstance *retain_function;
207217

218+
CApiFuncImport *c_api_func_imports;
219+
208220
#if WASM_ENABLE_SHARED_MEMORY != 0
209221
/* lock for shared memory atomic operations */
210222
korp_mutex mem_lock;

0 commit comments

Comments
 (0)