trap.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. // A function to be called from Wasm code.
  8. own wasm_trap_t* fail_callback(
  9. void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results
  10. ) {
  11. printf("Calling back...\n");
  12. own wasm_name_t message;
  13. wasm_name_new_from_string_nt(&message, "callback abort");
  14. own wasm_trap_t* trap = wasm_trap_new((wasm_store_t*)env, &message);
  15. wasm_name_delete(&message);
  16. return trap;
  17. }
  18. void print_frame(wasm_frame_t* frame) {
  19. printf("> %p @ 0x%zx = %"PRIu32".0x%zx\n",
  20. wasm_frame_instance(frame),
  21. wasm_frame_module_offset(frame),
  22. wasm_frame_func_index(frame),
  23. wasm_frame_func_offset(frame)
  24. );
  25. }
  26. int main(int argc, const char* argv[]) {
  27. // Initialize.
  28. printf("Initializing...\n");
  29. wasm_engine_t* engine = wasm_engine_new();
  30. wasm_store_t* store = wasm_store_new(engine);
  31. // Load binary.
  32. printf("Loading binary...\n");
  33. #if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0
  34. FILE* file = fopen("trap.aot", "rb");
  35. #else
  36. FILE* file = fopen("trap.wasm", "rb");
  37. #endif
  38. if (!file) {
  39. printf("> Error loading module!\n");
  40. return 1;
  41. }
  42. int ret = fseek(file, 0L, SEEK_END);
  43. if (ret == -1) {
  44. printf("> Error loading module!\n");
  45. fclose(file);
  46. return 1;
  47. }
  48. long file_size = ftell(file);
  49. if (file_size == -1) {
  50. printf("> Error loading module!\n");
  51. fclose(file);
  52. return 1;
  53. }
  54. ret = fseek(file, 0L, SEEK_SET);
  55. if (ret == -1) {
  56. printf("> Error loading module!\n");
  57. fclose(file);
  58. return 1;
  59. }
  60. wasm_byte_vec_t binary;
  61. wasm_byte_vec_new_uninitialized(&binary, file_size);
  62. if (fread(binary.data, file_size, 1, file) != 1) {
  63. printf("> Error loading module!\n");
  64. fclose(file);
  65. return 1;
  66. }
  67. fclose(file);
  68. // Compile.
  69. printf("Compiling module...\n");
  70. own wasm_module_t* module = wasm_module_new(store, &binary);
  71. if (!module) {
  72. printf("> Error compiling module!\n");
  73. return 1;
  74. }
  75. wasm_byte_vec_delete(&binary);
  76. // Create external print functions.
  77. printf("Creating callback...\n");
  78. own wasm_functype_t* fail_type =
  79. wasm_functype_new_0_1(wasm_valtype_new_i32());
  80. own wasm_func_t* fail_func =
  81. wasm_func_new_with_env(store, fail_type, fail_callback, store, NULL);
  82. wasm_functype_delete(fail_type);
  83. // Instantiate.
  84. printf("Instantiating module...\n");
  85. wasm_extern_t* externs[] = { wasm_func_as_extern(fail_func) };
  86. wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
  87. own wasm_instance_t* instance =
  88. wasm_instance_new(store, module, &imports, NULL);
  89. if (!instance) {
  90. printf("> Error instantiating module!\n");
  91. return 1;
  92. }
  93. wasm_func_delete(fail_func);
  94. // Extract export.
  95. printf("Extracting exports...\n");
  96. own wasm_extern_vec_t exports;
  97. wasm_instance_exports(instance, &exports);
  98. if (exports.size < 2) {
  99. printf("> Error accessing exports!\n");
  100. return 1;
  101. }
  102. wasm_module_delete(module);
  103. wasm_instance_delete(instance);
  104. // Call.
  105. for (int i = 0; i < 2; ++i) {
  106. const wasm_func_t* func = wasm_extern_as_func(exports.data[i]);
  107. if (func == NULL) {
  108. printf("> Error accessing export!\n");
  109. return 1;
  110. }
  111. printf("Calling export %d...\n", i);
  112. wasm_val_vec_t args = WASM_EMPTY_VEC;
  113. wasm_val_vec_t results = WASM_EMPTY_VEC;
  114. own wasm_trap_t* trap = wasm_func_call(func, &args, &results);
  115. if (!trap) {
  116. printf("> Error calling function, expected trap!\n");
  117. return 1;
  118. }
  119. printf("Printing message...\n");
  120. own wasm_name_t message;
  121. wasm_trap_message(trap, &message);
  122. printf("> %s\n", message.data);
  123. assert(message.num_elems > 0);
  124. assert(strncmp(message.data, "Exception: ", strlen("Exception: ")) == 0);
  125. printf("Printing origin...\n");
  126. own wasm_frame_t* frame = wasm_trap_origin(trap);
  127. if (frame) {
  128. print_frame(frame);
  129. wasm_frame_delete(frame);
  130. } else {
  131. printf("> Empty origin.\n");
  132. }
  133. printf("Printing trace...\n");
  134. own wasm_frame_vec_t trace;
  135. wasm_trap_trace(trap, &trace);
  136. if (trace.size > 0) {
  137. for (size_t i = 0; i < trace.size; ++i) {
  138. print_frame(trace.data[i]);
  139. }
  140. } else {
  141. printf("> Empty trace.\n");
  142. }
  143. wasm_frame_vec_delete(&trace);
  144. wasm_trap_delete(trap);
  145. wasm_name_delete(&message);
  146. }
  147. wasm_extern_vec_delete(&exports);
  148. // Shut down.
  149. printf("Shutting down...\n");
  150. wasm_store_delete(store);
  151. wasm_engine_delete(engine);
  152. // All done.
  153. printf("Done.\n");
  154. return 0;
  155. }