32
32
#include <assert.h>
33
33
#include <stdio.h>
34
34
#include <stdlib.h>
35
+ #include <string.h>
35
36
36
37
#ifdef HAVE_DLOPEN
37
38
# include <dlfcn.h>
44
45
#endif
45
46
46
47
#if HAVE_DLOPEN && HAVE_WASMTIME
48
+ static void
49
+ libwasmtime_run_module (void * cookie , char * const argv [], wasm_engine_t * engine , wasm_byte_vec_t * wasm );
50
+
51
+ static void
52
+ libwasmtime_run_component (void * cookie , char * const argv [], wasm_engine_t * engine , wasm_byte_vec_t * wasm );
53
+
47
54
static int
48
55
libwasmtime_exec (void * cookie , libcrun_container_t * container arg_unused ,
49
56
const char * pathname , char * const argv [])
50
57
{
51
- size_t args_size = 0 ;
52
- char * const * arg ;
53
58
wasm_byte_vec_t error_message ;
54
59
wasm_byte_vec_t wasm_bytes ;
55
60
wasm_engine_t * (* wasm_engine_new ) ();
56
61
wasmtime_error_t * (* wasmtime_wat2wasm ) (const char * wat , size_t wat_len , wasm_byte_vec_t * out );
62
+ void (* wasm_byte_vec_new_uninitialized ) (wasm_byte_vec_t * , size_t );
63
+ wasmtime_error_t * (* wasmtime_module_validate ) (wasm_engine_t * engine , const uint8_t * wasm , size_t wasm_len );
64
+ void (* wasmtime_error_message ) (const wasmtime_error_t * error , wasm_name_t * message );
65
+ void (* wasmtime_error_delete ) (wasmtime_error_t * error );
66
+
67
+ wasmtime_wat2wasm = dlsym (cookie , "wasmtime_wat2wasm" );
68
+ wasm_engine_new = dlsym (cookie , "wasm_engine_new" );
69
+ wasm_byte_vec_new_uninitialized = dlsym (cookie , "wasm_byte_vec_new_uninitialized" );
70
+ wasmtime_module_validate = dlsym (cookie , "wasmtime_module_validate" );
71
+ wasmtime_error_delete = dlsym (cookie , "wasmtime_error_delete" );
72
+ wasmtime_error_message = dlsym (cookie , "wasmtime_error_message" );
73
+
74
+ if (wasmtime_wat2wasm == NULL
75
+ || wasm_engine_new == NULL
76
+ || wasm_byte_vec_new_uninitialized == NULL
77
+ || wasmtime_module_validate == NULL
78
+ || wasmtime_error_delete == NULL
79
+ || wasmtime_error_message == NULL )
80
+ error (EXIT_FAILURE , 0 , "could not find symbol in `libwasmtime.so`" );
81
+
82
+ // Set up wasmtime context
83
+ wasm_engine_t * engine = wasm_engine_new ();
84
+ assert (engine != NULL );
85
+
86
+ wasm_byte_vec_t wasm ;
87
+ // Load and parse container entrypoint
88
+ FILE * file = fopen (pathname , "rbe" );
89
+ if (! file )
90
+ error (EXIT_FAILURE , 0 , "error loading entrypoint" );
91
+ fseek (file , 0L , SEEK_END );
92
+ size_t file_size = ftell (file );
93
+ wasm_byte_vec_new_uninitialized (& wasm , file_size );
94
+ fseek (file , 0L , SEEK_SET );
95
+ if (fread (wasm .data , file_size , 1 , file ) != 1 )
96
+ error (EXIT_FAILURE , 0 , "error load" );
97
+ fclose (file );
98
+
99
+ // If entrypoint contains a webassembly text format
100
+ // compile it on the fly and convert to equivalent
101
+ // binary format.
102
+ if (has_suffix (pathname , "wat" ) > 0 )
103
+ {
104
+ wasmtime_error_t * err = wasmtime_wat2wasm ((char * ) & wasm_bytes , file_size , & wasm );
105
+ if (err != NULL )
106
+ {
107
+ wasmtime_error_message (err , & error_message );
108
+ wasmtime_error_delete (err );
109
+ error (EXIT_FAILURE , 0 , "failed while compiling wat to wasm binary : %.*s" , (int ) error_message .size , error_message .data );
110
+ }
111
+ wasm = wasm_bytes ;
112
+ }
113
+
114
+ // Check if it is a valid webassembly module or
115
+ // a component.
116
+ bool is_wasm_module = true;
117
+ wasmtime_error_t * err = wasmtime_module_validate (engine , (uint8_t * ) wasm .data , wasm .size );
118
+ if (err != NULL )
119
+ {
120
+ wasmtime_error_message (err , & error_message );
121
+ wasmtime_error_delete (err );
122
+
123
+ if (strcmp ((char * ) error_message .data , "component passed to module validation" ) != 0 )
124
+ {
125
+ error (EXIT_FAILURE , 0 , "failed to validate module: %.*s" , (int ) error_message .size , error_message .data );
126
+ }
127
+
128
+ err = NULL ;
129
+ is_wasm_module = false;
130
+ }
131
+
132
+ if (is_wasm_module )
133
+ {
134
+ libwasmtime_run_module (cookie , argv , engine , & wasm );
135
+ }
136
+ else
137
+ {
138
+ libwasmtime_run_component (cookie , argv , engine , & wasm );
139
+ }
140
+
141
+ exit (EXIT_SUCCESS );
142
+ }
143
+
144
+ static void
145
+ libwasmtime_run_module (void * cookie , char * const argv [], wasm_engine_t * engine , wasm_byte_vec_t * wasm )
146
+ {
147
+ size_t args_size = 0 ;
148
+ char * const * arg ;
149
+ wasm_byte_vec_t error_message ;
150
+
151
+ // Load needed functions
57
152
void (* wasm_engine_delete ) (wasm_engine_t * );
58
153
void (* wasm_byte_vec_delete ) (wasm_byte_vec_t * );
59
154
void (* wasm_byte_vec_new_uninitialized ) (wasm_byte_vec_t * , size_t );
@@ -100,8 +195,6 @@ libwasmtime_exec (void *cookie, libcrun_container_t *container arg_unused,
100
195
void (* wasmtime_error_delete ) (wasmtime_error_t * error );
101
196
bool (* wasi_config_preopen_dir ) (wasi_config_t * config , const char * path , const char * guest_path );
102
197
103
- wasmtime_wat2wasm = dlsym (cookie , "wasmtime_wat2wasm" );
104
- wasm_engine_new = dlsym (cookie , "wasm_engine_new" );
105
198
wasm_engine_delete = dlsym (cookie , "wasm_engine_delete" );
106
199
wasm_byte_vec_delete = dlsym (cookie , "wasm_byte_vec_delete" );
107
200
wasm_byte_vec_new_uninitialized = dlsym (cookie , "wasm_byte_vec_new_uninitialized" );
@@ -127,21 +220,18 @@ libwasmtime_exec (void *cookie, libcrun_container_t *container arg_unused,
127
220
wasmtime_error_message = dlsym (cookie , "wasmtime_error_message" );
128
221
wasi_config_preopen_dir = dlsym (cookie , "wasi_config_preopen_dir" );
129
222
130
- if (wasm_engine_new == NULL || wasm_engine_delete == NULL || wasm_byte_vec_delete == NULL
223
+ if (wasm_engine_delete == NULL || wasm_byte_vec_delete == NULL
131
224
|| wasm_byte_vec_new_uninitialized == NULL || wasi_config_new == NULL || wasmtime_store_new == NULL
132
225
|| wasmtime_store_context == NULL || wasmtime_linker_new == NULL || wasmtime_linker_define_wasi == NULL
133
226
|| wasmtime_module_new == NULL || wasi_config_inherit_argv == NULL || wasi_config_inherit_stdout == NULL
134
227
|| wasi_config_inherit_stdin == NULL || wasi_config_inherit_stderr == NULL
135
228
|| wasi_config_inherit_env == NULL || wasmtime_context_set_wasi == NULL
136
229
|| wasmtime_linker_module == NULL || wasmtime_linker_get_default == NULL || wasmtime_func_call == NULL
137
230
|| wasmtime_module_delete == NULL || wasmtime_store_delete == NULL || wasi_config_set_argv == NULL
138
- || wasmtime_error_delete == NULL || wasmtime_error_message == NULL || wasi_config_preopen_dir == NULL
139
- || wasmtime_wat2wasm == NULL )
231
+ || wasmtime_error_delete == NULL || wasmtime_error_message == NULL || wasi_config_preopen_dir == NULL )
140
232
error (EXIT_FAILURE , 0 , "could not find symbol in `libwasmtime.so`" );
141
233
142
234
// Set up wasmtime context
143
- wasm_engine_t * engine = wasm_engine_new ();
144
- assert (engine != NULL );
145
235
wasmtime_store_t * store = wasmtime_store_new (engine , NULL , NULL );
146
236
assert (store != NULL );
147
237
wasmtime_context_t * context = wasmtime_store_context (store );
@@ -156,44 +246,16 @@ libwasmtime_exec (void *cookie, libcrun_container_t *container arg_unused,
156
246
error (EXIT_FAILURE , 0 , "failed to link wasi: %.*s" , (int ) error_message .size , error_message .data );
157
247
}
158
248
159
- wasm_byte_vec_t wasm ;
160
- // Load and parse container entrypoint
161
- FILE * file = fopen (pathname , "rbe" );
162
- if (! file )
163
- error (EXIT_FAILURE , 0 , "error loading entrypoint" );
164
- fseek (file , 0L , SEEK_END );
165
- size_t file_size = ftell (file );
166
- wasm_byte_vec_new_uninitialized (& wasm , file_size );
167
- fseek (file , 0L , SEEK_SET );
168
- if (fread (wasm .data , file_size , 1 , file ) != 1 )
169
- error (EXIT_FAILURE , 0 , "error load" );
170
- fclose (file );
171
-
172
- // If entrypoint contains a webassembly text format
173
- // compile it on the fly and convert to equivalent
174
- // binary format.
175
- if (has_suffix (pathname , "wat" ) > 0 )
176
- {
177
- wasmtime_error_t * err = wasmtime_wat2wasm ((char * ) & wasm_bytes , file_size , & wasm );
178
- if (err != NULL )
179
- {
180
- wasmtime_error_message (err , & error_message );
181
- wasmtime_error_delete (err );
182
- error (EXIT_FAILURE , 0 , "failed while compiling wat to wasm binary : %.*s" , (int ) error_message .size , error_message .data );
183
- }
184
- wasm = wasm_bytes ;
185
- }
186
-
187
249
// Compile wasm modules
188
250
wasmtime_module_t * module = NULL ;
189
- err = wasmtime_module_new (engine , (uint8_t * ) wasm . data , wasm . size , & module );
251
+ err = wasmtime_module_new (engine , (uint8_t * ) wasm -> data , wasm -> size , & module );
190
252
if (! module )
191
253
{
192
254
wasmtime_error_message (err , & error_message );
193
255
wasmtime_error_delete (err );
194
256
error (EXIT_FAILURE , 0 , "failed to compile module: %.*s" , (int ) error_message .size , error_message .data );
195
257
}
196
- wasm_byte_vec_delete (& wasm );
258
+ wasm_byte_vec_delete (wasm );
197
259
198
260
// Init WASI program
199
261
wasi_config_t * wasi_config = wasi_config_new ("crun_wasi_program" );
@@ -249,8 +311,12 @@ libwasmtime_exec (void *cookie, libcrun_container_t *container arg_unused,
249
311
wasmtime_module_delete (module );
250
312
wasmtime_store_delete (store );
251
313
wasm_engine_delete (engine );
314
+ }
252
315
253
- exit (EXIT_SUCCESS );
316
+ static void
317
+ libwasmtime_run_component (void * cookie , char * const argv [], wasm_engine_t * engine , wasm_byte_vec_t * wasm )
318
+ {
319
+ error (EXIT_FAILURE , 0 , "running components is not yet implemented!" );
254
320
}
255
321
256
322
static int
0 commit comments