| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- /*
- * Copyright (C) 2019 Intel Corporation. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- */
- #include <assert.h>
- #include <inttypes.h>
- #include <pthread.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "wasm_c_api.h"
- #define own
- /* return a copy of the file stem of a file path */
- static own char *
- stem(const char *file_path)
- {
- char *base_name = basename(file_path);
- char *s = strdup(base_name);
- char *dot = strchr(s, '.');
- assert(dot);
- *dot = '\0';
- return s;
- }
- static void
- guest_i32_to_wasm_i32_array(int *args, unsigned argc, wasm_val_t *data,
- unsigned datac)
- {
- for (unsigned i = 0; i < argc && i < datac; i++) {
- memset(&data[i], 0, sizeof(wasm_val_t));
- data[i].kind = WASM_I32;
- data[i].of.i32 = args[i];
- }
- }
- int
- load_run_wasm_file(wasm_engine_t *engine, const char *file_path, int *args,
- unsigned argc)
- {
- wasm_store_t *store = wasm_store_new(engine);
- // Load binary.
- printf("Loading binary...\n");
- FILE *file = fopen(file_path, "rb");
- assert(file);
- int ret = fseek(file, 0L, SEEK_END);
- assert(ret == 0);
- long file_size = ftell(file);
- assert(file_size != -1);
- ret = fseek(file, 0L, SEEK_SET);
- assert(ret == 0);
- wasm_byte_vec_t binary = { 0 };
- wasm_byte_vec_new_uninitialized(&binary, file_size);
- size_t nread = fread(binary.data, file_size, 1, file);
- fclose(file);
- // Compile.
- printf("Compiling module...\n");
- // Use its file name as the module name
- char *file_name = stem(file_path);
- assert(file_name);
- LoadArgs load_args = { 0 };
- load_args.name = file_name;
- own wasm_module_t *module = wasm_module_new_ex(store, &binary, &load_args);
- wasm_byte_vec_delete(&binary);
- assert(module);
- // Use export type to find the function index to call later
- wasm_exporttype_vec_t export_types = { 0 };
- wasm_module_exports(module, &export_types);
- int func_to_call = -1;
- for (unsigned i = 0; i < export_types.num_elems; i++) {
- const wasm_name_t *name = wasm_exporttype_name(export_types.data[i]);
- if (strncmp(name->data, "run", 3) == 0) {
- func_to_call = i;
- break;
- }
- }
- assert(func_to_call != -1);
- // Instantiate.
- printf("Instantiating module...\n");
- wasm_extern_vec_t imports = WASM_EMPTY_VEC;
- own wasm_instance_t *instance = wasm_instance_new_with_args(
- store, module, &imports, NULL, 16 * 1024 * 1024, 1 * 1024 * 1024);
- assert(instance);
- // Extract export.
- printf("Extracting export...\n");
- own wasm_extern_vec_t exports;
- wasm_instance_exports(instance, &exports);
- assert(exports.size);
- assert(wasm_extern_kind(exports.data[func_to_call]) == WASM_EXTERN_FUNC);
- const wasm_func_t *run_func =
- wasm_extern_as_func(exports.data[func_to_call]);
- assert(run_func);
- wasm_module_delete(module);
- wasm_instance_delete(instance);
- // Call.
- printf("Calling export...\n");
- wasm_val_t as[4] = { 0 };
- guest_i32_to_wasm_i32_array(args, argc, as, 4);
- wasm_val_vec_t params = WASM_ARRAY_VEC(as);
- wasm_val_t rs[1] = { WASM_I32_VAL(0) };
- wasm_val_vec_t results = WASM_ARRAY_VEC(rs);
- wasm_trap_t *trap = wasm_func_call(run_func, ¶ms, &results);
- assert(!trap);
- wasm_extern_vec_delete(&exports);
- free(file_name);
- wasm_store_delete(store);
- {
- nread = nread;
- ret = ret;
- trap = trap;
- }
- return 0;
- }
- void *
- load_run_fib_wasm(void *arg)
- {
- wasm_engine_t *engine = (wasm_engine_t *)arg;
- int args[] = { 40 };
- load_run_wasm_file(engine, "./fib1.wasm", args, 1);
- return NULL;
- }
- void *
- load_run_fib_aot(void *arg)
- {
- wasm_engine_t *engine = (wasm_engine_t *)arg;
- int args[] = { 40 };
- load_run_wasm_file(engine, "./fib2.aot", args, 1);
- return NULL;
- }
- void *
- load_run_ackermann_wasm(void *arg)
- {
- wasm_engine_t *engine = (wasm_engine_t *)arg;
- int args[] = { 3, 12 };
- load_run_wasm_file(engine, "./ackermann1.wasm", args, 2);
- return NULL;
- }
- void *
- load_run_ackermann_aot(void *arg)
- {
- wasm_engine_t *engine = (wasm_engine_t *)arg;
- int args[] = { 3, 12 };
- load_run_wasm_file(engine, "./ackermann2.aot", args, 2);
- return NULL;
- }
- int
- main(int argc, const char *argv[])
- {
- // Initialize.
- printf("Initializing...\n");
- wasm_config_t *config = wasm_config_new();
- wasm_config_set_linux_perf_opt(config, true);
- wasm_engine_t *engine = wasm_engine_new_with_config(config);
- pthread_t tid[4] = { 0 };
- /* FIXME: uncomment when it is able to run two modules with llvm-jit */
- // pthread_create(&tid[0], NULL, load_run_fib_wasm, (void *)engine);
- // pthread_create(&tid[2], NULL, load_run_ackermann_wasm, (void *)engine);
- pthread_create(&tid[1], NULL, load_run_fib_aot, (void *)engine);
- pthread_create(&tid[3], NULL, load_run_ackermann_aot, (void *)engine);
- for (unsigned i = 0; i < sizeof(tid) / sizeof(tid[0]); i++)
- pthread_join(tid[i], NULL);
- // Shut down.
- printf("Shutting down...\n");
- wasm_engine_delete(engine);
- // All done.
- printf("Done.\n");
- return 0;
- }
|