Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/examples/fib-debug/main.c
1691 views
1
#include <inttypes.h>
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5
#include <wasm.h>
6
#include <wasmtime.h>
7
8
#ifdef WASMTIME_TEST_ONLY
9
// These are the declarations provided from GDB documentation, used to validate
10
// that we actually added some DWARF info:
11
// https://sourceware.org/gdb/current/onlinedocs/gdb.html/Declarations.html#Declarations
12
//
13
// NOTE: These are not required in your code, rather they are used for wasmtime
14
// testing only.
15
typedef enum {
16
JIT_NOACTION = 0,
17
JIT_REGISTER_FN,
18
JIT_UNREGISTER_FN
19
} jit_actions_t;
20
21
struct jit_code_entry {
22
struct jit_code_entry *next_entry;
23
struct jit_code_entry *prev_entry;
24
const char *symfile_addr;
25
uint64_t symfile_size;
26
};
27
28
struct jit_descriptor {
29
uint32_t version;
30
/* This type should be jit_actions_t, but we use uint32_t
31
to be explicit about the bitwidth. */
32
uint32_t action_flag;
33
struct jit_code_entry *relevant_entry;
34
struct jit_code_entry *first_entry;
35
};
36
37
/*
38
* Import the descriptor, defined elsewhere in wasmtime
39
*/
40
extern struct jit_descriptor __jit_debug_descriptor;
41
#endif
42
43
#define own
44
45
static void exit_with_error(const char *message, wasmtime_error_t *error,
46
wasm_trap_t *trap);
47
48
int main(int argc, const char *argv[]) {
49
// Configuring engine to support generating of DWARF info.
50
// lldb can be used to attach to the program and observe
51
// original fib-wasm.c source code and variables.
52
wasm_config_t *config = wasm_config_new();
53
wasmtime_config_debug_info_set(config, true);
54
wasmtime_config_cranelift_opt_level_set(config, WASMTIME_OPT_LEVEL_NONE);
55
56
// Initialize.
57
printf("Initializing...\n");
58
wasm_engine_t *engine = wasm_engine_new_with_config(config);
59
wasmtime_store_t *store = wasmtime_store_new(engine, NULL, NULL);
60
wasmtime_context_t *context = wasmtime_store_context(store);
61
62
#ifdef WASMTIME_TEST_ONLY
63
// NOTE: This validation is for wasmtime testing and should not be included in
64
// your code.
65
if (__jit_debug_descriptor.first_entry != NULL) {
66
fprintf(stderr, "FAIL: JIT descriptor is already initialized\n");
67
return 1;
68
}
69
#endif
70
71
// Load binary.
72
printf("Loading binary...\n");
73
FILE *file = fopen("target/wasm32-unknown-unknown/debug/fib.wasm", "rb");
74
if (!file) {
75
printf("> Error opening module!\n");
76
return 1;
77
}
78
fseek(file, 0L, SEEK_END);
79
size_t file_size = ftell(file);
80
fseek(file, 0L, SEEK_SET);
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 reading module!\n");
85
return 1;
86
}
87
fclose(file);
88
89
// Compile.
90
printf("Compiling module...\n");
91
wasmtime_module_t *module = NULL;
92
wasmtime_error_t *error =
93
wasmtime_module_new(engine, (uint8_t *)binary.data, binary.size, &module);
94
if (!module)
95
exit_with_error("failed to compile module", error, NULL);
96
wasm_byte_vec_delete(&binary);
97
98
// Instantiate.
99
printf("Instantiating module...\n");
100
wasmtime_instance_t instance;
101
wasm_trap_t *trap = NULL;
102
error = wasmtime_instance_new(context, module, NULL, 0, &instance, &trap);
103
if (error != NULL || trap != NULL)
104
exit_with_error("failed to instantiate", error, trap);
105
wasmtime_module_delete(module);
106
107
#ifdef WASMTIME_TEST_ONLY
108
// NOTE: This validation is for wasmtime testing and should not be included in
109
// your code.
110
if (__jit_debug_descriptor.first_entry == NULL) {
111
fprintf(stderr, "FAIL: JIT descriptor is NOT initialized\n");
112
return 1;
113
}
114
#endif
115
116
// Extract export.
117
wasmtime_extern_t fib;
118
bool ok = wasmtime_instance_export_get(context, &instance, "fib", 3, &fib);
119
assert(ok);
120
121
// Call.
122
printf("Calling fib...\n");
123
wasmtime_val_t params[1];
124
params[0].kind = WASMTIME_I32;
125
params[0].of.i32 = 6;
126
wasmtime_val_t results[1];
127
error =
128
wasmtime_func_call(context, &fib.of.func, params, 1, results, 1, &trap);
129
if (error != NULL || trap != NULL)
130
exit_with_error("failed to call function", error, trap);
131
132
assert(results[0].kind == WASMTIME_I32);
133
printf("> fib(6) = %d\n", results[0].of.i32);
134
135
// Shut down.
136
printf("Shutting down...\n");
137
wasmtime_store_delete(store);
138
wasm_engine_delete(engine);
139
140
// All done.
141
printf("Done.\n");
142
return 0;
143
}
144
145
static void exit_with_error(const char *message, wasmtime_error_t *error,
146
wasm_trap_t *trap) {
147
fprintf(stderr, "error: %s\n", message);
148
wasm_byte_vec_t error_message;
149
if (error != NULL) {
150
wasmtime_error_message(error, &error_message);
151
} else {
152
wasm_trap_message(trap, &error_message);
153
}
154
fprintf(stderr, "%.*s\n", (int)error_message.size, error_message.data);
155
wasm_byte_vec_delete(&error_message);
156
exit(1);
157
}
158
159