|
|
@@ -1199,46 +1199,163 @@ wasm_runtime_lookup_function(WASMModuleInstanceCommon *const module_inst,
|
|
|
}
|
|
|
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
-static void
|
|
|
-wasm_runtime_reclaim_externref(WASMExecEnv *exec_env,
|
|
|
- WASMFunctionInstanceCommon *function,
|
|
|
- uint32 *argv)
|
|
|
-{
|
|
|
- uint32 i = 0, cell_num = 0;
|
|
|
+/* (uintptr_t)externref -> (uint32_t)index */
|
|
|
+/* argv -> *ret_argv */
|
|
|
+static bool
|
|
|
+wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
|
|
|
+ WASMFunctionInstanceCommon *function,
|
|
|
+ uint32 *argv, uint32 argc, uint32 **ret_argv,
|
|
|
+ uint32 *ret_argc_param,
|
|
|
+ uint32 *ret_argc_result)
|
|
|
+{
|
|
|
+ uint32 *new_argv = NULL, argv_i = 0, new_argv_i = 0, param_i = 0,
|
|
|
+ result_i = 0;
|
|
|
+ bool need_param_transform = false, need_result_transform = false;
|
|
|
+ uint64 size = 0;
|
|
|
WASMType *func_type = wasm_runtime_get_function_type(
|
|
|
function, exec_env->module_inst->module_type);
|
|
|
+
|
|
|
bh_assert(func_type);
|
|
|
|
|
|
- while (i < func_type->result_count) {
|
|
|
- uint8 result_type = func_type->types[func_type->param_count + i];
|
|
|
- if (result_type == VALUE_TYPE_EXTERNREF && argv[i] != NULL_REF) {
|
|
|
- /* Retain the externref returned to runtime embedder */
|
|
|
- (void)wasm_externref_retain(argv[i]);
|
|
|
+ *ret_argc_param = func_type->param_cell_num;
|
|
|
+ *ret_argc_result = func_type->ret_cell_num;
|
|
|
+ for (param_i = 0; param_i < func_type->param_count; param_i++) {
|
|
|
+ if (VALUE_TYPE_EXTERNREF == func_type->types[param_i]) {
|
|
|
+ need_param_transform = true;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- cell_num += wasm_value_type_cell_num(result_type);
|
|
|
- i++;
|
|
|
+ for (result_i = 0; result_i < func_type->result_count; result_i++) {
|
|
|
+ if (VALUE_TYPE_EXTERNREF
|
|
|
+ == func_type->types[func_type->param_count + result_i]) {
|
|
|
+ need_result_transform = true;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- wasm_externref_reclaim(exec_env->module_inst);
|
|
|
-}
|
|
|
+ if (!need_param_transform && !need_result_transform) {
|
|
|
+ *ret_argv = argv;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
-void
|
|
|
-wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
|
|
|
- WASMFunctionInstanceCommon *function)
|
|
|
-{
|
|
|
- exec_env->nested_calling_depth++;
|
|
|
+ if (func_type->param_cell_num >= func_type->ret_cell_num) {
|
|
|
+ size = sizeof(uint32) * func_type->param_cell_num;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ size = sizeof(uint32) * func_type->ret_cell_num;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!(new_argv = runtime_malloc(size, exec_env->module_inst, NULL, 0))) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!need_param_transform) {
|
|
|
+ bh_memcpy_s(new_argv, size, argv, size);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ for (param_i = 0; param_i < func_type->param_count && argv_i < argc
|
|
|
+ && new_argv_i < func_type->param_cell_num;
|
|
|
+ param_i++) {
|
|
|
+ uint8 param_type = func_type->types[param_i];
|
|
|
+ if (VALUE_TYPE_EXTERNREF == param_type) {
|
|
|
+ void *externref_obj;
|
|
|
+ uint32 externref_index;
|
|
|
+
|
|
|
+#if UINTPTR_MAX == UINT32_MAX
|
|
|
+ externref_obj = (void *)argv[argv_i];
|
|
|
+#else
|
|
|
+ union {
|
|
|
+ uintptr_t val;
|
|
|
+ uint32 parts[2];
|
|
|
+ } u;
|
|
|
+
|
|
|
+ u.parts[0] = argv[argv_i];
|
|
|
+ u.parts[1] = argv[argv_i + 1];
|
|
|
+ externref_obj = (void *)u.val;
|
|
|
+#endif
|
|
|
+ if (!wasm_externref_obj2ref(exec_env->module_inst,
|
|
|
+ externref_obj, &externref_index)) {
|
|
|
+ wasm_runtime_free(new_argv);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ new_argv[new_argv_i] = externref_index;
|
|
|
+ argv_i += sizeof(uintptr_t) / sizeof(uint32);
|
|
|
+ new_argv_i++;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ uint16 param_cell_num = wasm_value_type_cell_num(param_type);
|
|
|
+ uint32 param_size = sizeof(uint32) * param_cell_num;
|
|
|
+ bh_memcpy_s(new_argv + new_argv_i, param_size, argv + argv_i,
|
|
|
+ param_size);
|
|
|
+ argv_i += param_cell_num;
|
|
|
+ new_argv_i += param_cell_num;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ *ret_argv = new_argv;
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
-void
|
|
|
+/* (uintptr_t)externref <- (uint32_t)index */
|
|
|
+/* argv <- new_argv */
|
|
|
+static bool
|
|
|
wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
|
|
|
WASMFunctionInstanceCommon *function,
|
|
|
- bool ret, uint32 *argv)
|
|
|
+ uint32 *argv, uint32 argc, uint32 *ret_argv)
|
|
|
{
|
|
|
- exec_env->nested_calling_depth--;
|
|
|
- if (!exec_env->nested_calling_depth && ret) {
|
|
|
- wasm_runtime_reclaim_externref(exec_env, function, argv);
|
|
|
+ uint32 argv_i = 0, result_i = 0, ret_argv_i = 0;
|
|
|
+ WASMType *func_type;
|
|
|
+
|
|
|
+ bh_assert(argv && ret_argv);
|
|
|
+
|
|
|
+ if (argv == ret_argv) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ func_type = wasm_runtime_get_function_type(
|
|
|
+ function, exec_env->module_inst->module_type);
|
|
|
+ bh_assert(func_type);
|
|
|
+
|
|
|
+ for (result_i = 0; result_i < func_type->result_count && argv_i < argc;
|
|
|
+ result_i++) {
|
|
|
+ uint8 result_type = func_type->types[func_type->param_count + result_i];
|
|
|
+ if (result_type == VALUE_TYPE_EXTERNREF) {
|
|
|
+ void *externref_obj;
|
|
|
+#if UINTPTR_MAX != UINT32_MAX
|
|
|
+ union {
|
|
|
+ uintptr_t val;
|
|
|
+ uint32 parts[2];
|
|
|
+ } u;
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (!wasm_externref_ref2obj(argv[argv_i], &externref_obj)) {
|
|
|
+ wasm_runtime_free(argv);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+#if UINTPTR_MAX == UINT32_MAX
|
|
|
+ ret_argv[ret_argv_i] = (uintptr_t)externref_obj;
|
|
|
+#else
|
|
|
+ u.val = (uintptr_t)externref_obj;
|
|
|
+ ret_argv[ret_argv_i] = u.parts[0];
|
|
|
+ ret_argv[ret_argv_i + 1] = u.parts[1];
|
|
|
+#endif
|
|
|
+ argv_i += 1;
|
|
|
+ ret_argv_i += sizeof(uintptr_t) / sizeof(uint32);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ uint16 result_cell_num = wasm_value_type_cell_num(result_type);
|
|
|
+ uint32 result_size = sizeof(uint32) * result_cell_num;
|
|
|
+ bh_memcpy_s(ret_argv + ret_argv_i, result_size, argv + argv_i,
|
|
|
+ result_size);
|
|
|
+ argv_i += result_cell_num;
|
|
|
+ ret_argv_i += result_cell_num;
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ wasm_runtime_free(argv);
|
|
|
+ return true;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
@@ -1248,6 +1365,10 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
|
|
|
uint32 argv[])
|
|
|
{
|
|
|
bool ret = false;
|
|
|
+ uint32 *new_argv = NULL, param_argc;
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ uint32 result_argc = 0;
|
|
|
+#endif
|
|
|
|
|
|
if (!wasm_runtime_exec_env_check(exec_env)) {
|
|
|
LOG_ERROR("Invalid exec env stack info.");
|
|
|
@@ -1255,34 +1376,53 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
|
|
|
}
|
|
|
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
- wasm_runtime_prepare_call_function(exec_env, function);
|
|
|
+ if (!wasm_runtime_prepare_call_function(exec_env, function, argv, argc,
|
|
|
+ &new_argv, ¶m_argc,
|
|
|
+ &result_argc)) {
|
|
|
+ wasm_runtime_set_exception(exec_env->module_inst,
|
|
|
+ "the arguments conversion is failed");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+#else
|
|
|
+ new_argv = argv;
|
|
|
+ param_argc = argc;
|
|
|
#endif
|
|
|
|
|
|
#if WASM_ENABLE_INTERP != 0
|
|
|
if (exec_env->module_inst->module_type == Wasm_Module_Bytecode)
|
|
|
ret = wasm_call_function(exec_env, (WASMFunctionInstance *)function,
|
|
|
- argc, argv);
|
|
|
+ param_argc, new_argv);
|
|
|
#endif
|
|
|
#if WASM_ENABLE_AOT != 0
|
|
|
if (exec_env->module_inst->module_type == Wasm_Module_AoT)
|
|
|
- ret = aot_call_function(exec_env, (AOTFunctionInstance *)function, argc,
|
|
|
- argv);
|
|
|
+ ret = aot_call_function(exec_env, (AOTFunctionInstance *)function,
|
|
|
+ param_argc, new_argv);
|
|
|
#endif
|
|
|
+ if (!ret) {
|
|
|
+ if (new_argv != argv) {
|
|
|
+ wasm_runtime_free(new_argv);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
- wasm_runtime_finalize_call_function(exec_env, function, ret, argv);
|
|
|
+ if (!wasm_runtime_finalize_call_function(exec_env, function, new_argv,
|
|
|
+ result_argc, argv)) {
|
|
|
+ wasm_runtime_set_exception(exec_env->module_inst,
|
|
|
+ "the result conversion is failed");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
#endif
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static uint32
|
|
|
-parse_args_to_uint32_array(WASMType *type, uint32 num_args, wasm_val_t *args,
|
|
|
- uint32 *out_argv)
|
|
|
+static void
|
|
|
+parse_args_to_uint32_array(WASMType *type, wasm_val_t *args, uint32 *out_argv)
|
|
|
{
|
|
|
uint32 i, p;
|
|
|
|
|
|
- for (i = 0, p = 0; i < num_args; i++) {
|
|
|
+ for (i = 0, p = 0; i < type->param_count; i++) {
|
|
|
switch (args[i].kind) {
|
|
|
case WASM_I32:
|
|
|
out_argv[p++] = args[i].of.i32;
|
|
|
@@ -1319,16 +1459,38 @@ parse_args_to_uint32_array(WASMType *type, uint32 num_args, wasm_val_t *args,
|
|
|
out_argv[p++] = u.parts[1];
|
|
|
break;
|
|
|
}
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case WASM_FUNCREF:
|
|
|
+ {
|
|
|
+ out_argv[p++] = args[i].of.i32;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case WASM_ANYREF:
|
|
|
+ {
|
|
|
+#if UINTPTR_MAX == UINT32_MAX
|
|
|
+ out_argv[p++] = args[i].of.foreign;
|
|
|
+#else
|
|
|
+ union {
|
|
|
+ uintptr_t val;
|
|
|
+ uint32 parts[2];
|
|
|
+ } u;
|
|
|
+
|
|
|
+ u.val = (uintptr_t)args[i].of.foreign;
|
|
|
+ out_argv[p++] = u.parts[0];
|
|
|
+ out_argv[p++] = u.parts[1];
|
|
|
+#endif
|
|
|
+ break;
|
|
|
+ }
|
|
|
+#endif
|
|
|
default:
|
|
|
bh_assert(0);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- return p;
|
|
|
}
|
|
|
|
|
|
-static uint32
|
|
|
-parse_uint32_array_to_results(WASMType *type, uint32 argc, uint32 *argv,
|
|
|
+static void
|
|
|
+parse_uint32_array_to_results(WASMType *type, uint32 *argv,
|
|
|
wasm_val_t *out_results)
|
|
|
{
|
|
|
uint32 i, p;
|
|
|
@@ -1374,13 +1536,36 @@ parse_uint32_array_to_results(WASMType *type, uint32 argc, uint32 *argv,
|
|
|
out_results[i].of.f64 = u.val;
|
|
|
break;
|
|
|
}
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case VALUE_TYPE_FUNCREF:
|
|
|
+ {
|
|
|
+ out_results[i].kind = WASM_I32;
|
|
|
+ out_results[i].of.i32 = (int32)argv[p++];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case VALUE_TYPE_EXTERNREF:
|
|
|
+ {
|
|
|
+#if UINTPTR_MAX == UINT32_MAX
|
|
|
+ out_results[i].kind = WASM_ANYREF;
|
|
|
+ out_results[i].of.foreign = (uintptr_t)argv[p++];
|
|
|
+#else
|
|
|
+ union {
|
|
|
+ uintptr_t val;
|
|
|
+ uint32 parts[2];
|
|
|
+ } u;
|
|
|
+ u.parts[0] = argv[p++];
|
|
|
+ u.parts[1] = argv[p++];
|
|
|
+ out_results[i].kind = WASM_ANYREF;
|
|
|
+ out_results[i].of.foreign = u.val;
|
|
|
+#endif
|
|
|
+ break;
|
|
|
+ }
|
|
|
+#endif
|
|
|
default:
|
|
|
bh_assert(0);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- bh_assert(argc == p);
|
|
|
- return type->result_count;
|
|
|
}
|
|
|
|
|
|
bool
|
|
|
@@ -1389,7 +1574,10 @@ wasm_runtime_call_wasm_a(WASMExecEnv *exec_env,
|
|
|
uint32 num_results, wasm_val_t results[],
|
|
|
uint32 num_args, wasm_val_t args[])
|
|
|
{
|
|
|
- uint32 argc, *argv, ret_num, cell_num, total_size, module_type;
|
|
|
+ uint32 argc, *argv, cell_num, total_size, module_type;
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ uint32 i, param_size_in_double_world = 0, result_size_in_double_world = 0;
|
|
|
+#endif
|
|
|
WASMType *type;
|
|
|
bool ret = false;
|
|
|
|
|
|
@@ -1402,8 +1590,23 @@ wasm_runtime_call_wasm_a(WASMExecEnv *exec_env,
|
|
|
goto fail1;
|
|
|
}
|
|
|
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ for (i = 0; i < type->param_count; i++) {
|
|
|
+ param_size_in_double_world +=
|
|
|
+ wasm_value_type_cell_num_outside(type->types[i]);
|
|
|
+ }
|
|
|
+ for (i = 0; i < type->result_count; i++) {
|
|
|
+ result_size_in_double_world += wasm_value_type_cell_num_outside(
|
|
|
+ type->types[type->param_count + i]);
|
|
|
+ }
|
|
|
+ argc = param_size_in_double_world;
|
|
|
+ cell_num = (argc >= result_size_in_double_world)
|
|
|
+ ? argc
|
|
|
+ : result_size_in_double_world;
|
|
|
+#else
|
|
|
argc = type->param_cell_num;
|
|
|
cell_num = (argc > type->ret_cell_num) ? argc : type->ret_cell_num;
|
|
|
+#endif
|
|
|
|
|
|
if (num_results != type->result_count) {
|
|
|
LOG_ERROR(
|
|
|
@@ -1425,14 +1628,11 @@ wasm_runtime_call_wasm_a(WASMExecEnv *exec_env,
|
|
|
goto fail1;
|
|
|
}
|
|
|
|
|
|
- argc = parse_args_to_uint32_array(type, num_args, args, argv);
|
|
|
- if (!(ret = wasm_runtime_call_wasm(exec_env, function, argc, argv)))
|
|
|
+ parse_args_to_uint32_array(type, args, argv);
|
|
|
+ if (!(ret = wasm_runtime_call_wasm(exec_env, function, num_args, argv)))
|
|
|
goto fail2;
|
|
|
|
|
|
- ret_num =
|
|
|
- parse_uint32_array_to_results(type, type->ret_cell_num, argv, results);
|
|
|
- bh_assert(ret_num == num_results);
|
|
|
- (void)ret_num;
|
|
|
+ parse_uint32_array_to_results(type, argv, results);
|
|
|
|
|
|
fail2:
|
|
|
wasm_runtime_free(argv);
|
|
|
@@ -1492,6 +1692,20 @@ wasm_runtime_call_wasm_v(WASMExecEnv *exec_env,
|
|
|
args[i].kind = WASM_F64;
|
|
|
args[i].of.f64 = va_arg(vargs, float64);
|
|
|
break;
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case VALUE_TYPE_FUNCREF:
|
|
|
+ {
|
|
|
+ args[i].kind = WASM_FUNCREF;
|
|
|
+ args[i].of.i32 = va_arg(vargs, uint32);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case VALUE_TYPE_EXTERNREF:
|
|
|
+ {
|
|
|
+ args[i].kind = WASM_ANYREF;
|
|
|
+ args[i].of.foreign = va_arg(vargs, uintptr_t);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+#endif
|
|
|
default:
|
|
|
bh_assert(0);
|
|
|
break;
|
|
|
@@ -1547,13 +1761,21 @@ WASMExecEnv *
|
|
|
wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst)
|
|
|
{
|
|
|
#if WASM_ENABLE_INTERP != 0
|
|
|
- if (module_inst->module_type == Wasm_Module_Bytecode)
|
|
|
+ if (module_inst->module_type == Wasm_Module_Bytecode) {
|
|
|
+ if (!((WASMModuleInstance *)module_inst)->exec_env_singleton) {
|
|
|
+ wasm_create_exec_env_singleton((WASMModuleInstance *)module_inst);
|
|
|
+ }
|
|
|
return ((WASMModuleInstance *)module_inst)->exec_env_singleton;
|
|
|
+ }
|
|
|
#endif
|
|
|
#if WASM_ENABLE_AOT != 0
|
|
|
- if (module_inst->module_type == Wasm_Module_AoT)
|
|
|
+ if (module_inst->module_type == Wasm_Module_AoT) {
|
|
|
+ if (!((AOTModuleInstance *)module_inst)->exec_env_singleton.ptr) {
|
|
|
+ aot_create_exec_env_singleton((AOTModuleInstance *)module_inst);
|
|
|
+ }
|
|
|
return (WASMExecEnv *)((AOTModuleInstance *)module_inst)
|
|
|
->exec_env_singleton.ptr;
|
|
|
+ }
|
|
|
#endif
|
|
|
return NULL;
|
|
|
}
|
|
|
@@ -2497,6 +2719,9 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
for (i = 0; i < func_type->param_count; i++, argv_dst++) {
|
|
|
switch (func_type->types[i]) {
|
|
|
case VALUE_TYPE_I32:
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case VALUE_TYPE_FUNCREF:
|
|
|
+#endif
|
|
|
{
|
|
|
*(uint32 *)argv_dst = arg_i32 = *argv_src++;
|
|
|
if (signature) {
|
|
|
@@ -2540,10 +2765,19 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
*(float32 *)argv_dst = *(float32 *)argv_src++;
|
|
|
break;
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
- case VALUE_TYPE_FUNCREF:
|
|
|
case VALUE_TYPE_EXTERNREF:
|
|
|
- *(uint32 *)argv_dst = *argv_src++;
|
|
|
+ {
|
|
|
+ uint32 externref_idx = *argv_src++;
|
|
|
+
|
|
|
+ void *externref_obj;
|
|
|
+
|
|
|
+ if (!wasm_externref_ref2obj(externref_idx, &externref_obj))
|
|
|
+ goto fail;
|
|
|
+
|
|
|
+ bh_memcpy_s(argv_dst, sizeof(uintptr_t), argv_src,
|
|
|
+ sizeof(uintptr_t));
|
|
|
break;
|
|
|
+ }
|
|
|
#endif
|
|
|
default:
|
|
|
bh_assert(0);
|
|
|
@@ -2560,7 +2794,6 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
case VALUE_TYPE_I32:
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
case VALUE_TYPE_FUNCREF:
|
|
|
- case VALUE_TYPE_EXTERNREF:
|
|
|
#endif
|
|
|
argv_ret[0] = *(uint32 *)argv1;
|
|
|
break;
|
|
|
@@ -2572,6 +2805,23 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
bh_memcpy_s(argv_ret, sizeof(uint32) * 2, argv1,
|
|
|
sizeof(uint64));
|
|
|
break;
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case VALUE_TYPE_EXTERNREF:
|
|
|
+ {
|
|
|
+ uint32 externref_idx;
|
|
|
+ uint64 externref_obj;
|
|
|
+
|
|
|
+ bh_memcpy_s(&externref_obj, sizeof(uint64), argv1,
|
|
|
+ sizeof(uint64));
|
|
|
+
|
|
|
+ if (!wasm_externref_obj2ref(exec_env->module_inst,
|
|
|
+ (void *)(uintptr_t)externref_obj,
|
|
|
+ &externref_idx))
|
|
|
+ goto fail;
|
|
|
+ argv_ret[0] = externref_idx;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+#endif
|
|
|
default:
|
|
|
bh_assert(0);
|
|
|
break;
|
|
|
@@ -2634,6 +2884,9 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
uint32 result_count = func_type->result_count;
|
|
|
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
|
|
|
bool ret = false;
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ bool is_aot_func = (NULL == signature);
|
|
|
+#endif
|
|
|
#if !defined(BUILD_TARGET_RISCV32_ILP32) && !defined(BUILD_TARGET_ARC)
|
|
|
uint32 *fps;
|
|
|
int n_fps = 0;
|
|
|
@@ -2792,6 +3045,9 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
for (i = 0; i < func_type->param_count; i++) {
|
|
|
switch (func_type->types[i]) {
|
|
|
case VALUE_TYPE_I32:
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case VALUE_TYPE_FUNCREF:
|
|
|
+#endif
|
|
|
{
|
|
|
arg_i32 = *argv_src++;
|
|
|
|
|
|
@@ -2829,17 +3085,6 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
stacks[n_stacks++] = arg_i32;
|
|
|
break;
|
|
|
}
|
|
|
-#if WASM_ENABLE_REF_TYPES != 0
|
|
|
- case VALUE_TYPE_FUNCREF:
|
|
|
- case VALUE_TYPE_EXTERNREF:
|
|
|
- {
|
|
|
- if (n_ints < MAX_REG_INTS)
|
|
|
- ints[n_ints++] = *argv_src++;
|
|
|
- else
|
|
|
- stacks[n_stacks++] = *argv_src++;
|
|
|
- break;
|
|
|
- }
|
|
|
-#endif
|
|
|
case VALUE_TYPE_I64:
|
|
|
{
|
|
|
if (n_ints < MAX_REG_INTS - 1) {
|
|
|
@@ -2959,6 +3204,31 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
break;
|
|
|
}
|
|
|
#endif /* BUILD_TARGET_RISCV32_ILP32D */
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case VALUE_TYPE_EXTERNREF:
|
|
|
+ {
|
|
|
+ uint32 externref_idx = *argv_src++;
|
|
|
+
|
|
|
+ if (is_aot_func) {
|
|
|
+ if (n_ints < MAX_REG_INTS)
|
|
|
+ ints[n_ints++] = externref_idx;
|
|
|
+ else
|
|
|
+ stacks[n_stacks++] = externref_idx;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ void *externref_obj;
|
|
|
+
|
|
|
+ if (!wasm_externref_ref2obj(externref_idx, &externref_obj))
|
|
|
+ goto fail;
|
|
|
+
|
|
|
+ if (n_ints < MAX_REG_INTS)
|
|
|
+ ints[n_ints++] = (uintptr_t)externref_obj;
|
|
|
+ else
|
|
|
+ stacks[n_stacks++] = (uintptr_t)externref_obj;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+#endif
|
|
|
default:
|
|
|
bh_assert(0);
|
|
|
break;
|
|
|
@@ -2982,7 +3252,6 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
case VALUE_TYPE_I32:
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
case VALUE_TYPE_FUNCREF:
|
|
|
- case VALUE_TYPE_EXTERNREF:
|
|
|
#endif
|
|
|
argv_ret[0] =
|
|
|
(uint32)invokeNative_Int32(func_ptr, argv1, n_stacks);
|
|
|
@@ -2999,6 +3268,30 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
PUT_F64_TO_ADDR(
|
|
|
argv_ret, invokeNative_Float64(func_ptr, argv1, n_stacks));
|
|
|
break;
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case VALUE_TYPE_EXTERNREF:
|
|
|
+ {
|
|
|
+ if (is_aot_func) {
|
|
|
+ uint32 externref_idx =
|
|
|
+ (uint32)invokeNative_Int32(func_ptr, argv1, argc1);
|
|
|
+ argv_ret[0] = externref_idx;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ uint32 externref_idx;
|
|
|
+ void *externref_obj;
|
|
|
+
|
|
|
+ externref_obj = (void *)(uintptr_t)invokeNative_Int32(
|
|
|
+ func_ptr, argv1, argc1);
|
|
|
+
|
|
|
+ if (!wasm_externref_obj2ref(exec_env->module_inst,
|
|
|
+ externref_obj, &externref_idx))
|
|
|
+ goto fail;
|
|
|
+
|
|
|
+ argv_ret[0] = externref_idx;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+#endif
|
|
|
default:
|
|
|
bh_assert(0);
|
|
|
break;
|
|
|
@@ -3060,6 +3353,9 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
|
|
|
uint64 size;
|
|
|
bool ret = false;
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ bool is_aot_func = (NULL == signature);
|
|
|
+#endif
|
|
|
|
|
|
#if defined(BUILD_TARGET_X86_32)
|
|
|
argc1 = argc + ext_ret_count + 2;
|
|
|
@@ -3083,6 +3379,9 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
for (i = 0; i < func_type->param_count; i++) {
|
|
|
switch (func_type->types[i]) {
|
|
|
case VALUE_TYPE_I32:
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case VALUE_TYPE_FUNCREF:
|
|
|
+#endif
|
|
|
{
|
|
|
arg_i32 = *argv++;
|
|
|
|
|
|
@@ -3129,12 +3428,26 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
argv1[j++] = *argv++;
|
|
|
break;
|
|
|
case VALUE_TYPE_F32:
|
|
|
+ argv1[j++] = *argv++;
|
|
|
+ break;
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
- case VALUE_TYPE_FUNCREF:
|
|
|
case VALUE_TYPE_EXTERNREF:
|
|
|
-#endif
|
|
|
- argv1[j++] = *argv++;
|
|
|
+ {
|
|
|
+ uint32 externref_idx = *argv++;
|
|
|
+ if (is_aot_func) {
|
|
|
+ argv1[j++] = externref_idx;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ void *externref_obj;
|
|
|
+
|
|
|
+ if (!wasm_externref_ref2obj(externref_idx, &externref_obj))
|
|
|
+ goto fail;
|
|
|
+
|
|
|
+ argv1[j++] = (uintptr_t)externref_obj;
|
|
|
+ }
|
|
|
break;
|
|
|
+ }
|
|
|
+#endif
|
|
|
default:
|
|
|
bh_assert(0);
|
|
|
break;
|
|
|
@@ -3154,7 +3467,6 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
case VALUE_TYPE_I32:
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
case VALUE_TYPE_FUNCREF:
|
|
|
- case VALUE_TYPE_EXTERNREF:
|
|
|
#endif
|
|
|
argv_ret[0] =
|
|
|
(uint32)invokeNative_Int32(func_ptr, argv1, argc1);
|
|
|
@@ -3171,6 +3483,26 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
PUT_F64_TO_ADDR(argv_ret,
|
|
|
invokeNative_Float64(func_ptr, argv1, argc1));
|
|
|
break;
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case VALUE_TYPE_EXTERNREF:
|
|
|
+ {
|
|
|
+ if (is_aot_func) {
|
|
|
+ uint32 externref_idx =
|
|
|
+ (uint32)invokeNative_Int32(func_ptr, argv1, argc1);
|
|
|
+ argv_ret[0] = externref_idx;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ void *externref_obj = (void *)(uintptr_t)invokeNative_Int32(
|
|
|
+ func_ptr, argv1, argc1);
|
|
|
+ uint32 externref_idx;
|
|
|
+ if (!wasm_externref_obj2ref(exec_env->module_inst,
|
|
|
+ externref_obj, &externref_idx))
|
|
|
+ goto fail;
|
|
|
+ argv_ret[0] = externref_idx;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+#endif
|
|
|
default:
|
|
|
bh_assert(0);
|
|
|
break;
|
|
|
@@ -3281,12 +3613,16 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
uint32 *argv_ret)
|
|
|
{
|
|
|
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
|
|
|
- uint64 argv_buf[32], *argv1 = argv_buf, *ints, *stacks, size, arg_i64;
|
|
|
+ uint64 argv_buf[32] = { 0 }, *argv1 = argv_buf, *ints, *stacks, size,
|
|
|
+ arg_i64;
|
|
|
uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0;
|
|
|
uint32 arg_i32, ptr_len;
|
|
|
uint32 result_count = func_type->result_count;
|
|
|
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
|
|
|
bool ret = false;
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ bool is_aot_func = (NULL == signature);
|
|
|
+#endif
|
|
|
#ifndef BUILD_TARGET_RISCV64_LP64
|
|
|
#if WASM_ENABLE_SIMD == 0
|
|
|
uint64 *fps;
|
|
|
@@ -3336,6 +3672,9 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
for (i = 0; i < func_type->param_count; i++) {
|
|
|
switch (func_type->types[i]) {
|
|
|
case VALUE_TYPE_I32:
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case VALUE_TYPE_FUNCREF:
|
|
|
+#endif
|
|
|
{
|
|
|
arg_i32 = *argv_src++;
|
|
|
arg_i64 = arg_i32;
|
|
|
@@ -3397,13 +3736,28 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
argv_src += 2;
|
|
|
break;
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
- case VALUE_TYPE_FUNCREF:
|
|
|
case VALUE_TYPE_EXTERNREF:
|
|
|
- if (n_ints < MAX_REG_INTS)
|
|
|
- ints[n_ints++] = *argv_src++;
|
|
|
- else
|
|
|
- stacks[n_stacks++] = *argv_src++;
|
|
|
+ {
|
|
|
+ uint32 externref_idx = *argv_src++;
|
|
|
+ if (is_aot_func) {
|
|
|
+ if (n_ints < MAX_REG_INTS)
|
|
|
+ ints[n_ints++] = externref_idx;
|
|
|
+ else
|
|
|
+ stacks[n_stacks++] = externref_idx;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ void *externref_obj;
|
|
|
+
|
|
|
+ if (!wasm_externref_ref2obj(externref_idx, &externref_obj))
|
|
|
+ goto fail;
|
|
|
+
|
|
|
+ if (n_ints < MAX_REG_INTS)
|
|
|
+ ints[n_ints++] = (uintptr_t)externref_obj;
|
|
|
+ else
|
|
|
+ stacks[n_stacks++] = (uintptr_t)externref_obj;
|
|
|
+ }
|
|
|
break;
|
|
|
+ }
|
|
|
#endif
|
|
|
#if WASM_ENABLE_SIMD != 0
|
|
|
case VALUE_TYPE_V128:
|
|
|
@@ -3442,7 +3796,6 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
case VALUE_TYPE_I32:
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
case VALUE_TYPE_FUNCREF:
|
|
|
- case VALUE_TYPE_EXTERNREF:
|
|
|
#endif
|
|
|
argv_ret[0] =
|
|
|
(uint32)invokeNative_Int32(func_ptr, argv1, n_stacks);
|
|
|
@@ -3459,6 +3812,26 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
|
|
PUT_F64_TO_ADDR(
|
|
|
argv_ret, invokeNative_Float64(func_ptr, argv1, n_stacks));
|
|
|
break;
|
|
|
+#if WASM_ENABLE_REF_TYPES != 0
|
|
|
+ case VALUE_TYPE_EXTERNREF:
|
|
|
+ {
|
|
|
+ if (is_aot_func) {
|
|
|
+ argv_ret[0] = invokeNative_Int32(func_ptr, argv1, n_stacks);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ uint32 externref_idx;
|
|
|
+ void *externref_obj = (void *)(uintptr_t)invokeNative_Int64(
|
|
|
+ func_ptr, argv1, n_stacks);
|
|
|
+
|
|
|
+ if (!wasm_externref_obj2ref(exec_env->module_inst,
|
|
|
+ externref_obj, &externref_idx))
|
|
|
+ goto fail;
|
|
|
+
|
|
|
+ argv_ret[0] = externref_idx;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+#endif
|
|
|
#if WASM_ENABLE_SIMD != 0
|
|
|
case VALUE_TYPE_V128:
|
|
|
*(v128 *)argv_ret =
|
|
|
@@ -3709,10 +4082,24 @@ bool
|
|
|
wasm_externref_obj2ref(WASMModuleInstanceCommon *module_inst, void *extern_obj,
|
|
|
uint32 *p_externref_idx)
|
|
|
{
|
|
|
- LookupExtObj_UserData lookup_user_data;
|
|
|
+ LookupExtObj_UserData lookup_user_data = { 0 };
|
|
|
ExternRefMapNode *node;
|
|
|
uint32 externref_idx;
|
|
|
|
|
|
+ /*
|
|
|
+ * to catch a parameter from `wasm_application_execute_func`,
|
|
|
+ * which represents a string 'null'
|
|
|
+ */
|
|
|
+#if UINTPTR_MAX == UINT32_MAX
|
|
|
+ if ((uint32)-1 == (uintptr_t)extern_obj) {
|
|
|
+#else
|
|
|
+ if ((uint64)-1LL == (uintptr_t)extern_obj) {
|
|
|
+#endif
|
|
|
+ *p_externref_idx = NULL_REF;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* in a wrapper, extern_obj could be any value */
|
|
|
lookup_user_data.node.extern_obj = extern_obj;
|
|
|
lookup_user_data.node.module_inst = module_inst;
|
|
|
lookup_user_data.found = false;
|
|
|
@@ -3764,8 +4151,10 @@ wasm_externref_ref2obj(uint32 externref_idx, void **p_extern_obj)
|
|
|
{
|
|
|
ExternRefMapNode *node;
|
|
|
|
|
|
+ /* catch a `ref.null` vairable */
|
|
|
if (externref_idx == NULL_REF) {
|
|
|
- return false;
|
|
|
+ *p_extern_obj = NULL;
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
os_mutex_lock(&externref_lock);
|
|
|
@@ -4170,14 +4559,9 @@ argv_to_params(wasm_val_t *out_params, const uint32 *argv, WASMType *func_type)
|
|
|
case VALUE_TYPE_EXTERNREF:
|
|
|
param->kind = WASM_ANYREF;
|
|
|
|
|
|
- if (NULL_REF == *argv) {
|
|
|
- param->of.ref = NULL;
|
|
|
- }
|
|
|
- else {
|
|
|
- if (!wasm_externref_ref2obj(*argv,
|
|
|
- (void **)¶m->of.ref)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
+ if (!wasm_externref_ref2obj(*argv,
|
|
|
+ (void **)¶m->of.foreign)) {
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
argv++;
|
|
|
@@ -4213,8 +4597,8 @@ results_to_argv(WASMModuleInstanceCommon *module_inst, uint32 *out_argv,
|
|
|
break;
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
case VALUE_TYPE_EXTERNREF:
|
|
|
- if (!wasm_externref_obj2ref(module_inst, result->of.ref,
|
|
|
- argv)) {
|
|
|
+ if (!wasm_externref_obj2ref(module_inst,
|
|
|
+ (void *)result->of.foreign, argv)) {
|
|
|
return false;
|
|
|
}
|
|
|
argv++;
|
|
|
@@ -4234,17 +4618,19 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
|
|
|
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_buf[16] = { 0 }, results_buf[4] = { 0 };
|
|
|
wasm_val_t *params = params_buf, *results = results_buf;
|
|
|
wasm_trap_t *trap = NULL;
|
|
|
bool ret = false;
|
|
|
wasm_val_vec_t params_vec, results_vec;
|
|
|
|
|
|
- if (func_type->param_count > 16
|
|
|
- && !(params = wasm_runtime_malloc(sizeof(wasm_val_t)
|
|
|
- * func_type->param_count))) {
|
|
|
- wasm_runtime_set_exception(module_inst, "allocate memory failed");
|
|
|
- return false;
|
|
|
+ if (func_type->param_count > 16) {
|
|
|
+ if (!(params =
|
|
|
+ runtime_malloc(sizeof(wasm_val_t) * func_type->param_count,
|
|
|
+ module_inst, NULL, 0))) {
|
|
|
+ wasm_runtime_set_exception(module_inst, "allocate memory failed");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (!argv_to_params(params, argv, func_type)) {
|
|
|
@@ -4252,11 +4638,13 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
|
|
|
goto fail;
|
|
|
}
|
|
|
|
|
|
- if (func_type->result_count > 4
|
|
|
- && !(results = wasm_runtime_malloc(sizeof(wasm_val_t)
|
|
|
- * func_type->result_count))) {
|
|
|
- wasm_runtime_set_exception(module_inst, "allocate memory failed");
|
|
|
- goto fail;
|
|
|
+ if (func_type->result_count > 4) {
|
|
|
+ if (!(results =
|
|
|
+ runtime_malloc(sizeof(wasm_val_t) * func_type->result_count,
|
|
|
+ module_inst, NULL, 0))) {
|
|
|
+ wasm_runtime_set_exception(module_inst, "allocate memory failed");
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
params_vec.data = params;
|