global.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <inttypes.h>
  5. #include "wasm_c_api.h"
  6. #define own
  7. wasm_global_t* get_export_global(const wasm_extern_vec_t* exports, size_t i) {
  8. if (exports->size <= i || !wasm_extern_as_global(exports->data[i])) {
  9. printf("> Error accessing global export %zu!\n", i);
  10. exit(1);
  11. }
  12. return wasm_extern_as_global(exports->data[i]);
  13. }
  14. wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) {
  15. if (exports->size <= i || !wasm_extern_as_func(exports->data[i])) {
  16. printf("> Error accessing function export %zu!\n", i);
  17. exit(1);
  18. }
  19. return wasm_extern_as_func(exports->data[i]);
  20. }
  21. #define check(val, type, expected) \
  22. if (val.of.type != expected) { \
  23. printf("> Error reading value\n"); \
  24. exit(1); \
  25. }
  26. #define check_global(global, type, expected) \
  27. { \
  28. wasm_val_t val; \
  29. wasm_global_get(global, &val); \
  30. check(val, type, expected); \
  31. }
  32. #define check_trap(trap) \
  33. if (trap) { \
  34. printf("> Error calling function\n"); \
  35. wasm_trap_delete(trap); \
  36. exit(1); \
  37. }
  38. #define check_call(func, type, expected) \
  39. { \
  40. wasm_val_t vs[1]; \
  41. wasm_val_vec_t args = WASM_EMPTY_VEC; \
  42. wasm_val_vec_t results = WASM_ARRAY_VEC(vs); \
  43. wasm_trap_t *trap = wasm_func_call(func, &args, &results); \
  44. check_trap(trap); \
  45. check(vs[0], type, expected); \
  46. }
  47. int main(int argc, const char* argv[]) {
  48. // Initialize.
  49. printf("Initializing...\n");
  50. wasm_engine_t* engine = wasm_engine_new();
  51. wasm_store_t* store = wasm_store_new(engine);
  52. // Load binary.
  53. printf("Loading binary...\n");
  54. #if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0
  55. FILE* file = fopen("global.aot", "rb");
  56. #else
  57. FILE* file = fopen("global.wasm", "rb");
  58. #endif
  59. if (!file) {
  60. printf("> Error loading module!\n");
  61. return 1;
  62. }
  63. int ret = fseek(file, 0L, SEEK_END);
  64. if (ret == -1) {
  65. printf("> Error loading module!\n");
  66. fclose(file);
  67. return 1;
  68. }
  69. long file_size = ftell(file);
  70. if (file_size == -1) {
  71. printf("> Error loading module!\n");
  72. fclose(file);
  73. return 1;
  74. }
  75. ret = fseek(file, 0L, SEEK_SET);
  76. if (ret == -1) {
  77. printf("> Error loading module!\n");
  78. fclose(file);
  79. return 1;
  80. }
  81. wasm_byte_vec_t binary;
  82. wasm_byte_vec_new_uninitialized(&binary, file_size);
  83. if (fread(binary.data, file_size, 1, file) != 1) {
  84. printf("> Error loading module!\n");
  85. fclose(file);
  86. return 1;
  87. }
  88. fclose(file);
  89. // Compile.
  90. printf("Compiling module...\n");
  91. own wasm_module_t* module = wasm_module_new(store, &binary);
  92. if (!module) {
  93. printf("> Error compiling module!\n");
  94. return 1;
  95. }
  96. wasm_byte_vec_delete(&binary);
  97. // Create external globals.
  98. printf("Creating globals...\n");
  99. own wasm_globaltype_t* const_f32_type = wasm_globaltype_new(
  100. wasm_valtype_new(WASM_F32), WASM_CONST);
  101. own wasm_globaltype_t* const_i64_type = wasm_globaltype_new(
  102. wasm_valtype_new(WASM_I64), WASM_CONST);
  103. own wasm_globaltype_t* var_f32_type = wasm_globaltype_new(
  104. wasm_valtype_new(WASM_F32), WASM_VAR);
  105. own wasm_globaltype_t* var_i64_type = wasm_globaltype_new(
  106. wasm_valtype_new(WASM_I64), WASM_VAR);
  107. wasm_val_t val_f32_1 = WASM_F32_VAL(1);
  108. own wasm_global_t* const_f32_import =
  109. wasm_global_new(store, const_f32_type, &val_f32_1);
  110. wasm_val_t val_i64_2 = WASM_I64_VAL(2);
  111. own wasm_global_t* const_i64_import =
  112. wasm_global_new(store, const_i64_type, &val_i64_2);
  113. wasm_val_t val_f32_3 = WASM_F32_VAL(3);
  114. own wasm_global_t* var_f32_import =
  115. wasm_global_new(store, var_f32_type, &val_f32_3);
  116. wasm_val_t val_i64_4 = WASM_I64_VAL(4);
  117. own wasm_global_t* var_i64_import =
  118. wasm_global_new(store, var_i64_type, &val_i64_4);
  119. wasm_globaltype_delete(const_f32_type);
  120. wasm_globaltype_delete(const_i64_type);
  121. wasm_globaltype_delete(var_f32_type);
  122. wasm_globaltype_delete(var_i64_type);
  123. // Instantiate.
  124. printf("Instantiating module...\n");
  125. wasm_extern_t* externs[] = {
  126. wasm_global_as_extern(const_f32_import),
  127. wasm_global_as_extern(const_i64_import),
  128. wasm_global_as_extern(var_f32_import),
  129. wasm_global_as_extern(var_i64_import)
  130. };
  131. wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
  132. own wasm_instance_t* instance =
  133. wasm_instance_new(store, module, &imports, NULL);
  134. if (!instance) {
  135. printf("> Error instantiating module!\n");
  136. return 1;
  137. }
  138. wasm_module_delete(module);
  139. // Extract export.
  140. printf("Extracting exports...\n");
  141. own wasm_extern_vec_t exports;
  142. wasm_instance_exports(instance, &exports);
  143. size_t i = 0;
  144. wasm_global_t* const_f32_export = get_export_global(&exports, i++);
  145. wasm_global_t* const_i64_export = get_export_global(&exports, i++);
  146. wasm_global_t* var_f32_export = get_export_global(&exports, i++);
  147. wasm_global_t* var_i64_export = get_export_global(&exports, i++);
  148. wasm_func_t* get_const_f32_import = get_export_func(&exports, i++);
  149. wasm_func_t* get_const_i64_import = get_export_func(&exports, i++);
  150. wasm_func_t* get_var_f32_import = get_export_func(&exports, i++);
  151. wasm_func_t* get_var_i64_import = get_export_func(&exports, i++);
  152. wasm_func_t* get_const_f32_export = get_export_func(&exports, i++);
  153. wasm_func_t* get_const_i64_export = get_export_func(&exports, i++);
  154. wasm_func_t* get_var_f32_export = get_export_func(&exports, i++);
  155. wasm_func_t* get_var_i64_export = get_export_func(&exports, i++);
  156. wasm_func_t* set_var_f32_import = get_export_func(&exports, i++);
  157. wasm_func_t* set_var_i64_import = get_export_func(&exports, i++);
  158. wasm_func_t* set_var_f32_export = get_export_func(&exports, i++);
  159. wasm_func_t* set_var_i64_export = get_export_func(&exports, i++);
  160. // Try cloning.
  161. own wasm_global_t* copy = wasm_global_copy(var_f32_import);
  162. assert(wasm_global_same(var_f32_import, copy));
  163. wasm_global_delete(copy);
  164. // Interact.
  165. printf("Accessing globals...\n");
  166. // Check initial values.
  167. check_global(const_f32_import, f32, 1);
  168. check_global(const_i64_import, i64, 2);
  169. check_global(var_f32_import, f32, 3);
  170. check_global(var_i64_import, i64, 4);
  171. check_global(const_f32_export, f32, 5);
  172. check_global(const_i64_export, i64, 6);
  173. check_global(var_f32_export, f32, 7);
  174. check_global(var_i64_export, i64, 8);
  175. check_call(get_const_f32_import, f32, 1);
  176. check_call(get_const_i64_import, i64, 2);
  177. check_call(get_var_f32_import, f32, 3);
  178. check_call(get_var_i64_import, i64, 4);
  179. check_call(get_const_f32_export, f32, 5);
  180. check_call(get_const_i64_export, i64, 6);
  181. check_call(get_var_f32_export, f32, 7);
  182. check_call(get_var_i64_export, i64, 8);
  183. // Modify variables through API and check again.
  184. wasm_val_t val33 = WASM_F32_VAL(33);
  185. wasm_global_set(var_f32_import, &val33);
  186. wasm_val_t val34 = WASM_I64_VAL(34);
  187. wasm_global_set(var_i64_import, &val34);
  188. wasm_val_t val37 = WASM_F32_VAL(37);
  189. wasm_global_set(var_f32_export, &val37);
  190. wasm_val_t val38 = WASM_I64_VAL(38);
  191. wasm_global_set(var_i64_export, &val38);
  192. check_global(var_f32_import, f32, 33);
  193. check_global(var_i64_import, i64, 34);
  194. check_global(var_f32_export, f32, 37);
  195. check_global(var_i64_export, i64, 38);
  196. check_call(get_var_f32_import, f32, 33);
  197. check_call(get_var_i64_import, i64, 34);
  198. check_call(get_var_f32_export, f32, 37);
  199. check_call(get_var_i64_export, i64, 38);
  200. // Modify variables through calls and check again.
  201. wasm_val_vec_t res = WASM_EMPTY_VEC;
  202. wasm_val_t vs73[] = { WASM_F32_VAL(73) };
  203. wasm_val_vec_t args73 = WASM_ARRAY_VEC(vs73);
  204. wasm_trap_t *trap = wasm_func_call(set_var_f32_import, &args73, &res);
  205. check_trap(trap);
  206. wasm_val_t vs74[] = { WASM_I64_VAL(74) };
  207. wasm_val_vec_t args74 = WASM_ARRAY_VEC(vs74);
  208. trap = wasm_func_call(set_var_i64_import, &args74, &res);
  209. check_trap(trap);
  210. wasm_val_t vs77[] = { WASM_F32_VAL(77) };
  211. wasm_val_vec_t args77 = WASM_ARRAY_VEC(vs77);
  212. trap = wasm_func_call(set_var_f32_export, &args77, &res);
  213. check_trap(trap);
  214. wasm_val_t vs78[] = { WASM_I64_VAL(78) };
  215. wasm_val_vec_t args78 = WASM_ARRAY_VEC(vs78);
  216. trap = wasm_func_call(set_var_i64_export, &args78, &res);
  217. check_trap(trap);
  218. check_global(var_f32_import, f32, 73);
  219. check_global(var_i64_import, i64, 74);
  220. check_global(var_f32_export, f32, 77);
  221. check_global(var_i64_export, i64, 78);
  222. check_call(get_var_f32_import, f32, 73);
  223. check_call(get_var_i64_import, i64, 74);
  224. check_call(get_var_f32_export, f32, 77);
  225. check_call(get_var_i64_export, i64, 78);
  226. wasm_global_delete(const_f32_import);
  227. wasm_global_delete(const_i64_import);
  228. wasm_global_delete(var_f32_import);
  229. wasm_global_delete(var_i64_import);
  230. wasm_extern_vec_delete(&exports);
  231. wasm_instance_delete(instance);
  232. // Shut down.
  233. printf("Shutting down...\n");
  234. wasm_store_delete(store);
  235. wasm_engine_delete(engine);
  236. // All done.
  237. printf("Done.\n");
  238. return 0;
  239. }