xref: /wasmtime-44.0.1/examples/fib-debug/main.c (revision adff9d9d)
1f8fee938STyler Rockwood #include <inttypes.h>
23c51d3adSAlex Crichton #include <stdio.h>
33c51d3adSAlex Crichton #include <stdlib.h>
43c51d3adSAlex Crichton #include <string.h>
53c51d3adSAlex Crichton #include <wasm.h>
67a1b7cdfSAlex Crichton #include <wasmtime.h>
73c51d3adSAlex Crichton 
86a95189cSBen Jackson #ifdef WASMTIME_TEST_ONLY
96a95189cSBen Jackson // These are the declarations provided from GDB documentation, used to validate
106a95189cSBen Jackson // that we actually added some DWARF info:
116a95189cSBen Jackson // https://sourceware.org/gdb/current/onlinedocs/gdb.html/Declarations.html#Declarations
126a95189cSBen Jackson //
136a95189cSBen Jackson // NOTE: These are not required in your code, rather they are used for wasmtime
146a95189cSBen Jackson // testing only.
156a95189cSBen Jackson typedef enum {
166a95189cSBen Jackson   JIT_NOACTION = 0,
176a95189cSBen Jackson   JIT_REGISTER_FN,
186a95189cSBen Jackson   JIT_UNREGISTER_FN
196a95189cSBen Jackson } jit_actions_t;
206a95189cSBen Jackson 
216a95189cSBen Jackson struct jit_code_entry {
226a95189cSBen Jackson   struct jit_code_entry *next_entry;
236a95189cSBen Jackson   struct jit_code_entry *prev_entry;
246a95189cSBen Jackson   const char *symfile_addr;
256a95189cSBen Jackson   uint64_t symfile_size;
266a95189cSBen Jackson };
276a95189cSBen Jackson 
286a95189cSBen Jackson struct jit_descriptor {
296a95189cSBen Jackson   uint32_t version;
306a95189cSBen Jackson   /* This type should be jit_actions_t, but we use uint32_t
316a95189cSBen Jackson      to be explicit about the bitwidth.  */
326a95189cSBen Jackson   uint32_t action_flag;
336a95189cSBen Jackson   struct jit_code_entry *relevant_entry;
346a95189cSBen Jackson   struct jit_code_entry *first_entry;
356a95189cSBen Jackson };
366a95189cSBen Jackson 
376a95189cSBen Jackson /*
386a95189cSBen Jackson  * Import the descriptor, defined elsewhere in wasmtime
396a95189cSBen Jackson  */
406a95189cSBen Jackson extern struct jit_descriptor __jit_debug_descriptor;
416a95189cSBen Jackson #endif
426a95189cSBen Jackson 
433c51d3adSAlex Crichton #define own
443c51d3adSAlex Crichton 
45f8fee938STyler Rockwood static void exit_with_error(const char *message, wasmtime_error_t *error,
46f8fee938STyler Rockwood                             wasm_trap_t *trap);
47bd374fd6SAlex Crichton 
main()48*adff9d9dSAlex Crichton int main() {
493c51d3adSAlex Crichton   // Configuring engine to support generating of DWARF info.
503c51d3adSAlex Crichton   // lldb can be used to attach to the program and observe
513c51d3adSAlex Crichton   // original fib-wasm.c source code and variables.
523c51d3adSAlex Crichton   wasm_config_t *config = wasm_config_new();
533c51d3adSAlex Crichton   wasmtime_config_debug_info_set(config, true);
5496c905a6SAlex Crichton   wasmtime_config_cranelift_opt_level_set(config, WASMTIME_OPT_LEVEL_NONE);
553c51d3adSAlex Crichton 
563c51d3adSAlex Crichton   // Initialize.
573c51d3adSAlex Crichton   printf("Initializing...\n");
583c51d3adSAlex Crichton   wasm_engine_t *engine = wasm_engine_new_with_config(config);
597a1b7cdfSAlex Crichton   wasmtime_store_t *store = wasmtime_store_new(engine, NULL, NULL);
607a1b7cdfSAlex Crichton   wasmtime_context_t *context = wasmtime_store_context(store);
613c51d3adSAlex Crichton 
626a95189cSBen Jackson #ifdef WASMTIME_TEST_ONLY
636a95189cSBen Jackson   // NOTE: This validation is for wasmtime testing and should not be included in
646a95189cSBen Jackson   // your code.
656a95189cSBen Jackson   if (__jit_debug_descriptor.first_entry != NULL) {
666a95189cSBen Jackson     fprintf(stderr, "FAIL: JIT descriptor is already initialized\n");
676a95189cSBen Jackson     return 1;
686a95189cSBen Jackson   }
696a95189cSBen Jackson #endif
706a95189cSBen Jackson 
713c51d3adSAlex Crichton   // Load binary.
723c51d3adSAlex Crichton   printf("Loading binary...\n");
733c51d3adSAlex Crichton   FILE *file = fopen("target/wasm32-unknown-unknown/debug/fib.wasm", "rb");
743c51d3adSAlex Crichton   if (!file) {
753c51d3adSAlex Crichton     printf("> Error opening module!\n");
763c51d3adSAlex Crichton     return 1;
773c51d3adSAlex Crichton   }
783c51d3adSAlex Crichton   fseek(file, 0L, SEEK_END);
793c51d3adSAlex Crichton   size_t file_size = ftell(file);
803c51d3adSAlex Crichton   fseek(file, 0L, SEEK_SET);
813c51d3adSAlex Crichton   wasm_byte_vec_t binary;
823c51d3adSAlex Crichton   wasm_byte_vec_new_uninitialized(&binary, file_size);
833c51d3adSAlex Crichton   if (fread(binary.data, file_size, 1, file) != 1) {
843c51d3adSAlex Crichton     printf("> Error reading module!\n");
853c51d3adSAlex Crichton     return 1;
863c51d3adSAlex Crichton   }
873c51d3adSAlex Crichton   fclose(file);
883c51d3adSAlex Crichton 
893c51d3adSAlex Crichton   // Compile.
903c51d3adSAlex Crichton   printf("Compiling module...\n");
917a1b7cdfSAlex Crichton   wasmtime_module_t *module = NULL;
92f8fee938STyler Rockwood   wasmtime_error_t *error =
93f8fee938STyler Rockwood       wasmtime_module_new(engine, (uint8_t *)binary.data, binary.size, &module);
94bd374fd6SAlex Crichton   if (!module)
95bd374fd6SAlex Crichton     exit_with_error("failed to compile module", error, NULL);
963c51d3adSAlex Crichton   wasm_byte_vec_delete(&binary);
973c51d3adSAlex Crichton 
983c51d3adSAlex Crichton   // Instantiate.
993c51d3adSAlex Crichton   printf("Instantiating module...\n");
1007a1b7cdfSAlex Crichton   wasmtime_instance_t instance;
101bd374fd6SAlex Crichton   wasm_trap_t *trap = NULL;
1027a1b7cdfSAlex Crichton   error = wasmtime_instance_new(context, module, NULL, 0, &instance, &trap);
103bd374fd6SAlex Crichton   if (error != NULL || trap != NULL)
104bd374fd6SAlex Crichton     exit_with_error("failed to instantiate", error, trap);
1057a1b7cdfSAlex Crichton   wasmtime_module_delete(module);
1063c51d3adSAlex Crichton 
1076a95189cSBen Jackson #ifdef WASMTIME_TEST_ONLY
1086a95189cSBen Jackson   // NOTE: This validation is for wasmtime testing and should not be included in
1096a95189cSBen Jackson   // your code.
1106a95189cSBen Jackson   if (__jit_debug_descriptor.first_entry == NULL) {
1116a95189cSBen Jackson     fprintf(stderr, "FAIL: JIT descriptor is NOT initialized\n");
1126a95189cSBen Jackson     return 1;
1136a95189cSBen Jackson   }
1146a95189cSBen Jackson #endif
1156a95189cSBen Jackson 
1163c51d3adSAlex Crichton   // Extract export.
1177a1b7cdfSAlex Crichton   wasmtime_extern_t fib;
1187a1b7cdfSAlex Crichton   bool ok = wasmtime_instance_export_get(context, &instance, "fib", 3, &fib);
1197a1b7cdfSAlex Crichton   assert(ok);
1203c51d3adSAlex Crichton 
1213c51d3adSAlex Crichton   // Call.
1223c51d3adSAlex Crichton   printf("Calling fib...\n");
1237a1b7cdfSAlex Crichton   wasmtime_val_t params[1];
1247a1b7cdfSAlex Crichton   params[0].kind = WASMTIME_I32;
1257a1b7cdfSAlex Crichton   params[0].of.i32 = 6;
1267a1b7cdfSAlex Crichton   wasmtime_val_t results[1];
127f8fee938STyler Rockwood   error =
128f8fee938STyler Rockwood       wasmtime_func_call(context, &fib.of.func, params, 1, results, 1, &trap);
129bd374fd6SAlex Crichton   if (error != NULL || trap != NULL)
130bd374fd6SAlex Crichton     exit_with_error("failed to call function", error, trap);
1313c51d3adSAlex Crichton 
1327a1b7cdfSAlex Crichton   assert(results[0].kind == WASMTIME_I32);
1333c51d3adSAlex Crichton   printf("> fib(6) = %d\n", results[0].of.i32);
1343c51d3adSAlex Crichton 
1353c51d3adSAlex Crichton   // Shut down.
1363c51d3adSAlex Crichton   printf("Shutting down...\n");
1377a1b7cdfSAlex Crichton   wasmtime_store_delete(store);
1383c51d3adSAlex Crichton   wasm_engine_delete(engine);
1393c51d3adSAlex Crichton 
1403c51d3adSAlex Crichton   // All done.
1413c51d3adSAlex Crichton   printf("Done.\n");
1423c51d3adSAlex Crichton   return 0;
1433c51d3adSAlex Crichton }
1443c51d3adSAlex Crichton 
exit_with_error(const char * message,wasmtime_error_t * error,wasm_trap_t * trap)145f8fee938STyler Rockwood static void exit_with_error(const char *message, wasmtime_error_t *error,
146f8fee938STyler Rockwood                             wasm_trap_t *trap) {
147bd374fd6SAlex Crichton   fprintf(stderr, "error: %s\n", message);
148bd374fd6SAlex Crichton   wasm_byte_vec_t error_message;
149bd374fd6SAlex Crichton   if (error != NULL) {
150bd374fd6SAlex Crichton     wasmtime_error_message(error, &error_message);
151bd374fd6SAlex Crichton   } else {
152bd374fd6SAlex Crichton     wasm_trap_message(trap, &error_message);
153bd374fd6SAlex Crichton   }
154bd374fd6SAlex Crichton   fprintf(stderr, "%.*s\n", (int)error_message.size, error_message.data);
155bd374fd6SAlex Crichton   wasm_byte_vec_delete(&error_message);
156bd374fd6SAlex Crichton   exit(1);
157bd374fd6SAlex Crichton }
158