demo.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include <assert.h>
  6. #include <inttypes.h>
  7. #include <pthread.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "wasm_c_api.h"
  12. #define own
  13. /* return a copy of the file stem of a file path */
  14. static own char *
  15. stem(const char *file_path)
  16. {
  17. char *base_name = basename(file_path);
  18. char *s = strdup(base_name);
  19. char *dot = strchr(s, '.');
  20. assert(dot);
  21. *dot = '\0';
  22. return s;
  23. }
  24. static void
  25. guest_i32_to_wasm_i32_array(int *args, unsigned argc, wasm_val_t *data,
  26. unsigned datac)
  27. {
  28. for (unsigned i = 0; i < argc && i < datac; i++) {
  29. memset(&data[i], 0, sizeof(wasm_val_t));
  30. data[i].kind = WASM_I32;
  31. data[i].of.i32 = args[i];
  32. }
  33. }
  34. int
  35. load_run_wasm_file(wasm_engine_t *engine, const char *file_path, int *args,
  36. unsigned argc)
  37. {
  38. wasm_store_t *store = wasm_store_new(engine);
  39. // Load binary.
  40. printf("Loading binary...\n");
  41. FILE *file = fopen(file_path, "rb");
  42. assert(file);
  43. int ret = fseek(file, 0L, SEEK_END);
  44. assert(ret == 0);
  45. long file_size = ftell(file);
  46. assert(file_size != -1);
  47. ret = fseek(file, 0L, SEEK_SET);
  48. assert(ret == 0);
  49. wasm_byte_vec_t binary = { 0 };
  50. wasm_byte_vec_new_uninitialized(&binary, file_size);
  51. size_t nread = fread(binary.data, file_size, 1, file);
  52. fclose(file);
  53. // Compile.
  54. printf("Compiling module...\n");
  55. // Use its file name as the module name
  56. char *file_name = stem(file_path);
  57. assert(file_name);
  58. LoadArgs load_args = { 0 };
  59. load_args.name = file_name;
  60. own wasm_module_t *module = wasm_module_new_ex(store, &binary, &load_args);
  61. wasm_byte_vec_delete(&binary);
  62. assert(module);
  63. // Use export type to find the function index to call later
  64. wasm_exporttype_vec_t export_types = { 0 };
  65. wasm_module_exports(module, &export_types);
  66. int func_to_call = -1;
  67. for (unsigned i = 0; i < export_types.num_elems; i++) {
  68. const wasm_name_t *name = wasm_exporttype_name(export_types.data[i]);
  69. if (strncmp(name->data, "run", 3) == 0) {
  70. func_to_call = i;
  71. break;
  72. }
  73. }
  74. assert(func_to_call != -1);
  75. // Instantiate.
  76. printf("Instantiating module...\n");
  77. wasm_extern_vec_t imports = WASM_EMPTY_VEC;
  78. own wasm_instance_t *instance = wasm_instance_new_with_args(
  79. store, module, &imports, NULL, 16 * 1024 * 1024, 1 * 1024 * 1024);
  80. assert(instance);
  81. // Extract export.
  82. printf("Extracting export...\n");
  83. own wasm_extern_vec_t exports;
  84. wasm_instance_exports(instance, &exports);
  85. assert(exports.size);
  86. assert(wasm_extern_kind(exports.data[func_to_call]) == WASM_EXTERN_FUNC);
  87. const wasm_func_t *run_func =
  88. wasm_extern_as_func(exports.data[func_to_call]);
  89. assert(run_func);
  90. wasm_module_delete(module);
  91. wasm_instance_delete(instance);
  92. // Call.
  93. printf("Calling export...\n");
  94. wasm_val_t as[4] = { 0 };
  95. guest_i32_to_wasm_i32_array(args, argc, as, 4);
  96. wasm_val_vec_t params = WASM_ARRAY_VEC(as);
  97. wasm_val_t rs[1] = { WASM_I32_VAL(0) };
  98. wasm_val_vec_t results = WASM_ARRAY_VEC(rs);
  99. wasm_trap_t *trap = wasm_func_call(run_func, &params, &results);
  100. assert(!trap);
  101. wasm_extern_vec_delete(&exports);
  102. free(file_name);
  103. wasm_store_delete(store);
  104. {
  105. nread = nread;
  106. ret = ret;
  107. trap = trap;
  108. }
  109. return 0;
  110. }
  111. void *
  112. load_run_fib_wasm(void *arg)
  113. {
  114. wasm_engine_t *engine = (wasm_engine_t *)arg;
  115. int args[] = { 40 };
  116. load_run_wasm_file(engine, "./fib1.wasm", args, 1);
  117. return NULL;
  118. }
  119. void *
  120. load_run_fib_aot(void *arg)
  121. {
  122. wasm_engine_t *engine = (wasm_engine_t *)arg;
  123. int args[] = { 40 };
  124. load_run_wasm_file(engine, "./fib2.aot", args, 1);
  125. return NULL;
  126. }
  127. void *
  128. load_run_ackermann_wasm(void *arg)
  129. {
  130. wasm_engine_t *engine = (wasm_engine_t *)arg;
  131. int args[] = { 3, 12 };
  132. load_run_wasm_file(engine, "./ackermann1.wasm", args, 2);
  133. return NULL;
  134. }
  135. void *
  136. load_run_ackermann_aot(void *arg)
  137. {
  138. wasm_engine_t *engine = (wasm_engine_t *)arg;
  139. int args[] = { 3, 12 };
  140. load_run_wasm_file(engine, "./ackermann2.aot", args, 2);
  141. return NULL;
  142. }
  143. int
  144. main(int argc, const char *argv[])
  145. {
  146. // Initialize.
  147. printf("Initializing...\n");
  148. wasm_config_t *config = wasm_config_new();
  149. wasm_config_set_linux_perf_opt(config, true);
  150. wasm_engine_t *engine = wasm_engine_new_with_config(config);
  151. pthread_t tid[4] = { 0 };
  152. /* FIXME: uncomment when it is able to run two modules with llvm-jit */
  153. // pthread_create(&tid[0], NULL, load_run_fib_wasm, (void *)engine);
  154. // pthread_create(&tid[2], NULL, load_run_ackermann_wasm, (void *)engine);
  155. pthread_create(&tid[1], NULL, load_run_fib_aot, (void *)engine);
  156. pthread_create(&tid[3], NULL, load_run_ackermann_aot, (void *)engine);
  157. for (unsigned i = 0; i < sizeof(tid) / sizeof(tid[0]); i++)
  158. pthread_join(tid[i], NULL);
  159. // Shut down.
  160. printf("Shutting down...\n");
  161. wasm_engine_delete(engine);
  162. // All done.
  163. printf("Done.\n");
  164. return 0;
  165. }