Refactor externref related APIs of reference types feature (#971)
Currently when calling wasm_runtime_call_wasm() to invoke wasm function with externref type argument from runtime embedder, developer needs to use wasm_externref_obj2ref() to convert externref obj into an internal ref index firstly, which is not convenient to developer. To align with GC feature in which all the references passed to wasm_runtime_call_wasm() can be object pointers directly, we change the interface of wasm_runtime_call_wasm() to allow to pass object pointer directly for the externref argument, and refactor the related codes, update the related samples and the document.
This commit is contained in:
@ -854,6 +854,7 @@ load_import_table_list(const uint8 **p_buf, const uint8 *buf_end,
|
||||
|
||||
/* keep sync with aot_emit_table_info() aot_emit_aot_file */
|
||||
for (i = 0; i < module->import_table_count; i++, import_table++) {
|
||||
read_uint32(buf, buf_end, import_table->elem_type);
|
||||
read_uint32(buf, buf_end, import_table->table_init_size);
|
||||
read_uint32(buf, buf_end, import_table->table_max_size);
|
||||
read_uint32(buf, buf_end, possible_grow);
|
||||
|
||||
@ -85,7 +85,7 @@ init_global_data(uint8 *global_data, uint8 type, WASMValue *initial_value)
|
||||
switch (type) {
|
||||
case VALUE_TYPE_I32:
|
||||
case VALUE_TYPE_F32:
|
||||
#if WASM_ENABLE_REF_TYPES
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
#endif
|
||||
@ -1572,16 +1572,8 @@ aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
|
||||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
wasm_runtime_prepare_call_function(exec_env, func);
|
||||
#endif
|
||||
|
||||
ret = aot_call_function(exec_env, func, argc, argv);
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
wasm_runtime_finalize_call_function(exec_env, func, ret, argv);
|
||||
#endif
|
||||
|
||||
/* don't destroy the exec_env if it's searched from the cluster */
|
||||
if (!existing_exec_env)
|
||||
wasm_exec_env_destroy(exec_env);
|
||||
|
||||
@ -82,6 +82,7 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
|
||||
{
|
||||
WASMFunctionInstanceCommon *func;
|
||||
WASMType *func_type = NULL;
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
uint32 argc1 = 0, argv1[2] = { 0 };
|
||||
uint32 total_argv_size = 0;
|
||||
uint64 total_size;
|
||||
@ -91,14 +92,20 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
|
||||
uint32 *argv_offsets, module_type;
|
||||
bool ret, is_import_func = true;
|
||||
|
||||
exec_env = wasm_runtime_get_exec_env_singleton(module_inst);
|
||||
if (!exec_env) {
|
||||
wasm_runtime_set_exception(module_inst,
|
||||
"create singleton exec_env failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
/* In wasi mode, we should call the function named "_start"
|
||||
which initializes the wasi envrionment and then calls
|
||||
the actual main function. Directly calling main function
|
||||
may cause exception thrown. */
|
||||
if ((func = wasm_runtime_lookup_wasi_start_function(module_inst))) {
|
||||
return wasm_runtime_create_exec_env_and_call_wasm(module_inst, func, 0,
|
||||
NULL);
|
||||
return wasm_runtime_call_wasm(exec_env, func, 0, NULL);
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_LIBC_WASI */
|
||||
|
||||
@ -179,8 +186,7 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
|
||||
(uint32)wasm_runtime_addr_native_to_app(module_inst, argv_offsets);
|
||||
}
|
||||
|
||||
ret = wasm_runtime_create_exec_env_and_call_wasm(module_inst, func, argc1,
|
||||
argv1);
|
||||
ret = wasm_runtime_call_wasm(exec_env, func, argc1, argv1);
|
||||
if (ret && func_type->result_count > 0 && argc > 0 && argv)
|
||||
/* copy the return value */
|
||||
*(int *)argv = (int)argv1[0];
|
||||
@ -345,7 +351,11 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
|
||||
WASMFunctionInstanceCommon *target_func;
|
||||
WASMModuleInstanceCommon *target_inst;
|
||||
WASMType *type = NULL;
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
uint32 argc1, *argv1 = NULL, cell_num = 0, j, k = 0;
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
uint32 param_size_in_double_world = 0, result_size_in_double_world = 0;
|
||||
#endif
|
||||
int32 i, p, module_type;
|
||||
uint64 total_size;
|
||||
const char *exception;
|
||||
@ -373,8 +383,23 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#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]);
|
||||
}
|
||||
argc1 = param_size_in_double_world;
|
||||
cell_num = (param_size_in_double_world >= result_size_in_double_world)
|
||||
? param_size_in_double_world
|
||||
: result_size_in_double_world;
|
||||
#else
|
||||
argc1 = type->param_cell_num;
|
||||
cell_num = (argc1 > type->ret_cell_num) ? argc1 : type->ret_cell_num;
|
||||
#endif
|
||||
|
||||
total_size = sizeof(uint32) * (uint64)(cell_num > 2 ? cell_num : 2);
|
||||
if ((!(argv1 = runtime_malloc((uint32)total_size, target_inst, NULL, 0)))) {
|
||||
@ -487,9 +512,8 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
{
|
||||
if (strncmp(argv[i], "null", 4) == 0
|
||||
|| strncmp(argv[i], "NULL", 4) == 0) {
|
||||
argv1[p++] = NULL_REF;
|
||||
if (strncasecmp(argv[i], "null", 4) == 0) {
|
||||
argv1[p++] = (uint32)-1;
|
||||
}
|
||||
else {
|
||||
argv1[p++] = (uint32)strtoul(argv[i], &endptr, 0);
|
||||
@ -498,23 +522,27 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
|
||||
}
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
{
|
||||
if (strncmp(argv[i], "null", 4) == 0
|
||||
|| strncmp(argv[i], "NULL", 4) == 0) {
|
||||
argv1[p++] = NULL_REF;
|
||||
#if UINTPTR_MAX == UINT32_MAX
|
||||
if (strncasecmp(argv[i], "null", 4) == 0) {
|
||||
argv1[p++] = (uint32)-1;
|
||||
}
|
||||
else {
|
||||
uint64 val = strtoull(argv[i], &endptr, 0);
|
||||
void *extern_obj = (void *)(uintptr_t)val;
|
||||
uint32 externref_idx;
|
||||
|
||||
if (!wasm_externref_obj2ref(target_inst, extern_obj,
|
||||
&externref_idx)) {
|
||||
wasm_runtime_set_exception(
|
||||
module_inst, "map extern object to ref failed");
|
||||
goto fail;
|
||||
}
|
||||
argv1[p++] = externref_idx;
|
||||
argv1[p++] = strtoul(argv[i], &endptr, 0);
|
||||
}
|
||||
#else
|
||||
union {
|
||||
uintptr_t val;
|
||||
uint32 parts[2];
|
||||
} u;
|
||||
if (strncasecmp(argv[i], "null", 4) == 0) {
|
||||
u.val = (uintptr_t)-1LL;
|
||||
}
|
||||
else {
|
||||
u.val = strtoull(argv[i], &endptr, 0);
|
||||
}
|
||||
argv1[p++] = u.parts[0];
|
||||
argv1[p++] = u.parts[1];
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif /* WASM_ENABLE_REF_TYPES */
|
||||
@ -529,11 +557,20 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
bh_assert(p == (int32)argc1);
|
||||
|
||||
wasm_runtime_set_exception(module_inst, NULL);
|
||||
if (!wasm_runtime_create_exec_env_and_call_wasm(target_inst, target_func,
|
||||
argc1, argv1)) {
|
||||
#if WASM_ENABLE_REF_TYPES == 0
|
||||
bh_assert(p == (int32)argc1);
|
||||
#endif
|
||||
|
||||
exec_env = wasm_runtime_get_exec_env_singleton(module_inst);
|
||||
if (!exec_env) {
|
||||
wasm_runtime_set_exception(module_inst,
|
||||
"create singleton exec_env failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!wasm_runtime_call_wasm(exec_env, target_func, argc1, argv1)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -576,7 +613,7 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
|
||||
os_printf("%.7g:f64", u.val);
|
||||
break;
|
||||
}
|
||||
#if WASM_ENABLE_REF_TYPES
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
{
|
||||
if (argv1[k] != NULL_REF)
|
||||
@ -588,16 +625,25 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
|
||||
}
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
{
|
||||
if (argv1[k] != NULL_REF) {
|
||||
void *extern_obj = NULL;
|
||||
bool ret = wasm_externref_ref2obj(argv1[k], &extern_obj);
|
||||
bh_assert(ret);
|
||||
(void)ret;
|
||||
os_printf("%p:ref.extern", extern_obj);
|
||||
}
|
||||
#if UINTPTR_MAX == UINT32_MAX
|
||||
if (argv1[k] != 0 && argv1[k] != (uint32)-1)
|
||||
os_printf("%p:ref.extern", (void *)argv1[k]);
|
||||
else
|
||||
os_printf("extern:ref.null");
|
||||
k++;
|
||||
#else
|
||||
union {
|
||||
uintptr_t val;
|
||||
uint32 parts[2];
|
||||
} u;
|
||||
u.parts[0] = argv1[k];
|
||||
u.parts[1] = argv1[k + 1];
|
||||
k += 2;
|
||||
if (u.val && u.val != (uintptr_t)-1LL)
|
||||
os_printf("%p:ref.extern", (void *)u.val);
|
||||
else
|
||||
os_printf("extern:ref.null");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1235,9 +1235,8 @@ wasm_exporttype_type(const wasm_exporttype_t *export_type)
|
||||
void
|
||||
wasm_val_delete(wasm_val_t *v)
|
||||
{
|
||||
if (v) {
|
||||
if (v)
|
||||
wasm_runtime_free(v);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1562,19 +1561,13 @@ wasm_trap_new_internal(WASMModuleInstanceCommon *inst_comm_rt,
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (inst_comm_rt->module_type == Wasm_Module_Bytecode) {
|
||||
if (!(error_info =
|
||||
wasm_get_exception((WASMModuleInstance *)inst_comm_rt))) {
|
||||
return NULL;
|
||||
}
|
||||
error_info = wasm_get_exception((WASMModuleInstance *)inst_comm_rt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (inst_comm_rt->module_type == Wasm_Module_AoT) {
|
||||
if (!(error_info =
|
||||
aot_get_exception((AOTModuleInstance *)inst_comm_rt))) {
|
||||
return NULL;
|
||||
}
|
||||
error_info = aot_get_exception((AOTModuleInstance *)inst_comm_rt);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2160,7 +2153,7 @@ wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out)
|
||||
- import_memory_count);
|
||||
module_name_rt = import->module_name;
|
||||
field_name_rt = import->table_name;
|
||||
elem_type_rt = VALUE_TYPE_FUNCREF;
|
||||
elem_type_rt = import->elem_type;
|
||||
min_size = import->table_init_size;
|
||||
max_size = import->table_max_size;
|
||||
}
|
||||
@ -2563,151 +2556,127 @@ wasm_func_type(const wasm_func_t *func)
|
||||
return wasm_functype_copy(func->type);
|
||||
}
|
||||
|
||||
static uint32
|
||||
params_to_argv(WASMModuleInstanceCommon *inst_comm_rt, const wasm_val_t *params,
|
||||
const wasm_valtype_vec_t *param_defs, size_t param_arity,
|
||||
uint32 *out)
|
||||
static bool
|
||||
params_to_argv(const wasm_val_vec_t *params,
|
||||
const wasm_valtype_vec_t *param_defs, uint32 *argv,
|
||||
uint32 *ptr_argc)
|
||||
{
|
||||
size_t i = 0;
|
||||
uint32 argc = 0;
|
||||
const wasm_val_t *param = NULL;
|
||||
|
||||
if (!param_arity) {
|
||||
return 0;
|
||||
if (!param_defs->num_elems) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bh_assert(params && param_defs && out);
|
||||
bh_assert(param_defs->num_elems == param_arity);
|
||||
if (!params || !params->num_elems || !params->size || !params->data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; out && i < param_arity; ++i) {
|
||||
param = params + i;
|
||||
*ptr_argc = 0;
|
||||
for (i = 0; i < param_defs->num_elems; ++i) {
|
||||
const wasm_val_t *param = params->data + i;
|
||||
bh_assert((*(param_defs->data + i))->kind == param->kind);
|
||||
|
||||
switch (param->kind) {
|
||||
case WASM_I32:
|
||||
*(int32 *)out = param->of.i32;
|
||||
out += 1;
|
||||
argc += 1;
|
||||
*(int32 *)argv = param->of.i32;
|
||||
argv += 1;
|
||||
*ptr_argc += 1;
|
||||
break;
|
||||
case WASM_I64:
|
||||
*(int64 *)out = param->of.i64;
|
||||
out += 2;
|
||||
argc += 2;
|
||||
*(int64 *)argv = param->of.i64;
|
||||
argv += 2;
|
||||
*ptr_argc += 2;
|
||||
break;
|
||||
case WASM_F32:
|
||||
*(float32 *)out = param->of.f32;
|
||||
out += 1;
|
||||
argc += 1;
|
||||
*(float32 *)argv = param->of.f32;
|
||||
argv += 1;
|
||||
*ptr_argc += 1;
|
||||
break;
|
||||
case WASM_F64:
|
||||
*(float64 *)out = param->of.f64;
|
||||
out += 2;
|
||||
argc += 2;
|
||||
*(float64 *)argv = param->of.f64;
|
||||
argv += 2;
|
||||
*ptr_argc += 2;
|
||||
break;
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
case WASM_ANYREF:
|
||||
if (!wasm_externref_obj2ref(inst_comm_rt, param->of.ref, out)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
out += 1;
|
||||
argc += 1;
|
||||
*(uintptr_t *)argv = (uintptr_t)param->of.ref;
|
||||
argv += sizeof(uintptr_t) / sizeof(uint32);
|
||||
*ptr_argc += 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
LOG_WARNING("unexpected parameter val type %d", param->kind);
|
||||
goto failed;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return argc;
|
||||
|
||||
failed:
|
||||
LOG_DEBUG("%s failed", __FUNCTION__);
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32
|
||||
argv_to_results(const uint32 *results, const wasm_valtype_vec_t *result_defs,
|
||||
size_t result_arity, wasm_val_t *out)
|
||||
static bool
|
||||
argv_to_results(const uint32 *argv, const wasm_valtype_vec_t *result_defs,
|
||||
wasm_val_vec_t *results)
|
||||
{
|
||||
size_t i = 0;
|
||||
uint32 argc = 0;
|
||||
const uint32 *result = results;
|
||||
const wasm_valtype_t *def = NULL;
|
||||
size_t i = 0, argv_i = 0;
|
||||
wasm_val_t *result;
|
||||
|
||||
if (!result_arity) {
|
||||
return 0;
|
||||
if (!result_defs->num_elems) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bh_assert(results && result_defs && out);
|
||||
bh_assert(result_arity == result_defs->num_elems);
|
||||
if (!results || !results->num_elems || !results->size || !results->data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; out && i < result_arity; i++) {
|
||||
def = *(result_defs->data + i);
|
||||
|
||||
switch (def->kind) {
|
||||
for (i = 0, result = results->data, argv_i = 0; i < result_defs->num_elems;
|
||||
i++, result++) {
|
||||
switch (result_defs->data[i]->kind) {
|
||||
case WASM_I32:
|
||||
{
|
||||
out->kind = WASM_I32;
|
||||
out->of.i32 = *(int32 *)result;
|
||||
result += 1;
|
||||
result->kind = WASM_I32;
|
||||
result->of.i32 = *(int32 *)(argv + argv_i);
|
||||
argv_i += 1;
|
||||
break;
|
||||
}
|
||||
case WASM_I64:
|
||||
{
|
||||
out->kind = WASM_I64;
|
||||
out->of.i64 = *(int64 *)result;
|
||||
result += 2;
|
||||
result->kind = WASM_I64;
|
||||
result->of.i64 = *(int64 *)(argv + argv_i);
|
||||
argv_i += 2;
|
||||
break;
|
||||
}
|
||||
case WASM_F32:
|
||||
{
|
||||
out->kind = WASM_F32;
|
||||
out->of.f32 = *(float32 *)result;
|
||||
result += 1;
|
||||
result->kind = WASM_F32;
|
||||
result->of.f32 = *(float32 *)(argv + argv_i);
|
||||
argv_i += 1;
|
||||
break;
|
||||
}
|
||||
case WASM_F64:
|
||||
{
|
||||
out->kind = WASM_F64;
|
||||
out->of.f64 = *(float64 *)result;
|
||||
result += 2;
|
||||
result->kind = WASM_F64;
|
||||
result->of.f64 = *(float64 *)(argv + argv_i);
|
||||
argv_i += 2;
|
||||
break;
|
||||
}
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
case WASM_ANYREF:
|
||||
{
|
||||
out->kind = WASM_ANYREF;
|
||||
|
||||
if (NULL_REF == *(uint32 *)result) {
|
||||
out->of.ref = NULL;
|
||||
}
|
||||
else {
|
||||
if (!wasm_externref_ref2obj(*(uint32 *)result,
|
||||
(void **)&out->of.ref)) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
result += 1;
|
||||
result->kind = WASM_ANYREF;
|
||||
result->of.ref =
|
||||
(struct wasm_ref_t *)(*(uintptr_t *)(argv + argv_i));
|
||||
argv_i += sizeof(uintptr_t) / sizeof(uint32);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
LOG_WARNING("%s meets unsupported type: %d", __FUNCTION__,
|
||||
def->kind);
|
||||
goto failed;
|
||||
result_defs->data[i]->kind);
|
||||
return false;
|
||||
}
|
||||
out++;
|
||||
argc++;
|
||||
}
|
||||
|
||||
return argc;
|
||||
|
||||
failed:
|
||||
LOG_DEBUG("%s failed", __FUNCTION__);
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
wasm_trap_t *
|
||||
@ -2718,7 +2687,7 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
|
||||
/* a int64 or float64 parameter means 2 */
|
||||
uint32 argc = 0;
|
||||
/* a parameter list and a return value list */
|
||||
uint32 argv_buf[32], *argv = argv_buf;
|
||||
uint32 argv_buf[32] = { 0 }, *argv = argv_buf;
|
||||
WASMFunctionInstanceCommon *func_comm_rt = NULL;
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
size_t param_count, result_count, alloc_count;
|
||||
@ -2776,10 +2745,8 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
|
||||
|
||||
/* copy parametes */
|
||||
if (param_count
|
||||
&& (!params
|
||||
|| !(argc = params_to_argv(func->inst_comm_rt, params->data,
|
||||
wasm_functype_params(func->type),
|
||||
param_count, argv)))) {
|
||||
&& !params_to_argv(params, wasm_functype_params(func->type), argv,
|
||||
&argc)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@ -2798,9 +2765,8 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
|
||||
|
||||
/* copy results */
|
||||
if (result_count) {
|
||||
if (!results
|
||||
|| !(argc = argv_to_results(argv, wasm_functype_results(func->type),
|
||||
result_count, results->data))) {
|
||||
if (!argv_to_results(argv, wasm_functype_results(func->type),
|
||||
results)) {
|
||||
goto failed;
|
||||
}
|
||||
results->num_elems = result_count;
|
||||
@ -3265,7 +3231,7 @@ wasm_table_new_internal(wasm_store_t *store, uint16 table_idx_rt,
|
||||
if (table_idx_rt < module_aot->import_table_count) {
|
||||
AOTImportTable *table_aot =
|
||||
module_aot->import_tables + table_idx_rt;
|
||||
val_type_rt = VALUE_TYPE_FUNCREF;
|
||||
val_type_rt = table_aot->elem_type;
|
||||
init_size = table_aot->table_init_size;
|
||||
max_size = table_aot->table_max_size;
|
||||
}
|
||||
@ -3273,7 +3239,7 @@ wasm_table_new_internal(wasm_store_t *store, uint16 table_idx_rt,
|
||||
AOTTable *table_aot =
|
||||
module_aot->tables
|
||||
+ (table_idx_rt - module_aot->import_table_count);
|
||||
val_type_rt = VALUE_TYPE_FUNCREF;
|
||||
val_type_rt = table_aot->elem_type;
|
||||
init_size = table_aot->table_init_size;
|
||||
max_size = table_aot->table_max_size;
|
||||
}
|
||||
@ -3360,13 +3326,12 @@ wasm_table_type(const wasm_table_t *table)
|
||||
own wasm_ref_t *
|
||||
wasm_table_get(const wasm_table_t *table, wasm_table_size_t index)
|
||||
{
|
||||
uint32 func_idx_rt = NULL_REF;
|
||||
uint32 ref_idx = NULL_REF;
|
||||
|
||||
if (!table) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* index -> func_idx_rt */
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (table->inst_comm_rt->module_type == Wasm_Module_Bytecode) {
|
||||
WASMTableInstance *table_interp =
|
||||
@ -3375,7 +3340,7 @@ wasm_table_get(const wasm_table_t *table, wasm_table_size_t index)
|
||||
if (index >= table_interp->cur_size) {
|
||||
return NULL;
|
||||
}
|
||||
func_idx_rt = ((uint32 *)table_interp->base_addr)[index];
|
||||
ref_idx = ((uint32 *)table_interp->base_addr)[index];
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3387,7 +3352,7 @@ wasm_table_get(const wasm_table_t *table, wasm_table_size_t index)
|
||||
if (index >= table_aot->cur_size) {
|
||||
return NULL;
|
||||
}
|
||||
func_idx_rt = table_aot->data[index];
|
||||
ref_idx = table_aot->data[index];
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3395,35 +3360,48 @@ wasm_table_get(const wasm_table_t *table, wasm_table_size_t index)
|
||||
* a wrong combination of module filetype and compilation flags
|
||||
* also leads to below branch
|
||||
*/
|
||||
if (func_idx_rt == NULL_REF) {
|
||||
if (ref_idx == NULL_REF) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wasm_ref_new_internal(table->store, WASM_REF_func, func_idx_rt,
|
||||
table->inst_comm_rt);
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
if (table->type->val_type->kind == WASM_ANYREF) {
|
||||
void *externref_obj;
|
||||
if (!wasm_externref_ref2obj(ref_idx, &externref_obj)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return externref_obj;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
return wasm_ref_new_internal(table->store, WASM_REF_func, ref_idx,
|
||||
table->inst_comm_rt);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
|
||||
own wasm_ref_t *func_ref)
|
||||
own wasm_ref_t *ref)
|
||||
{
|
||||
uint32 *p_func_idx_rt = NULL;
|
||||
uint32 function_count = 0, ref_idx_rt = NULL_REF;
|
||||
uint32 *p_ref_idx = NULL;
|
||||
uint32 function_count = 0;
|
||||
|
||||
if (!table) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (func_ref && func_ref->kind != WASM_REF_func) {
|
||||
if (ref
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
&& !(WASM_REF_foreign == ref->kind
|
||||
&& WASM_ANYREF == table->type->val_type->kind)
|
||||
#endif
|
||||
&& !(WASM_REF_func == ref->kind
|
||||
&& WASM_FUNCREF == table->type->val_type->kind)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (func_ref) {
|
||||
ref_idx_rt = func_ref->ref_idx_rt;
|
||||
wasm_ref_delete(func_ref);
|
||||
}
|
||||
|
||||
/* index -> *p_func_idx_rt */
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (table->inst_comm_rt->module_type == Wasm_Module_Bytecode) {
|
||||
WASMTableInstance *table_interp =
|
||||
@ -3434,7 +3412,7 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
|
||||
return false;
|
||||
}
|
||||
|
||||
p_func_idx_rt = ((uint32 *)table_interp->base_addr) + index;
|
||||
p_ref_idx = ((uint32 *)table_interp->base_addr) + index;
|
||||
function_count =
|
||||
((WASMModuleInstance *)table->inst_comm_rt)->function_count;
|
||||
}
|
||||
@ -3451,7 +3429,7 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
|
||||
return false;
|
||||
}
|
||||
|
||||
p_func_idx_rt = table_aot->data + index;
|
||||
p_ref_idx = table_aot->data + index;
|
||||
function_count = module_aot->func_count;
|
||||
}
|
||||
#endif
|
||||
@ -3460,17 +3438,31 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
|
||||
* a wrong combination of module filetype and compilation flags
|
||||
* leads to below branch
|
||||
*/
|
||||
if (!p_func_idx_rt) {
|
||||
if (!p_ref_idx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NULL_REF != ref_idx_rt) {
|
||||
if (ref_idx_rt >= function_count) {
|
||||
return false;
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
if (table->type->val_type->kind == WASM_ANYREF) {
|
||||
return wasm_externref_obj2ref(table->inst_comm_rt, ref, p_ref_idx);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (ref) {
|
||||
if (NULL_REF != ref->ref_idx_rt) {
|
||||
if (ref->ref_idx_rt >= function_count) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*p_ref_idx = ref->ref_idx_rt;
|
||||
wasm_ref_delete(ref);
|
||||
}
|
||||
else {
|
||||
*p_ref_idx = NULL_REF;
|
||||
}
|
||||
}
|
||||
|
||||
*p_func_idx_rt = ref_idx_rt;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -56,7 +56,6 @@ struct wasm_globaltype_t {
|
||||
|
||||
struct wasm_tabletype_t {
|
||||
uint32 extern_kind;
|
||||
/* always be WASM_FUNCREF */
|
||||
wasm_valtype_t *val_type;
|
||||
wasm_limits_t limits;
|
||||
};
|
||||
|
||||
@ -125,10 +125,6 @@ typedef struct WASMExecEnv {
|
||||
WASMJmpBuf *jmpbuf_stack_top;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
uint16 nested_calling_depth;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY_PROFILING != 0
|
||||
uint32 max_wasm_stack_used;
|
||||
#endif
|
||||
|
||||
@ -53,11 +53,30 @@ get_lib_pthread_export_apis(NativeSymbol **p_lib_pthread_apis);
|
||||
uint32
|
||||
get_libc_emcc_export_apis(NativeSymbol **p_libc_emcc_apis);
|
||||
|
||||
static bool
|
||||
compare_type_with_signautre(uint8 type, const char signature)
|
||||
{
|
||||
const char num_sig_map[] = { 'F', 'f', 'I', 'i' };
|
||||
|
||||
if (VALUE_TYPE_F64 <= type && type <= VALUE_TYPE_I32
|
||||
&& signature == num_sig_map[type - VALUE_TYPE_F64]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
if ('r' == signature && type == VALUE_TYPE_EXTERNREF)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
/* TODO: a v128 parameter */
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_symbol_signature(const WASMType *type, const char *signature)
|
||||
{
|
||||
const char *p = signature, *p_end;
|
||||
char sig_map[] = { 'F', 'f', 'I', 'i' }, sig;
|
||||
char sig;
|
||||
uint32 i = 0;
|
||||
|
||||
if (!p || strlen(p) < 2)
|
||||
@ -74,16 +93,12 @@ check_symbol_signature(const WASMType *type, const char *signature)
|
||||
|
||||
for (i = 0; i < type->param_count; i++) {
|
||||
sig = *p++;
|
||||
if ((type->types[i] >= VALUE_TYPE_F64
|
||||
&& type->types[i] <= VALUE_TYPE_I32
|
||||
&& sig == sig_map[type->types[i] - VALUE_TYPE_F64])
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
|| (sig == 'i' && type->types[i] == VALUE_TYPE_EXTERNREF)
|
||||
#endif
|
||||
)
|
||||
/* normal parameter */
|
||||
|
||||
/* a f64/f32/i64/i32/externref parameter */
|
||||
if (compare_type_with_signautre(type->types[i], sig))
|
||||
continue;
|
||||
|
||||
/* a pointer/string paramter */
|
||||
if (type->types[i] != VALUE_TYPE_I32)
|
||||
/* pointer and string must be i32 type */
|
||||
return false;
|
||||
@ -112,8 +127,12 @@ check_symbol_signature(const WASMType *type, const char *signature)
|
||||
if (type->result_count) {
|
||||
if (p >= p_end)
|
||||
return false;
|
||||
if (*p++ != sig_map[type->types[i] - VALUE_TYPE_F64])
|
||||
|
||||
/* result types includes: f64,f32,i64,i32,externref */
|
||||
if (!compare_type_with_signautre(type->types[i], *p))
|
||||
return false;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p != '\0')
|
||||
|
||||
@ -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)
|
||||
/* (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 i = 0, cell_num = 0;
|
||||
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);
|
||||
|
||||
*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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!need_param_transform && !need_result_transform) {
|
||||
*ret_argv = argv;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* (uintptr_t)externref <- (uint32_t)index */
|
||||
/* argv <- new_argv */
|
||||
static bool
|
||||
wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
|
||||
WASMFunctionInstanceCommon *function,
|
||||
uint32 *argv, uint32 argc, uint32 *ret_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);
|
||||
|
||||
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]);
|
||||
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;
|
||||
}
|
||||
|
||||
cell_num += wasm_value_type_cell_num(result_type);
|
||||
i++;
|
||||
}
|
||||
|
||||
wasm_externref_reclaim(exec_env->module_inst);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
|
||||
WASMFunctionInstanceCommon *function)
|
||||
{
|
||||
exec_env->nested_calling_depth++;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
|
||||
WASMFunctionInstanceCommon *function,
|
||||
bool ret, uint32 *argv)
|
||||
{
|
||||
exec_env->nested_calling_depth--;
|
||||
if (!exec_env->nested_calling_depth && ret) {
|
||||
wasm_runtime_reclaim_externref(exec_env, function, argv);
|
||||
}
|
||||
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:
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
#endif
|
||||
argv1[j++] = *argv++;
|
||||
break;
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
{
|
||||
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;
|
||||
|
||||
@ -525,11 +525,6 @@ bool
|
||||
wasm_runtime_call_indirect(WASMExecEnv *exec_env, uint32 element_indices,
|
||||
uint32 argc, uint32 argv[]);
|
||||
|
||||
bool
|
||||
wasm_runtime_create_exec_env_and_call_wasm(
|
||||
WASMModuleInstanceCommon *module_inst, WASMFunctionInstanceCommon *function,
|
||||
uint32 argc, uint32 argv[]);
|
||||
|
||||
bool
|
||||
wasm_runtime_create_exec_env_singleton(WASMModuleInstanceCommon *module_inst);
|
||||
|
||||
@ -813,16 +808,6 @@ wasm_runtime_dump_module_inst_mem_consumption(
|
||||
void
|
||||
wasm_runtime_dump_exec_env_mem_consumption(const WASMExecEnv *exec_env);
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
void
|
||||
wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
|
||||
WASMFunctionInstanceCommon *function);
|
||||
void
|
||||
wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
|
||||
WASMFunctionInstanceCommon *function,
|
||||
bool ret, uint32 *argv);
|
||||
#endif
|
||||
|
||||
bool
|
||||
wasm_runtime_get_export_func_type(const WASMModuleCommon *module_comm,
|
||||
const WASMExport *export_, WASMType **out);
|
||||
|
||||
@ -96,6 +96,7 @@ typedef struct AOTMemInitData {
|
||||
typedef struct AOTImportTable {
|
||||
char *module_name;
|
||||
char *table_name;
|
||||
uint32 elem_type;
|
||||
uint32 table_flags;
|
||||
uint32 table_init_size;
|
||||
uint32 table_max_size;
|
||||
|
||||
@ -1398,6 +1398,7 @@ aot_emit_table_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
|
||||
* EMIT_STR(comp_data->import_tables[i].module_name );
|
||||
* EMIT_STR(comp_data->import_tables[i].table_name);
|
||||
*/
|
||||
EMIT_U32(comp_data->import_tables[i].elem_type);
|
||||
EMIT_U32(comp_data->import_tables[i].table_init_size);
|
||||
EMIT_U32(comp_data->import_tables[i].table_max_size);
|
||||
EMIT_U32(comp_data->import_tables[i].possible_grow & 0x000000FF);
|
||||
|
||||
@ -155,16 +155,17 @@ enum wasm_valkind_enum {
|
||||
|
||||
#ifndef WASM_VAL_T_DEFINED
|
||||
#define WASM_VAL_T_DEFINED
|
||||
struct wasm_ref_t;
|
||||
|
||||
typedef struct wasm_val_t {
|
||||
wasm_valkind_t kind;
|
||||
union {
|
||||
/* also represent a function index */
|
||||
int32_t i32;
|
||||
int64_t i64;
|
||||
float f32;
|
||||
double f64;
|
||||
struct wasm_ref_t *ref;
|
||||
/* represent a foreign object, aka externref in .wat */
|
||||
uintptr_t foreign;
|
||||
} of;
|
||||
} wasm_val_t;
|
||||
#endif
|
||||
@ -790,6 +791,7 @@ wasm_runtime_get_native_addr_range(wasm_module_inst_t module_inst,
|
||||
* 'I': the parameter is i64 type
|
||||
* 'f': the parameter is f32 type
|
||||
* 'F': the parameter is f64 type
|
||||
* 'r': the parameter is externref type, it should be a uintptr_t in host
|
||||
* '*': the parameter is a pointer (i32 in WASM), and runtime will
|
||||
* auto check its boundary before calling the native function.
|
||||
* If it is followed by '~', the checked length of the pointer
|
||||
|
||||
@ -544,6 +544,19 @@ wasm_get_cell_num(const uint8 *types, uint32 type_count)
|
||||
return cell_num;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
inline static uint16
|
||||
wasm_value_type_cell_num_outside(uint8 value_type)
|
||||
{
|
||||
if (VALUE_TYPE_EXTERNREF == value_type) {
|
||||
return sizeof(uintptr_t) / sizeof(uint32);
|
||||
}
|
||||
else {
|
||||
return wasm_value_type_cell_num(value_type);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline static bool
|
||||
wasm_type_equal(const WASMType *type1, const WASMType *type2)
|
||||
{
|
||||
|
||||
@ -1748,16 +1748,8 @@ wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
wasm_runtime_prepare_call_function(exec_env, func);
|
||||
#endif
|
||||
|
||||
ret = wasm_call_function(exec_env, func, argc, argv);
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
wasm_runtime_finalize_call_function(exec_env, func, ret, argv);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
/* don't destroy the exec_env if it's searched from the cluster */
|
||||
if (!existing_exec_env)
|
||||
@ -1770,9 +1762,14 @@ wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst,
|
||||
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);
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
|
||||
if (module_inst->exec_env_singleton) {
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@ -74,6 +74,9 @@ os_mem_decommit(void *ptr, size_t size);
|
||||
|
||||
#define os_thread_local_attribute __declspec(thread)
|
||||
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
|
||||
#if WASM_DISABLE_HW_BOUND_CHECK == 0
|
||||
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user