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:
Wenyong Huang
2022-01-19 11:25:08 +08:00
committed by GitHub
parent 2c743dbd51
commit 260d36a62d
30 changed files with 1148 additions and 595 deletions

View File

@ -47,21 +47,23 @@ wasm_table_t* get_export_table(const wasm_extern_vec_t* exports, size_t i) {
own wasm_ref_t* call_v_r(const wasm_func_t* func) {
printf("call_v_r... "); fflush(stdout);
wasm_val_vec_t rs;
wasm_val_vec_new_uninitialized(&rs, 1);
if (wasm_func_call(func, NULL, &rs)) {
wasm_val_t rs[] = { WASM_INIT_VAL };
wasm_val_vec_t args = WASM_EMPTY_VEC;
wasm_val_vec_t results = WASM_ARRAY_VEC(rs);
if (wasm_func_call(func, &args, &results)) {
printf("> Error calling function!\n");
exit(1);
}
printf("okay\n");
return rs.data[0].of.ref;
return rs[0].of.ref;
}
void call_r_v(const wasm_func_t* func, wasm_ref_t* ref) {
printf("call_r_v... "); fflush(stdout);
wasm_val_vec_t vs;
wasm_val_vec_new(&vs, 1, (wasm_val_t []){ WASM_REF_VAL(ref) });
if (wasm_func_call(func, &vs, NULL)) {
wasm_val_t vs[1] = { WASM_REF_VAL(ref) };
wasm_val_vec_t args = WASM_ARRAY_VEC(vs);
wasm_val_vec_t results = WASM_EMPTY_VEC;
if (wasm_func_call(func, &args, &results)) {
printf("> Error calling function!\n");
exit(1);
}
@ -70,22 +72,24 @@ void call_r_v(const wasm_func_t* func, wasm_ref_t* ref) {
own wasm_ref_t* call_r_r(const wasm_func_t* func, wasm_ref_t* ref) {
printf("call_r_r... "); fflush(stdout);
wasm_val_vec_t vs, rs;
wasm_val_vec_new(&vs, 1, (wasm_val_t []){ WASM_REF_VAL(ref) });
wasm_val_vec_new_uninitialized(&rs, 1);
if (wasm_func_call(func, &vs, &rs)) {
wasm_val_t vs[1] = { WASM_REF_VAL(ref) };
wasm_val_t rs[1] = { WASM_INIT_VAL };
wasm_val_vec_t args = WASM_ARRAY_VEC(vs);
wasm_val_vec_t results = WASM_ARRAY_VEC(rs);
if (wasm_func_call(func, &args, &results)) {
printf("> Error calling function!\n");
exit(1);
}
printf("okay\n");
return rs.data[0].of.ref;
return rs[0].of.ref;
}
void call_ir_v(const wasm_func_t* func, int32_t i, wasm_ref_t* ref) {
printf("call_ir_v... "); fflush(stdout);
wasm_val_vec_t vs;
wasm_val_vec_new(&vs, 2, (wasm_val_t []){ WASM_I32_VAL(i), WASM_REF_VAL(ref) });
if (wasm_func_call(func, &vs, NULL)) {
wasm_val_t vs[2] = { WASM_I32_VAL(i), WASM_REF_VAL(ref) };
wasm_val_vec_t args = WASM_ARRAY_VEC(vs);
wasm_val_vec_t results = WASM_EMPTY_VEC;
if (wasm_func_call(func, &args, &results)) {
printf("> Error calling function!\n");
exit(1);
}
@ -94,31 +98,30 @@ void call_ir_v(const wasm_func_t* func, int32_t i, wasm_ref_t* ref) {
own wasm_ref_t* call_i_r(const wasm_func_t* func, int32_t i) {
printf("call_i_r... "); fflush(stdout);
wasm_val_vec_t vs, rs;
wasm_val_vec_new(&vs, 1, (wasm_val_t []){ WASM_I32_VAL(i) });
wasm_val_vec_new_uninitialized(&rs, 1);
if (wasm_func_call(func, &vs, &rs)) {
wasm_val_t vs[1] = { WASM_I32_VAL(i) };
wasm_val_t rs[1] = { WASM_INIT_VAL };
wasm_val_vec_t args = WASM_ARRAY_VEC(vs);
wasm_val_vec_t results = WASM_ARRAY_VEC(rs);
if (wasm_func_call(func, &args, &results)) {
printf("> Error calling function!\n");
exit(1);
}
printf("okay\n");
return rs.data[0].of.ref;
return rs[0].of.ref;
}
void
check(own wasm_ref_t *actual, const wasm_ref_t *expected, bool release_ref)
{
if (actual != expected
&& !(actual && expected && wasm_ref_same(actual, expected))) {
printf("> Error reading reference, expected %p, got %p\n",
expected ? wasm_ref_get_host_info(expected) : NULL,
actual ? wasm_ref_get_host_info(actual) : NULL);
exit(1);
}
if (release_ref && actual)
wasm_ref_delete(actual);
void check(own wasm_ref_t* actual, const wasm_ref_t* expected) {
if (actual != expected &&
!(actual && expected && wasm_ref_same(actual, expected))) {
printf("> Error reading reference, expected %p, got %p\n",
expected ? wasm_ref_get_host_info(expected) : NULL,
actual ? wasm_ref_get_host_info(actual) : NULL);
exit(1);
}
// if (actual) wasm_ref_delete(actual);
}
int main(int argc, const char* argv[]) {
// Initialize.
printf("Initializing...\n");
@ -169,8 +172,8 @@ int main(int argc, const char* argv[]) {
// Instantiate.
printf("Instantiating module...\n");
wasm_extern_vec_t imports;
wasm_extern_vec_new(&imports, 1, (wasm_extern_t* []) { wasm_func_as_extern(callback_func) });
wasm_extern_t* externs[] = { wasm_func_as_extern(callback_func) };
wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
own wasm_instance_t* instance =
wasm_instance_new(store, module, &imports, NULL);
if (!instance) {
@ -204,54 +207,61 @@ int main(int argc, const char* argv[]) {
wasm_ref_set_host_info(host2, (void*)2);
// Some sanity checks.
check(NULL, NULL, true);
check(wasm_ref_copy(host1), host1, true);
check(wasm_ref_copy(host2), host2, true);
check(NULL, NULL);
wasm_ref_t *host1_cp = wasm_ref_copy(host1);
wasm_ref_t *host2_cp = wasm_ref_copy(host2);
check(host1_cp, host1);
check(host2_cp, host2);
wasm_ref_delete(host1_cp);
wasm_ref_delete(host2_cp);
own wasm_val_t val;
val.kind = WASM_ANYREF;
val.of.ref = wasm_ref_copy(host1);
check(wasm_ref_copy(val.of.ref), host1, true);
own wasm_ref_t* ref = val.of.ref;
check(wasm_ref_copy(ref), host1, true);
wasm_ref_t *ref_cp = wasm_ref_copy(val.of.ref);
check(ref_cp, host1);
check(val.of.ref, host1);
wasm_ref_delete(val.of.ref);
wasm_ref_delete(ref_cp);
// Interact.
printf("Accessing global...\n");
check(call_v_r(global_get), NULL, false);
check(call_v_r(global_get), NULL);
call_r_v(global_set, host1);
check(call_v_r(global_get), host1, false);
check(call_v_r(global_get), host1);
call_r_v(global_set, host2);
check(call_v_r(global_get), host2, false);
check(call_v_r(global_get), host2);
call_r_v(global_set, NULL);
check(call_v_r(global_get), NULL, false);
check(call_v_r(global_get), NULL);
wasm_global_get(global, &val);
assert(val.kind == WASM_ANYREF);
check(val.of.ref, NULL, false);
assert(val.of.ref == NULL);
val.of.ref = host2;
wasm_global_set(global, &val);
check(call_v_r(global_get), host2, false);
wasm_global_get(global, &val);
assert(val.kind == WASM_ANYREF);
check(val.of.ref, host2, false);
assert(val.of.ref == host2);
printf("Accessing table...\n");
check(call_i_r(table_get, 0), NULL, false);
check(call_i_r(table_get, 1), NULL, false);
check(call_i_r(table_get, 0), NULL);
check(call_i_r(table_get, 1), NULL);
call_ir_v(table_set, 0, host1);
call_ir_v(table_set, 1, host2);
check(call_i_r(table_get, 0), host1, false);
check(call_i_r(table_get, 1), host2, false);
check(call_i_r(table_get, 0), host1);
check(call_i_r(table_get, 1), host2);
call_ir_v(table_set, 0, NULL);
check(call_i_r(table_get, 0), NULL, false);
check(call_i_r(table_get, 0), NULL);
check(wasm_table_get(table, 2), NULL, false);
check(wasm_table_get(table, 2), NULL);
wasm_table_set(table, 2, host1);
check(call_i_r(table_get, 2), host1);
check(wasm_table_get(table, 2), host1);
printf("Accessing function...\n");
check(call_r_r(func_call, NULL), NULL, false);
check(call_r_r(func_call, host1), host1, false);
check(call_r_r(func_call, host2), host2, false);
check(call_r_r(func_call, NULL), NULL);
check(call_r_r(func_call, host1), host1);
check(call_r_r(func_call, host2), host2);
wasm_ref_delete(host1);
wasm_ref_delete(host2);