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:
@ -116,7 +116,7 @@ endif()
|
||||
# wat to wasm
|
||||
file(GLOB WAT_FILE src/hello.wat)
|
||||
add_custom_target(hello_wasm ALL
|
||||
COMMAND ${WAT2WASM} ${WAT_FILE} -o ${PROJECT_BINARY_DIR}/hello.wasm
|
||||
COMMAND ${WAT2WASM} ${WAT_FILE} --enable-reference-types -o ${PROJECT_BINARY_DIR}/hello.wasm
|
||||
DEPENDS ${WAT_FILE}
|
||||
BYPRODUCTS ${PROJECT_BINARY_DIR}/hello.wasm
|
||||
VERBATIM
|
||||
|
||||
@ -13,52 +13,170 @@
|
||||
static char global_heap_buf[10 * 1024 * 1024] = { 0 };
|
||||
#endif
|
||||
|
||||
static int
|
||||
test_write_wrapper(wasm_exec_env_t exec_env, uint32 externref_idx_of_file,
|
||||
const char *str, int len)
|
||||
static uintptr_t global_objects[10] = { 0 };
|
||||
|
||||
int32
|
||||
local_cmp_externref(wasm_exec_env_t exec_env, uintptr_t externref_a,
|
||||
uintptr_t externref_b)
|
||||
{
|
||||
FILE *file;
|
||||
char buf[16];
|
||||
return externref_a == externref_b;
|
||||
}
|
||||
|
||||
printf("## retrieve file handle from externref index\n");
|
||||
if (!wasm_externref_ref2obj(externref_idx_of_file, (void **)&file)) {
|
||||
printf("failed to get host object from externref index!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%%%ds", len);
|
||||
|
||||
printf("## write string to file: ");
|
||||
printf(buf, str);
|
||||
|
||||
return fprintf(file, buf, str);
|
||||
int32
|
||||
local_chk_externref(wasm_exec_env_t exec_env, int32 index, uintptr_t externref)
|
||||
{
|
||||
return externref == global_objects[index];
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
static NativeSymbol native_symbols[] = {
|
||||
{ "test_write", test_write_wrapper, "(i*~)i", NULL }
|
||||
{ "native-cmp-externref", local_cmp_externref, "(II)i", NULL },
|
||||
{ "native-chk-externref", local_chk_externref, "(iI)i", NULL },
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
static inline void
|
||||
local_set_externref(int32 index, uintptr_t externref)
|
||||
{
|
||||
global_objects[index] = externref;
|
||||
}
|
||||
|
||||
static WASMFunctionInstanceCommon *wasm_set_externref_ptr;
|
||||
static WASMFunctionInstanceCommon *wasm_get_externref_ptr;
|
||||
static WASMFunctionInstanceCommon *wasm_cmp_externref_ptr;
|
||||
|
||||
static bool
|
||||
wasm_set_externref(wasm_exec_env_t exec_env, wasm_module_inst_t inst,
|
||||
int32 index, uintptr_t externref)
|
||||
{
|
||||
union {
|
||||
uintptr_t val;
|
||||
uint32 parts[2];
|
||||
} u;
|
||||
uint32 argv[3] = { 0 };
|
||||
|
||||
if (!exec_env || !wasm_set_externref_ptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
u.val = externref;
|
||||
argv[0] = index;
|
||||
argv[1] = u.parts[0];
|
||||
argv[2] = u.parts[1];
|
||||
if (!wasm_runtime_call_wasm(exec_env, wasm_set_externref_ptr, 2, argv)) {
|
||||
const char *exception;
|
||||
if ((exception = wasm_runtime_get_exception(inst))) {
|
||||
printf("Exception: %s\n", exception);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
wasm_get_externref(wasm_exec_env_t exec_env, wasm_module_inst_t inst,
|
||||
int32 index, uintptr_t *ret_externref)
|
||||
{
|
||||
wasm_val_t results[1] = { 0 };
|
||||
|
||||
if (!exec_env || !wasm_get_externref_ptr || !ret_externref) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wasm_runtime_call_wasm_v(exec_env, wasm_get_externref_ptr, 1, results,
|
||||
1, index)) {
|
||||
const char *exception;
|
||||
if ((exception = wasm_runtime_get_exception(inst))) {
|
||||
printf("Exception: %s\n", exception);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WASM_ANYREF != results[0].kind) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*ret_externref = results[0].of.foreign;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
wasm_cmp_externref(wasm_exec_env_t exec_env, wasm_module_inst_t inst,
|
||||
int32 index, uintptr_t externref, int32 *ret_result)
|
||||
{
|
||||
wasm_val_t results[1] = { 0 };
|
||||
wasm_val_t arguments[2] = {
|
||||
{ .kind = WASM_I32, .of.i32 = index },
|
||||
{ .kind = WASM_ANYREF, .of.foreign = externref },
|
||||
};
|
||||
|
||||
if (!exec_env || !wasm_cmp_externref_ptr || !ret_result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wasm_runtime_call_wasm_a(exec_env, wasm_cmp_externref_ptr, 1, results,
|
||||
2, arguments)) {
|
||||
const char *exception;
|
||||
if ((exception = wasm_runtime_get_exception(inst))) {
|
||||
printf("Exception: %s\n", exception);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results[0].kind != WASM_I32) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*ret_result = results[0].of.i32;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_and_cmp(wasm_exec_env_t exec_env, wasm_module_inst_t inst, int32 i,
|
||||
uintptr_t externref)
|
||||
{
|
||||
int32 cmp_result = 0;
|
||||
uintptr_t wasm_externref = 0;
|
||||
|
||||
wasm_set_externref(exec_env, inst, i, externref);
|
||||
local_set_externref(i, externref);
|
||||
|
||||
wasm_get_externref(exec_env, inst, 0, &wasm_externref);
|
||||
if (!local_chk_externref(exec_env, 0, wasm_externref)) {
|
||||
printf("#%d, In host language world Wasm Externref 0x%lx Vs. Native "
|
||||
"Externref 0x%lx FAILED\n",
|
||||
i, wasm_externref, externref);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wasm_cmp_externref(exec_env, inst, i, global_objects[i], &cmp_result)
|
||||
|| !cmp_result) {
|
||||
printf("#%d, In Wasm world Native Externref 0x%lx Vs, Wasm Externref "
|
||||
"FAILED\n",
|
||||
i, global_objects[i]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *wasm_file = "hello.wasm";
|
||||
uint8 *wasm_file_buf = NULL;
|
||||
uint32 wasm_file_size, externref_idx;
|
||||
uint32 wasm_file_size;
|
||||
uint32 stack_size = 16 * 1024, heap_size = 16 * 1024;
|
||||
wasm_module_t wasm_module = NULL;
|
||||
wasm_module_inst_t wasm_module_inst = NULL;
|
||||
wasm_function_inst_t func_inst = NULL;
|
||||
wasm_exec_env_t exec_env = NULL;
|
||||
RuntimeInitArgs init_args;
|
||||
char error_buf[128] = { 0 };
|
||||
const char *exce;
|
||||
unsigned argv1[8];
|
||||
#if WASM_ENABLE_LOG != 0
|
||||
int log_verbose_level = 2;
|
||||
#endif
|
||||
FILE *file;
|
||||
const uint64 big_number = 0x123456789abc;
|
||||
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
|
||||
@ -90,13 +208,13 @@ main(int argc, char *argv[])
|
||||
/* load WASM byte buffer from WASM bin file */
|
||||
if (!(wasm_file_buf =
|
||||
(uint8 *)bh_read_file_to_buffer(wasm_file, &wasm_file_size)))
|
||||
goto fail1;
|
||||
goto fail;
|
||||
|
||||
/* load WASM module */
|
||||
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
printf("%s\n", error_buf);
|
||||
goto fail2;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* instantiate the module */
|
||||
@ -104,62 +222,66 @@ main(int argc, char *argv[])
|
||||
wasm_runtime_instantiate(wasm_module, stack_size, heap_size,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
printf("%s\n", error_buf);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
/* lookup function instance */
|
||||
if (!(func_inst =
|
||||
wasm_runtime_lookup_function(wasm_module_inst, "test", NULL))) {
|
||||
printf("%s\n", "lookup function test failed");
|
||||
goto fail4;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* create an execution env */
|
||||
if (!(exec_env =
|
||||
wasm_runtime_create_exec_env(wasm_module_inst, stack_size))) {
|
||||
printf("%s\n", "create exec env failed");
|
||||
goto fail4;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
printf("## open file test.txt\n");
|
||||
if (!(file = fopen("test.txt", "wb+"))) {
|
||||
printf("%s\n", "open file text.txt failed");
|
||||
goto fail5;
|
||||
/* lookup function instance */
|
||||
if (!(wasm_cmp_externref_ptr = wasm_runtime_lookup_function(
|
||||
wasm_module_inst, "cmp-externref", NULL))) {
|
||||
printf("%s\n", "lookup function cmp-externref failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
printf("## map file handle to externref index\n");
|
||||
if (!wasm_externref_obj2ref(wasm_module_inst, file, &externref_idx)) {
|
||||
printf("%s\n", "map host object to externref index failed");
|
||||
goto fail6;
|
||||
if (!(wasm_get_externref_ptr = wasm_runtime_lookup_function(
|
||||
wasm_module_inst, "get-externref", NULL))) {
|
||||
printf("%s\n", "lookup function get-externref failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
printf("## call wasm function with externref index\n");
|
||||
argv1[0] = externref_idx;
|
||||
wasm_runtime_call_wasm(exec_env, func_inst, 1, argv1);
|
||||
|
||||
if ((exce = wasm_runtime_get_exception(wasm_module_inst))) {
|
||||
printf("Exception: %s\n", exce);
|
||||
if (!(wasm_set_externref_ptr = wasm_runtime_lookup_function(
|
||||
wasm_module_inst, "set-externref", NULL))) {
|
||||
printf("%s\n", "lookup function set-externref failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail6:
|
||||
fclose(file);
|
||||
/* test with NULL */
|
||||
if (!set_and_cmp(exec_env, wasm_module_inst, 0, 0)
|
||||
|| !set_and_cmp(exec_env, wasm_module_inst, 1, big_number + 1)
|
||||
|| !set_and_cmp(exec_env, wasm_module_inst, 2, big_number + 2)
|
||||
|| !set_and_cmp(exec_env, wasm_module_inst, 3, big_number + 3)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail5:
|
||||
printf("GREAT! PASS ALL CHKs\n");
|
||||
|
||||
fail:
|
||||
/* destroy exec env */
|
||||
wasm_runtime_destroy_exec_env(exec_env);
|
||||
if (exec_env) {
|
||||
wasm_runtime_destroy_exec_env(exec_env);
|
||||
}
|
||||
|
||||
fail4:
|
||||
/* destroy the module instance */
|
||||
wasm_runtime_deinstantiate(wasm_module_inst);
|
||||
if (wasm_module_inst) {
|
||||
wasm_runtime_deinstantiate(wasm_module_inst);
|
||||
}
|
||||
|
||||
fail3:
|
||||
/* unload the module */
|
||||
wasm_runtime_unload(wasm_module);
|
||||
if (wasm_module) {
|
||||
wasm_runtime_unload(wasm_module);
|
||||
}
|
||||
|
||||
fail2:
|
||||
/* free the file buffer */
|
||||
wasm_runtime_free(wasm_file_buf);
|
||||
if (wasm_file_buf) {
|
||||
wasm_runtime_free(wasm_file_buf);
|
||||
}
|
||||
|
||||
fail1:
|
||||
/* destroy runtime environment */
|
||||
wasm_runtime_destroy();
|
||||
return 0;
|
||||
|
||||
@ -2,21 +2,43 @@
|
||||
;; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
(module
|
||||
;; import test_write function which is implemented by host
|
||||
(import "env" "test_write"
|
||||
(func $test_write (param externref i32 i32) (result i32)))
|
||||
(type $t0 (func (param i32 externref) (result i32)))
|
||||
|
||||
;; memory with one page (64KiB).
|
||||
(memory (export "memory") 1)
|
||||
(import "env" "native-cmp-externref"
|
||||
(func $native-cmp-externref (param externref externref) (result i32))
|
||||
)
|
||||
|
||||
(data (i32.const 0x8) "Hello, world!\n")
|
||||
(import "env" "native-chk-externref"
|
||||
(func $native-chk-externref (param i32 externref) (result i32))
|
||||
)
|
||||
|
||||
;; function that writes string to a given open file handle
|
||||
(func (export "test") (param externref)
|
||||
(local.get 0)
|
||||
(i32.const 0x8)
|
||||
(i32.const 14)
|
||||
(call $test_write)
|
||||
drop
|
||||
(table $t1 8 8 externref)
|
||||
(table $t2 funcref
|
||||
(elem
|
||||
$native-cmp-externref
|
||||
$native-chk-externref
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "set-externref") (param $i i32) (param $r externref)
|
||||
(table.set $t1 (local.get $i) (local.get $r))
|
||||
)
|
||||
|
||||
(func (export "get-externref") (param $i i32) (result externref)
|
||||
(table.get $t1 (local.get $i))
|
||||
)
|
||||
|
||||
(func (export "cmp-externref") (param $i i32) (param $r externref) (result i32)
|
||||
(table.get $t1 (local.get $i))
|
||||
(local.get $r)
|
||||
(call $native-cmp-externref)
|
||||
)
|
||||
|
||||
(func (export "chk-externref") (param $i i32) (param $r externref) (result i32)
|
||||
(call_indirect $t2 (type $t0)
|
||||
(local.get $i)
|
||||
(local.get $r)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@ -35,7 +35,7 @@ void wasm_val_print(wasm_val_t val) {
|
||||
|
||||
// A function to be called from Wasm code.
|
||||
own wasm_trap_t* print_callback(
|
||||
const wasm_val_vec_t *args, wasm_val_vec_t *results
|
||||
const wasm_val_vec_t* args, wasm_val_vec_t* results
|
||||
) {
|
||||
printf("Calling back...\n> ");
|
||||
wasm_val_print(args->data[0]);
|
||||
@ -48,7 +48,7 @@ own wasm_trap_t* print_callback(
|
||||
|
||||
// A function closure.
|
||||
own wasm_trap_t* closure_callback(
|
||||
void* env, const wasm_val_vec_t *args, wasm_val_vec_t *results
|
||||
void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results
|
||||
) {
|
||||
int i = *(int*)env;
|
||||
printf("Calling back closure...\n");
|
||||
@ -113,11 +113,10 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// Instantiate.
|
||||
printf("Instantiating module...\n");
|
||||
|
||||
wasm_extern_vec_t imports;
|
||||
wasm_extern_vec_new(&imports, 2, (wasm_extern_t *[]) {
|
||||
wasm_extern_t* externs[] = {
|
||||
wasm_func_as_extern(print_func), wasm_func_as_extern(closure_func)
|
||||
});
|
||||
};
|
||||
wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
|
||||
own wasm_instance_t* instance =
|
||||
wasm_instance_new(store, module, &imports, NULL);
|
||||
if (!instance) {
|
||||
@ -147,9 +146,10 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// Call.
|
||||
printf("Calling export...\n");
|
||||
wasm_val_vec_t args, results;
|
||||
wasm_val_vec_new(&args, 2, (wasm_val_t[]){ WASM_I32_VAL(3), WASM_I32_VAL(4) });
|
||||
wasm_val_vec_new(&results, 1, (wasm_val_t[]) { WASM_INIT_VAL });
|
||||
wasm_val_t as[2] = { WASM_I32_VAL(3), WASM_I32_VAL(4) };
|
||||
wasm_val_t rs[1] = { WASM_INIT_VAL };
|
||||
wasm_val_vec_t args = WASM_ARRAY_VEC(as);
|
||||
wasm_val_vec_t results = WASM_ARRAY_VEC(rs);
|
||||
if (wasm_func_call(run_func, &args, &results)) {
|
||||
printf("> Error calling function!\n");
|
||||
return 1;
|
||||
@ -159,7 +159,7 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// Print result.
|
||||
printf("Printing result...\n");
|
||||
printf("> %u\n", results.data[0].of.i32);
|
||||
printf("> %u\n", rs[0].of.i32);
|
||||
|
||||
// Shut down.
|
||||
printf("Shutting down...\n");
|
||||
|
||||
@ -61,10 +61,7 @@ enum EXPORT_ITEM_NAME {
|
||||
|
||||
DEFINE_FUNCTION(get_pairs)
|
||||
{
|
||||
wasm_val_vec_t arg, ret;
|
||||
wasm_val_vec_new(&ret, 1, (wasm_val_t []){ WASM_INIT_VAL });
|
||||
wasm_val_vec_new(&arg, 1, (wasm_val_t []){ WASM_I32_VAL(24) });
|
||||
call_wasm_function(e_malloc, &arg, &ret, "malloc");
|
||||
call_wasm_function(e_malloc, args, results, "malloc");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -204,9 +201,6 @@ main(int argc, const char *argv[])
|
||||
IMPORT_FUNCTION_LIST(IMPORT_FUNCTION_VARIABLE_NAME)
|
||||
#undef IMPORT_FUNCTION_VARIABLE_NAME
|
||||
|
||||
wasm_extern_vec_t imports;
|
||||
wasm_extern_vec_new_uninitialized(&imports, 10);
|
||||
|
||||
#define CREATE_WASM_FUNCTION(name, index, CREATE_FUNC_TYPE) \
|
||||
{ \
|
||||
own wasm_functype_t *type = CREATE_FUNC_TYPE; \
|
||||
@ -219,13 +213,13 @@ main(int argc, const char *argv[])
|
||||
IMPORT_FUNCTION_LIST(CREATE_WASM_FUNCTION)
|
||||
#undef CREATE_WASM_FUNCTION
|
||||
|
||||
wasm_extern_t *fs[10] = {0};
|
||||
#define ADD_TO_FUNCTION_LIST(name, index, ...) \
|
||||
imports.data[index] = wasm_func_as_extern(function_##name); \
|
||||
imports.num_elems += 1;
|
||||
fs[index] = wasm_func_as_extern(function_##name);
|
||||
IMPORT_FUNCTION_LIST(ADD_TO_FUNCTION_LIST)
|
||||
#undef CREATE_IMPORT_FUNCTION
|
||||
|
||||
#undef ADD_TO_FUNCTION_LIST
|
||||
|
||||
wasm_extern_vec_t imports = WASM_ARRAY_VEC(fs);
|
||||
own wasm_instance_t *instance =
|
||||
wasm_instance_new(store, module, &imports, NULL);
|
||||
if (!instance) {
|
||||
|
||||
@ -39,10 +39,11 @@ wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) {
|
||||
|
||||
#define check_call(func, type, expected) \
|
||||
{ \
|
||||
wasm_val_vec_t results; \
|
||||
wasm_val_vec_new_uninitialized(&results, 1); \
|
||||
wasm_func_call(func, NULL, &results); \
|
||||
check(results.data[0], type, expected); \
|
||||
wasm_val_t vs[1]; \
|
||||
wasm_val_vec_t args = WASM_EMPTY_VEC; \
|
||||
wasm_val_vec_t results = WASM_ARRAY_VEC(vs); \
|
||||
wasm_func_call(func, &args, &results); \
|
||||
check(vs[0], type, expected); \
|
||||
}
|
||||
|
||||
|
||||
@ -116,19 +117,13 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// Instantiate.
|
||||
printf("Instantiating module...\n");
|
||||
/*const wasm_extern_t* imports1[] = {
|
||||
wasm_extern_t* externs[] = {
|
||||
wasm_global_as_extern(const_f32_import),
|
||||
wasm_global_as_extern(const_i64_import),
|
||||
wasm_global_as_extern(var_f32_import),
|
||||
wasm_global_as_extern(var_i64_import)
|
||||
};*/
|
||||
wasm_extern_vec_t imports;
|
||||
wasm_extern_vec_new(&imports, 4, (wasm_extern_t* []) {
|
||||
wasm_global_as_extern(const_f32_import),
|
||||
wasm_global_as_extern(const_i64_import),
|
||||
wasm_global_as_extern(var_f32_import),
|
||||
wasm_global_as_extern(var_i64_import)
|
||||
});
|
||||
};
|
||||
wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
|
||||
own wasm_instance_t* instance =
|
||||
wasm_instance_new(store, module, &imports, NULL);
|
||||
if (!instance) {
|
||||
@ -208,18 +203,19 @@ int main(int argc, const char* argv[]) {
|
||||
check_call(get_var_i64_export, i64, 38);
|
||||
|
||||
// Modify variables through calls and check again.
|
||||
wasm_val_vec_t args73;
|
||||
wasm_val_vec_new(&args73, 1, (wasm_val_t []){ WASM_F32_VAL(73) });
|
||||
wasm_func_call(set_var_f32_import, &args73, NULL);
|
||||
wasm_val_vec_t args74;
|
||||
wasm_val_vec_new(&args74, 1, (wasm_val_t []){ WASM_I64_VAL(74) });
|
||||
wasm_func_call(set_var_i64_import, &args74, NULL);
|
||||
wasm_val_vec_t args77;
|
||||
wasm_val_vec_new(&args77, 1, (wasm_val_t []){ WASM_F32_VAL(77) });
|
||||
wasm_func_call(set_var_f32_export, &args77, NULL);
|
||||
wasm_val_vec_t args78;
|
||||
wasm_val_vec_new(&args78, 1, (wasm_val_t []){ WASM_I64_VAL(78) });
|
||||
wasm_func_call(set_var_i64_export, &args78, NULL);
|
||||
wasm_val_vec_t res = WASM_EMPTY_VEC;
|
||||
wasm_val_t vs73[] = { WASM_F32_VAL(73) };
|
||||
wasm_val_vec_t args73 = WASM_ARRAY_VEC(vs73);
|
||||
wasm_func_call(set_var_f32_import, &args73, &res);
|
||||
wasm_val_t vs74[] = { WASM_I64_VAL(74) };
|
||||
wasm_val_vec_t args74 = WASM_ARRAY_VEC(vs74);
|
||||
wasm_func_call(set_var_i64_import, &args74, &res);
|
||||
wasm_val_t vs77[] = { WASM_F32_VAL(77) };
|
||||
wasm_val_vec_t args77 = WASM_ARRAY_VEC(vs77);
|
||||
wasm_func_call(set_var_f32_export, &args77, &res);
|
||||
wasm_val_t vs78[] = { WASM_I64_VAL(78) };
|
||||
wasm_val_vec_t args78 = WASM_ARRAY_VEC(vs78);
|
||||
wasm_func_call(set_var_i64_export, &args78, &res);
|
||||
|
||||
check_global(var_f32_import, f32, 73);
|
||||
check_global(var_i64_import, i64, 74);
|
||||
|
||||
@ -66,9 +66,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(hello_func) });
|
||||
|
||||
wasm_extern_t* externs[] = { wasm_func_as_extern(hello_func) };
|
||||
wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
|
||||
own wasm_instance_t* instance =
|
||||
wasm_instance_new(store, module, &imports, NULL);
|
||||
if (!instance) {
|
||||
@ -98,7 +97,9 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// Call.
|
||||
printf("Calling export...\n");
|
||||
if (wasm_func_call(run_func, NULL, NULL)) {
|
||||
wasm_val_vec_t args = WASM_EMPTY_VEC;
|
||||
wasm_val_vec_t results = WASM_EMPTY_VEC;
|
||||
if (wasm_func_call(run_func, &args, &results)) {
|
||||
printf("> Error calling function!\n");
|
||||
return 1;
|
||||
}
|
||||
@ -114,4 +115,3 @@ int main(int argc, const char* argv[]) {
|
||||
printf("Done.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -33,13 +33,10 @@ void check(bool success) {
|
||||
}
|
||||
|
||||
void check_call(wasm_func_t* func, int i, wasm_val_t args[], int32_t expected) {
|
||||
wasm_val_vec_t args_vec;
|
||||
wasm_val_vec_t results_vec;
|
||||
if (args)
|
||||
wasm_val_vec_new(&args_vec, i, args);
|
||||
wasm_val_vec_new(&results_vec, 1, (wasm_val_t []){ WASM_INIT_VAL });
|
||||
if (wasm_func_call(func, args ? &args_vec : NULL, &results_vec)
|
||||
|| results_vec.data[0].of.i32 != expected) {
|
||||
wasm_val_t r[] = {WASM_INIT_VAL};
|
||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t)};
|
||||
wasm_val_vec_t results = WASM_ARRAY_VEC(r);
|
||||
if (wasm_func_call(func, &args_, &results) || r[0].of.i32 != expected) {
|
||||
printf("> Error on result\n");
|
||||
exit(1);
|
||||
}
|
||||
@ -60,9 +57,9 @@ void check_call2(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected
|
||||
}
|
||||
|
||||
void check_ok(wasm_func_t* func, int i, wasm_val_t args[]) {
|
||||
wasm_val_vec_t args_vec;
|
||||
wasm_val_vec_new(&args_vec, i, args);
|
||||
if (wasm_func_call(func, &args_vec, NULL)) {
|
||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t)};
|
||||
wasm_val_vec_t results = WASM_EMPTY_VEC;
|
||||
if (wasm_func_call(func, &args_, &results)) {
|
||||
printf("> Error on result, expected empty\n");
|
||||
exit(1);
|
||||
}
|
||||
@ -74,10 +71,10 @@ void check_ok2(wasm_func_t* func, int32_t arg1, int32_t arg2) {
|
||||
}
|
||||
|
||||
void check_trap(wasm_func_t* func, int i, wasm_val_t args[]) {
|
||||
wasm_val_vec_t args_vec, results_vec;
|
||||
wasm_val_vec_new(&args_vec, i, args);
|
||||
wasm_val_vec_new(&results_vec, 1, (wasm_val_t []){ WASM_INIT_VAL });
|
||||
own wasm_trap_t* trap = wasm_func_call(func, &args_vec, &results_vec);
|
||||
wasm_val_t r[] = {WASM_INIT_VAL};
|
||||
wasm_val_vec_t args_ = {i, args, i, sizeof(wasm_val_t)};
|
||||
wasm_val_vec_t results = WASM_ARRAY_VEC(r);
|
||||
own wasm_trap_t* trap = wasm_func_call(func, &args_, &results);
|
||||
if (! trap) {
|
||||
printf("> Error on result, expected trap\n");
|
||||
exit(1);
|
||||
@ -137,8 +134,9 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// Instantiate.
|
||||
printf("Instantiating module...\n");
|
||||
own wasm_instance_t* instance =
|
||||
wasm_instance_new_with_args(store, module, NULL, NULL, KILOBYTE(8), 0);
|
||||
wasm_extern_vec_t imports = WASM_EMPTY_VEC;
|
||||
own wasm_instance_t *instance = wasm_instance_new_with_args(
|
||||
store, module, &imports, NULL, KILOBYTE(32), 0);
|
||||
if (!instance) {
|
||||
printf("> Error instantiating module!\n");
|
||||
return 1;
|
||||
@ -156,15 +154,6 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
wasm_module_delete(module);
|
||||
|
||||
if (!memory || !wasm_memory_data(memory)) {
|
||||
printf("> Error getting memory!\n");
|
||||
wasm_extern_vec_delete(&exports);
|
||||
wasm_instance_delete(instance);
|
||||
wasm_store_delete(store);
|
||||
wasm_engine_delete(engine);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Try cloning.
|
||||
own wasm_memory_t* copy = wasm_memory_copy(memory);
|
||||
assert(wasm_memory_same(memory, copy));
|
||||
@ -172,13 +161,13 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// Check initial memory.
|
||||
printf("Checking memory...\n");
|
||||
check(wasm_memory_size(memory) >= 2);
|
||||
check(wasm_memory_data_size(memory) >= 0x20000);
|
||||
check(wasm_memory_size(memory) == 2);
|
||||
check(wasm_memory_data_size(memory) == 0x20000);
|
||||
check(wasm_memory_data(memory)[0] == 0);
|
||||
check(wasm_memory_data(memory)[0x1000] == 1);
|
||||
check(wasm_memory_data(memory)[0x1003] == 4);
|
||||
|
||||
(void)size_func;
|
||||
check_call0(size_func, 2);
|
||||
check_call1(load_func, 0, 0);
|
||||
check_call1(load_func, 0x1000, 1);
|
||||
check_call1(load_func, 0x1003, 4);
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
// A function to be called from Wasm code.
|
||||
own wasm_trap_t* callback(
|
||||
const wasm_val_vec_t *args, wasm_val_vec_t *results
|
||||
const wasm_val_vec_t* args, wasm_val_vec_t* results
|
||||
) {
|
||||
printf("Calling back...\n> ");
|
||||
printf("> %"PRIu32" %"PRIu64" %"PRIu64" %"PRIu32"\n",
|
||||
@ -27,14 +27,14 @@ own wasm_trap_t* callback(
|
||||
|
||||
// A function closure.
|
||||
own wasm_trap_t* closure_callback(
|
||||
void* env, const wasm_val_t args[], wasm_val_t results[]
|
||||
void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results
|
||||
) {
|
||||
int i = *(int*)env;
|
||||
printf("Calling back closure...\n");
|
||||
printf("> %d\n", i);
|
||||
|
||||
results[0].kind = WASM_I32;
|
||||
results[0].of.i32 = (int32_t)i;
|
||||
results->data[0].kind = WASM_I32;
|
||||
results->data[0].of.i32 = (int32_t)i;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -47,7 +47,11 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// Load binary.
|
||||
printf("Loading binary...\n");
|
||||
#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0
|
||||
FILE* file = fopen("multi.aot", "rb");
|
||||
#else
|
||||
FILE* file = fopen("multi.wasm", "rb");
|
||||
#endif
|
||||
if (!file) {
|
||||
printf("> Error loading module!\n");
|
||||
return 1;
|
||||
@ -91,8 +95,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) {
|
||||
@ -121,13 +125,14 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// Call.
|
||||
printf("Calling export...\n");
|
||||
wasm_val_vec_t args, results;
|
||||
wasm_val_vec_new(&args, 4, (wasm_val_t []){
|
||||
WASM_I32_VAL(1), WASM_I64_VAL(2), WASM_I64_VAL(3), WASM_I32_VAL(4)
|
||||
});
|
||||
wasm_val_vec_new(&results, 4, (wasm_val_t []) {
|
||||
WASM_INIT_VAL, WASM_INIT_VAL, WASM_INIT_VAL, WASM_INIT_VAL
|
||||
});
|
||||
wasm_val_t vals[4] = {
|
||||
WASM_I32_VAL(1), WASM_I64_VAL(2), WASM_I64_VAL(3), WASM_I32_VAL(4)
|
||||
};
|
||||
wasm_val_t res[4] = {
|
||||
WASM_INIT_VAL, WASM_INIT_VAL, WASM_INIT_VAL, WASM_INIT_VAL
|
||||
};
|
||||
wasm_val_vec_t args = WASM_ARRAY_VEC(vals);
|
||||
wasm_val_vec_t results = WASM_ARRAY_VEC(res);
|
||||
if (wasm_func_call(run_func, &args, &results)) {
|
||||
printf("> Error calling function!\n");
|
||||
return 1;
|
||||
@ -138,12 +143,12 @@ int main(int argc, const char* argv[]) {
|
||||
// Print result.
|
||||
printf("Printing result...\n");
|
||||
printf("> %"PRIu32" %"PRIu64" %"PRIu64" %"PRIu32"\n",
|
||||
results.data[0].of.i32, results.data[1].of.i64, results.data[2].of.i64, results.data[3].of.i32);
|
||||
res[0].of.i32, res[1].of.i64, res[2].of.i64, res[3].of.i32);
|
||||
|
||||
assert(results.data[0].of.i32 == 1);
|
||||
assert(results.data[1].of.i64 == 2);
|
||||
assert(results.data[2].of.i64 == 3);
|
||||
assert(results.data[3].of.i32 == 4);
|
||||
assert(res[0].of.i32 == 4);
|
||||
assert(res[1].of.i64 == 3);
|
||||
assert(res[2].of.i64 == 2);
|
||||
assert(res[3].of.i32 == 1);
|
||||
|
||||
// Shut down.
|
||||
printf("Shutting down...\n");
|
||||
|
||||
@ -32,12 +32,6 @@ void print_valtype(const wasm_valtype_t* type) {
|
||||
|
||||
void print_valtypes(const wasm_valtype_vec_t* types) {
|
||||
bool first = true;
|
||||
|
||||
if (!types) {
|
||||
printf("> Error print a NULL valtype\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < types->size; ++i) {
|
||||
if (first) {
|
||||
first = false;
|
||||
@ -49,11 +43,6 @@ void print_valtypes(const wasm_valtype_vec_t* types) {
|
||||
}
|
||||
|
||||
void print_externtype(const wasm_externtype_t* type) {
|
||||
if (!type) {
|
||||
printf("> Error print a NULL externtype\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (wasm_externtype_kind(type)) {
|
||||
case WASM_EXTERN_FUNC: {
|
||||
const wasm_functype_t* functype =
|
||||
@ -89,11 +78,6 @@ void print_externtype(const wasm_externtype_t* type) {
|
||||
}
|
||||
|
||||
void print_name(const wasm_name_t* name) {
|
||||
if (!name) {
|
||||
printf("> Error print a NULL name\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\"%.*s\"", (int)name->size, name->data);
|
||||
}
|
||||
|
||||
@ -139,8 +123,9 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// Instantiate.
|
||||
printf("Instantiating module...\n");
|
||||
wasm_extern_vec_t imports = WASM_EMPTY_VEC;
|
||||
own wasm_instance_t* instance =
|
||||
wasm_instance_new(store, module, NULL, NULL);
|
||||
wasm_instance_new(store, module, &imports, NULL);
|
||||
if (!instance) {
|
||||
printf("> Error instantiating module!\n");
|
||||
return 1;
|
||||
|
||||
@ -49,19 +49,21 @@ void check_table(wasm_table_t* table, int32_t i, bool expect_set) {
|
||||
}
|
||||
|
||||
void check_call(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) {
|
||||
wasm_val_vec_t args, results;
|
||||
wasm_val_vec_new(&args, 2, (wasm_val_t []){ WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) });
|
||||
wasm_val_vec_new(&results, 1, (wasm_val_t []){ WASM_INIT_VAL });
|
||||
if (wasm_func_call(func, &args, &results) || results.data[0].of.i32 != expected) {
|
||||
wasm_val_t vs[2] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) };
|
||||
wasm_val_t r[1] = { WASM_INIT_VAL };
|
||||
wasm_val_vec_t args = WASM_ARRAY_VEC(vs);
|
||||
wasm_val_vec_t results = WASM_ARRAY_VEC(r);
|
||||
if (wasm_func_call(func, &args, &results) || r[0].of.i32 != expected) {
|
||||
printf("> Error on result\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void check_trap(wasm_func_t* func, int32_t arg1, int32_t arg2) {
|
||||
wasm_val_vec_t args, results;
|
||||
wasm_val_vec_new(&args, 2, (wasm_val_t []){ WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) });
|
||||
wasm_val_vec_new(&results, 1, (wasm_val_t []){ WASM_INIT_VAL });
|
||||
wasm_val_t vs[2] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) };
|
||||
wasm_val_t r[1] = { WASM_INIT_VAL };
|
||||
wasm_val_vec_t args = WASM_ARRAY_VEC(vs);
|
||||
wasm_val_vec_t results = WASM_ARRAY_VEC(r);
|
||||
own wasm_trap_t* trap = wasm_func_call(func, &args, &results);
|
||||
if (! trap) {
|
||||
printf("> Error on result, expected trap\n");
|
||||
@ -112,8 +114,9 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// Instantiate.
|
||||
printf("Instantiating module...\n");
|
||||
own wasm_instance_t *instance =
|
||||
wasm_instance_new(store, module, NULL, NULL);
|
||||
wasm_extern_vec_t imports = WASM_EMPTY_VEC;
|
||||
own wasm_instance_t* instance =
|
||||
wasm_instance_new(store, module, &imports, NULL);
|
||||
if (!instance) {
|
||||
printf("> Error instantiating module!\n");
|
||||
return 1;
|
||||
@ -134,6 +137,7 @@ int main(int argc, const char* argv[]) {
|
||||
// Create external function.
|
||||
printf("Creating callback...\n");
|
||||
own wasm_functype_t* neg_type = wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32());
|
||||
own wasm_func_t* h = wasm_func_new(store, neg_type, neg_callback);
|
||||
|
||||
wasm_functype_delete(neg_type);
|
||||
|
||||
@ -155,7 +159,9 @@ int main(int argc, const char* argv[]) {
|
||||
printf("Mutating table...\n");
|
||||
check(wasm_table_set(table, 0, wasm_func_as_ref(g)));
|
||||
check(wasm_table_set(table, 1, NULL));
|
||||
check(! wasm_table_set(table, 2, wasm_func_as_ref(f)));
|
||||
wasm_ref_t *ref_f = wasm_func_as_ref(f);
|
||||
check(! wasm_table_set(table, 2, ref_f));
|
||||
wasm_ref_delete(ref_f);
|
||||
check_table(table, 0, true);
|
||||
check_table(table, 1, false);
|
||||
check_call(call_indirect, 7, 0, 666);
|
||||
@ -165,6 +171,8 @@ int main(int argc, const char* argv[]) {
|
||||
// Grow table.
|
||||
// DO NOT SUPPORT
|
||||
printf("Bypass Growing table...\n");
|
||||
|
||||
wasm_func_delete(h);
|
||||
wasm_extern_vec_delete(&exports);
|
||||
wasm_instance_delete(instance);
|
||||
|
||||
|
||||
@ -80,8 +80,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(fail_func) });
|
||||
wasm_extern_t* externs[] = { wasm_func_as_extern(fail_func) };
|
||||
wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
|
||||
own wasm_instance_t* instance =
|
||||
wasm_instance_new(store, module, &imports, NULL);
|
||||
if (!instance) {
|
||||
@ -112,10 +112,9 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
|
||||
printf("Calling export %d...\n", i);
|
||||
|
||||
wasm_val_vec_t results;
|
||||
wasm_val_vec_new_uninitialized(&results, 1);
|
||||
own wasm_trap_t* trap = wasm_func_call(func, NULL, &results);
|
||||
wasm_val_vec_t args = WASM_EMPTY_VEC;
|
||||
wasm_val_vec_t results = WASM_EMPTY_VEC;
|
||||
own wasm_trap_t* trap = wasm_func_call(func, &args, &results);
|
||||
if (!trap) {
|
||||
printf("> Error calling function, expected trap!\n");
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user