Skip to content

Commit 5418e09

Browse files
authored
Add two apis for wasm function call (#375)
Add below two apis: bool wasm_runtime_call_wasm_a(WASMExecEnv *exec_env, WASMFunctionInstanceCommon *function, uint32 num_results, wasm_val_t results[], uint32 num_args, wasm_val_t args[]) bool wasm_runtime_call_wasm_v(WASMExecEnv *exec_env, WASMFunctionInstanceCommon *function, uint32 num_results, wasm_val_t results[], uint32 num_args, ...) Signed-off-by: Xiaokang Qin <[email protected]>
1 parent 2135bad commit 5418e09

File tree

5 files changed

+359
-3
lines changed

5 files changed

+359
-3
lines changed

core/iwasm/common/wasm_runtime_common.c

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,227 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
863863
return false;
864864
}
865865

866+
static uint32
867+
parse_args_to_uint32_array(WASMType *type,
868+
uint32 num_args, wasm_val_t *args,
869+
uint32 *out_argv)
870+
{
871+
int i, p;
872+
873+
for (i = 0, p = 0; i < num_args; i++) {
874+
switch (args[i].kind) {
875+
case WASM_I32:
876+
out_argv[p++] = args[i].of.i32;
877+
break;
878+
case WASM_I64:
879+
{
880+
union { uint64 val; uint32 parts[2]; } u;
881+
u.val = args[i].of.i64;
882+
out_argv[p++] = u.parts[0];
883+
out_argv[p++] = u.parts[1];
884+
break;
885+
}
886+
case WASM_F32:
887+
{
888+
union { float32 val; uint32 part; } u;
889+
u.val = args[i].of.f32;
890+
out_argv[p++] = u.part;
891+
break;
892+
}
893+
case WASM_F64:
894+
{
895+
union { float64 val; uint32 parts[2]; } u;
896+
u.val = args[i].of.f64;
897+
out_argv[p++] = u.parts[0];
898+
out_argv[p++] = u.parts[1];
899+
break;
900+
}
901+
default:
902+
bh_assert(0);
903+
break;
904+
}
905+
}
906+
return p;
907+
}
908+
909+
static uint32
910+
parse_uint32_array_to_results(WASMType *type,
911+
uint32 argc, uint32 *argv,
912+
wasm_val_t *out_results)
913+
{
914+
int i, p;
915+
916+
for (i = 0, p = 0; i < type->result_count; i++) {
917+
switch (type->types[type->param_count + i]) {
918+
case VALUE_TYPE_I32:
919+
out_results[i].kind = WASM_I32;
920+
out_results[i].of.i32 = *(int32 *)argv[p++];
921+
break;
922+
case VALUE_TYPE_I64:
923+
{
924+
union { uint64 val; uint32 parts[2]; } u;
925+
u.parts[0] = argv[p++];
926+
u.parts[1] = argv[p++];
927+
out_results[i].kind = WASM_I64;
928+
out_results[i].of.i64 = u.val;
929+
break;
930+
}
931+
case VALUE_TYPE_F32:
932+
{
933+
union { float32 val; uint32 part; } u;
934+
u.part = argv[p++];
935+
out_results[i].kind = WASM_F32;
936+
out_results[i].of.f32 = u.val;
937+
break;
938+
}
939+
case VALUE_TYPE_F64:
940+
{
941+
union { float64 val; uint32 parts[2]; } u;
942+
u.parts[0] = argv[p++];
943+
u.parts[1] = argv[p++];
944+
out_results[i].kind = WASM_F64;
945+
out_results[i].of.f64 = u.val;
946+
break;
947+
}
948+
default:
949+
bh_assert(0);
950+
break;
951+
}
952+
}
953+
bh_assert(argc == p);
954+
return type->result_count;
955+
}
956+
957+
bool
958+
wasm_runtime_call_wasm_a(WASMExecEnv *exec_env,
959+
WASMFunctionInstanceCommon *function,
960+
uint32 num_results, wasm_val_t results[],
961+
uint32 num_args, wasm_val_t args[])
962+
{
963+
uint32 argc, *argv, ret_num, cell_num, total_size;
964+
bool ret = false;
965+
WASMType *type = NULL;
966+
967+
#if WASM_ENABLE_INTERP != 0
968+
if (exec_env->module_inst->module_type == Wasm_Module_Bytecode) {
969+
WASMFunctionInstance *wasm_func = (WASMFunctionInstance*)function;
970+
type = wasm_func->u.func->func_type;
971+
argc = wasm_func->param_cell_num;
972+
cell_num = argc > wasm_func->ret_cell_num ?
973+
argc : wasm_func->ret_cell_num;
974+
}
975+
#endif
976+
#if WASM_ENABLE_AOT != 0
977+
if (exec_env->module_inst->module_type == Wasm_Module_AoT) {
978+
type = ((AOTFunctionInstance*)function)->u.func.func_type;
979+
argc = type->param_cell_num;
980+
cell_num = argc > type->ret_cell_num ?
981+
argc : type->ret_cell_num;
982+
}
983+
#endif
984+
if (!type) {
985+
LOG_ERROR("Function type get failed, WAMR Interpreter and AOT must be enabled at least one.");
986+
goto fail1;
987+
}
988+
989+
if (num_results != type->result_count) {
990+
LOG_ERROR("The result value number does not match the function declaration.");
991+
goto fail1;
992+
}
993+
994+
if (num_args != type->param_count) {
995+
LOG_ERROR("The argument value number does not match the function declaration.");
996+
goto fail1;
997+
}
998+
999+
total_size = sizeof(uint32) * (uint64)(cell_num > 2 ? cell_num : 2);
1000+
if (!(argv = runtime_malloc((uint32)total_size, exec_env->module_inst, NULL, 0))) {
1001+
wasm_runtime_set_exception(exec_env->module_inst, "allocate memory failed");
1002+
goto fail1;
1003+
}
1004+
1005+
argc = parse_args_to_uint32_array(type, num_args, args, argv);
1006+
if (!(ret = wasm_runtime_call_wasm(exec_env, function, argc, argv)))
1007+
goto fail2;
1008+
1009+
ret_num = parse_uint32_array_to_results(type, type->ret_cell_num, argv, results);
1010+
bh_assert(ret_num == num_results);
1011+
1012+
fail2:
1013+
wasm_runtime_free(argv);
1014+
fail1:
1015+
return ret;
1016+
}
1017+
1018+
bool
1019+
wasm_runtime_call_wasm_v(WASMExecEnv *exec_env,
1020+
WASMFunctionInstanceCommon *function,
1021+
uint32 num_results, wasm_val_t results[],
1022+
uint32 num_args, ...)
1023+
{
1024+
wasm_val_t *args = NULL;
1025+
WASMType *type = NULL;
1026+
bool ret = false;
1027+
int i = 0;
1028+
va_list vargs;
1029+
1030+
#if WASM_ENABLE_INTERP != 0
1031+
if (exec_env->module_inst->module_type == Wasm_Module_Bytecode) {
1032+
WASMFunctionInstance *wasm_func = (WASMFunctionInstance*)function;
1033+
type = wasm_func->u.func->func_type;
1034+
}
1035+
#endif
1036+
#if WASM_ENABLE_AOT != 0
1037+
if (exec_env->module_inst->module_type == Wasm_Module_AoT) {
1038+
type = ((AOTFunctionInstance*)function)->u.func.func_type;
1039+
}
1040+
#endif
1041+
if (!type) {
1042+
LOG_ERROR("Function type get failed, WAMR Interpreter and AOT must be enabled at least one.");
1043+
goto fail1;
1044+
}
1045+
1046+
if (num_args != type->param_count) {
1047+
LOG_ERROR("The argument value number does not match the function declaration.");
1048+
goto fail1;
1049+
}
1050+
if (!(args = runtime_malloc(sizeof(wasm_val_t) * num_args, NULL, NULL, 0))) {
1051+
wasm_runtime_set_exception(exec_env->module_inst, "allocate memory failed");
1052+
goto fail1;
1053+
}
1054+
1055+
va_start(vargs, num_args);
1056+
for (i = 0; i < num_args; i++) {
1057+
switch (type->types[i]) {
1058+
case VALUE_TYPE_I32:
1059+
args[i].kind = WASM_I32;
1060+
args[i].of.i32 = va_arg(vargs, uint32);
1061+
break;
1062+
case VALUE_TYPE_I64:
1063+
args[i].kind = WASM_I64;
1064+
args[i].of.i64 = va_arg(vargs, uint64);
1065+
break;
1066+
case VALUE_TYPE_F32:
1067+
args[i].kind = WASM_F32;
1068+
args[i].of.f32 = (float32)va_arg(vargs, float64);
1069+
break;
1070+
case VALUE_TYPE_F64:
1071+
args[i].kind = WASM_F64;
1072+
args[i].of.f64 = va_arg(vargs, float64);;
1073+
break;
1074+
default:
1075+
bh_assert(0);
1076+
break;
1077+
}
1078+
}
1079+
va_end(vargs);
1080+
ret = wasm_runtime_call_wasm_a(exec_env, function, num_results, results, num_args, args);
1081+
wasm_runtime_free(args);
1082+
1083+
fail1:
1084+
return ret;
1085+
}
1086+
8661087
bool
8671088
wasm_runtime_create_exec_env_and_call_wasm(WASMModuleInstanceCommon *module_inst,
8681089
WASMFunctionInstanceCommon *function,

core/iwasm/common/wasm_runtime_common.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,18 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
167167
WASMFunctionInstanceCommon *function,
168168
uint32 argc, uint32 argv[]);
169169

170+
bool
171+
wasm_runtime_call_wasm_a(WASMExecEnv *exec_env,
172+
WASMFunctionInstanceCommon *function,
173+
uint32 num_results, wasm_val_t *results,
174+
uint32 num_args, wasm_val_t *args);
175+
176+
bool
177+
wasm_runtime_call_wasm_v(WASMExecEnv *exec_env,
178+
WASMFunctionInstanceCommon *function,
179+
uint32 num_results, wasm_val_t *results,
180+
uint32 num_args, ...);
181+
170182
/**
171183
* Call a function reference of a given WASM runtime instance with
172184
* arguments.

core/iwasm/include/wasm_c_api.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ static const uint32_t wasm_limits_max_default = 0xffffffff;
165165

166166
WASM_DECLARE_TYPE(valtype)
167167

168+
#ifndef WASM_VALKIND_T_DEFINED
169+
#define WASM_VALKIND_T_DEFINED
168170
typedef uint8_t wasm_valkind_t;
169171
enum wasm_valkind_enum {
170172
WASM_I32,
@@ -174,6 +176,7 @@ enum wasm_valkind_enum {
174176
WASM_ANYREF = 128,
175177
WASM_FUNCREF,
176178
};
179+
#endif
177180

178181
WASM_API_EXTERN own wasm_valtype_t* wasm_valtype_new(wasm_valkind_t);
179182

@@ -299,6 +302,8 @@ WASM_API_EXTERN const wasm_externtype_t* wasm_exporttype_type(const wasm_exportt
299302

300303
// Values
301304

305+
#ifndef WASM_VAL_T_DEFINED
306+
#define WASM_VAL_T_DEFINED
302307
struct wasm_ref_t;
303308

304309
typedef struct wasm_val_t {
@@ -311,6 +316,7 @@ typedef struct wasm_val_t {
311316
struct wasm_ref_t* ref;
312317
} of;
313318
} wasm_val_t;
319+
#endif
314320

315321
WASM_API_EXTERN void wasm_val_delete(own wasm_val_t* v);
316322
WASM_API_EXTERN void wasm_val_copy(own wasm_val_t* out, const wasm_val_t*);

core/iwasm/include/wasm_export.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,35 @@ typedef struct RuntimeInitArgs {
120120
uint32_t max_thread_num;
121121
} RuntimeInitArgs;
122122

123+
#ifndef WASM_VALKIND_T_DEFINED
124+
#define WASM_VALKIND_T_DEFINED
125+
typedef uint8_t wasm_valkind_t;
126+
enum wasm_valkind_enum {
127+
WASM_I32,
128+
WASM_I64,
129+
WASM_F32,
130+
WASM_F64,
131+
WASM_ANYREF = 128,
132+
WASM_FUNCREF,
133+
};
134+
#endif
135+
136+
#ifndef WASM_VAL_T_DEFINED
137+
#define WASM_VAL_T_DEFINED
138+
struct wasm_ref_t;
139+
140+
typedef struct wasm_val_t {
141+
wasm_valkind_t kind;
142+
union {
143+
int32_t i32;
144+
int64_t i64;
145+
float f32;
146+
double f64;
147+
struct wasm_ref_t* ref;
148+
} of;
149+
} wasm_val_t;
150+
#endif
151+
123152
/**
124153
* Initialize the WASM runtime environment, and also initialize
125154
* the memory allocator with system allocator, which calls os_malloc
@@ -385,6 +414,50 @@ wasm_runtime_call_wasm(wasm_exec_env_t exec_env,
385414
wasm_function_inst_t function,
386415
uint32_t argc, uint32_t argv[]);
387416

417+
/**
418+
* Call the given WASM function of a WASM module instance with
419+
* provided results space and arguments (bytecode and AoT).
420+
*
421+
* @param exec_env the execution environment to call the function,
422+
* which must be created from wasm_create_exec_env()
423+
* @param function the function to call
424+
* @param num_results the number of results
425+
* @param results the pre-alloced pointer to get the results
426+
* @param num_args the number of arguments
427+
* @param args the arguments
428+
*
429+
* @return true if success, false otherwise and exception will be thrown,
430+
* the caller can call wasm_runtime_get_exception to get the exception
431+
* info.
432+
*/
433+
bool
434+
wasm_runtime_call_wasm_a(wasm_exec_env_t exec_env,
435+
wasm_function_inst_t function,
436+
uint32_t num_results, wasm_val_t results[],
437+
uint32_t num_args, wasm_val_t *args);
438+
439+
/**
440+
* Call the given WASM function of a WASM module instance with
441+
* provided results space and variant arguments (bytecode and AoT).
442+
*
443+
* @param exec_env the execution environment to call the function,
444+
* which must be created from wasm_create_exec_env()
445+
* @param function the function to call
446+
* @param num_results the number of results
447+
* @param results the pre-alloced pointer to get the results
448+
* @param num_args the number of arguments
449+
* @param ... the variant arguments
450+
*
451+
* @return true if success, false otherwise and exception will be thrown,
452+
* the caller can call wasm_runtime_get_exception to get the exception
453+
* info.
454+
*/
455+
bool
456+
wasm_runtime_call_wasm_v(wasm_exec_env_t exec_env,
457+
wasm_function_inst_t function,
458+
uint32_t num_results, wasm_val_t results[],
459+
uint32_t num_args, ...);
460+
388461
/**
389462
* Find the unique main function from a WASM module instance
390463
* and execute that function.

0 commit comments

Comments
 (0)