1
- /*
2
- * Copyright (C) 2019 Intel Corporation. All rights reserved.
3
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
- */
5
-
6
- #ifndef _GNU_SOURCE
7
- #define _GNU_SOURCE
8
- #endif
9
- #include <stdlib.h>
10
- #include <string.h>
11
- #include "bh_platform.h"
12
- #include "bh_assert.h"
13
- #include "bh_log.h"
14
- #include "bh_read_file.h"
15
- #include "wasm_export.h"
16
-
17
- static int app_argc ;
18
- static char * * app_argv ;
19
-
20
- static int print_help ()
21
- {
22
- printf ("Usage: iwasm [-options] wasm_file [args...]\n" );
23
- printf ("options:\n" );
24
- printf (" -f|--function name Specify function name to run in module\n"
25
- " rather than main\n" );
26
- #if WASM_ENABLE_LOG != 0
27
- printf (" -v=n Set log verbose level (0 to 5, default is 2),\n"
28
- " larger level with more log\n" );
29
- #endif
30
- printf (" --stack-size=n Set maximum stack size in bytes, default is 16 KB\n" );
31
- printf (" --heap-size=n Set maximum heap size in bytes, default is 16 KB\n" );
32
- printf (" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
33
- " that runs commands in the form of `FUNC ARG...`\n" );
34
- #if WASM_ENABLE_LIBC_WASI != 0
35
- printf (" --env=<env> Pass wasi environment variables with \"key=value\"\n" );
36
- printf (" to the program, for example:\n" );
37
- printf (" --env=\"key1=value1\" --env=\"key2=value2\"\n" );
38
- printf (" --dir=<dir> Grant wasi access to the given host directories\n" );
39
- printf (" to the program, for example:\n" );
40
- printf (" --dir=<dir1> --dir=<dir2>\n" );
41
- #endif
42
-
43
- return 1 ;
44
- }
45
-
46
- static void *
47
- app_instance_main (wasm_module_inst_t module_inst )
48
- {
49
- const char * exception ;
50
-
51
- wasm_application_execute_main (module_inst , app_argc , app_argv );
52
- if ((exception = wasm_runtime_get_exception (module_inst )))
53
- printf ("%s\n" , exception );
54
- return NULL ;
55
- }
56
-
57
- static void *
58
- app_instance_func (wasm_module_inst_t module_inst , const char * func_name )
59
- {
60
- wasm_application_execute_func (module_inst , func_name , app_argc - 1 ,
61
- app_argv + 1 );
62
- /* The result of wasm function or exception info was output inside
63
- wasm_application_execute_func(), here we don't output them again. */
64
- return NULL ;
65
- }
66
-
67
- /**
68
- * Split a space separated strings into an array of strings
69
- * Returns NULL on failure
70
- * Memory must be freed by caller
71
- * Based on: http://stackoverflow.com/a/11198630/471795
72
- */
73
- static char * *
74
- split_string (char * str , int * count )
75
- {
76
- char * * res = NULL ;
77
- char * p ;
78
- int idx = 0 ;
79
-
80
- /* split string and append tokens to 'res' */
81
- do {
82
- p = strtok (str , " " );
83
- str = NULL ;
84
- res = (char * * ) realloc (res , sizeof (char * ) * (uint32 )(idx + 1 ));
85
- if (res == NULL ) {
86
- return NULL ;
87
- }
88
- res [idx ++ ] = p ;
89
- } while (p );
90
-
91
- if (count ) {
92
- * count = idx - 1 ;
93
- }
94
- return res ;
95
- }
96
-
97
- static void *
98
- app_instance_repl (wasm_module_inst_t module_inst )
99
- {
100
- char * cmd = NULL ;
101
- size_t len = 0 ;
102
- ssize_t n ;
103
-
104
- while ((printf ("webassembly> " ), n = getline (& cmd , & len , stdin )) != -1 ) {
105
- bh_assert (n > 0 );
106
- if (cmd [n - 1 ] == '\n' ) {
107
- if (n == 1 )
108
- continue ;
109
- else
110
- cmd [n - 1 ] = '\0' ;
111
- }
112
- app_argv = split_string (cmd , & app_argc );
113
- if (app_argv == NULL ) {
114
- LOG_ERROR ("Wasm prepare param failed: split string failed.\n" );
115
- break ;
116
- }
117
- if (app_argc != 0 ) {
118
- wasm_application_execute_func (module_inst , app_argv [0 ],
119
- app_argc - 1 , app_argv + 1 );
120
- }
121
- free (app_argv );
122
- }
123
- free (cmd );
124
- return NULL ;
125
- }
126
-
127
- #if WASM_ENABLE_LIBC_WASI != 0
128
- static bool
129
- validate_env_str (char * env )
130
- {
131
- char * p = env ;
132
- int key_len = 0 ;
133
-
134
- while (* p != '\0' && * p != '=' ) {
135
- key_len ++ ;
136
- p ++ ;
137
- }
138
-
139
- if (* p != '=' || key_len == 0 )
140
- return false;
141
-
142
- return true;
143
- }
144
- #endif
145
-
146
- #define USE_GLOBAL_HEAP_BUF 0
147
-
148
- #if USE_GLOBAL_HEAP_BUF != 0
149
- static char global_heap_buf [10 * 1024 * 1024 ] = { 0 };
150
- #endif
151
-
152
- int main (int argc , char * argv [])
153
- {
154
- char * wasm_file = NULL ;
155
- const char * func_name = NULL ;
156
- uint8 * wasm_file_buf = NULL ;
157
- uint32 wasm_file_size ;
158
- uint32 stack_size = 16 * 1024 , heap_size = 16 * 1024 ;
159
- wasm_module_t wasm_module = NULL ;
160
- wasm_module_inst_t wasm_module_inst = NULL ;
161
- RuntimeInitArgs init_args ;
162
- char error_buf [128 ] = { 0 };
163
- #if WASM_ENABLE_LOG != 0
164
- int log_verbose_level = 2 ;
165
- #endif
166
- bool is_repl_mode = false;
167
- #if WASM_ENABLE_LIBC_WASI != 0
168
- const char * dir_list [8 ] = { NULL };
169
- uint32 dir_list_size = 0 ;
170
- const char * env_list [8 ] = { NULL };
171
- uint32 env_list_size = 0 ;
172
- #endif
173
-
174
- /* Process options. */
175
- for (argc -- , argv ++ ; argc > 0 && argv [0 ][0 ] == '-' ; argc -- , argv ++ ) {
176
- if (!strcmp (argv [0 ], "-f" ) || !strcmp (argv [0 ], "--function" )) {
177
- argc -- , argv ++ ;
178
- if (argc < 2 ) {
179
- print_help ();
180
- return 0 ;
181
- }
182
- func_name = argv [0 ];
183
- }
184
- #if WASM_ENABLE_LOG != 0
185
- else if (!strncmp (argv [0 ], "- v = ", 3 )) {
186
- log_verbose_level = atoi (argv [0 ] + 3 );
187
- if (log_verbose_level < 0 || log_verbose_level > 5 )
188
- return print_help ();
189
- }
190
- #endif
191
- else if (!strcmp (argv [0 ], "-- repl "))
192
- is_repl_mode = true;
193
- else if (!strncmp (argv [0 ], "--stack-size=" , 13 )) {
194
- if (argv [0 ][13 ] == '\0' )
195
- return print_help ();
196
- stack_size = atoi (argv [0 ] + 13 );
197
- }
198
- else if (!strncmp (argv [0 ], "--heap-size=" , 12 )) {
199
- if (argv [0 ][12 ] == '\0' )
200
- return print_help ();
201
- heap_size = atoi (argv [0 ] + 12 );
202
- }
203
- #if WASM_ENABLE_LIBC_WASI != 0
204
- else if (!strncmp (argv [0 ], "-- dir = ", 6 )) {
205
- if (argv [0 ][6 ] == '\0' )
206
- return print_help ();
207
- if (dir_list_size >= sizeof (dir_list ) / sizeof (char * )) {
208
- printf ("Only allow max dir number %d\n" ,
209
- (int )(sizeof (dir_list ) / sizeof (char * )));
210
- return -1 ;
211
- }
212
- dir_list [dir_list_size ++ ] = argv [0 ] + 6 ;
213
- }
214
- else if (!strncmp (argv [0 ], "-- env = ", 6 )) {
215
- char * tmp_env ;
216
-
217
- if (argv [0 ][6 ] == '\0' )
218
- return print_help ();
219
- if (env_list_size >= sizeof (env_list ) / sizeof (char * )) {
220
- printf ("Only allow max env number %d\n" ,
221
- (int )(sizeof (env_list ) / sizeof (char * )));
222
- return -1 ;
223
- }
224
- tmp_env = argv [0 ] + 6 ;
225
- if (validate_env_str (tmp_env ))
226
- env_list [env_list_size ++ ] = tmp_env ;
227
- else {
228
- printf ("Wasm parse env string failed: expect \"key=value\", got \"%s\"\n" ,
229
- tmp_env );
230
- return print_help ();
231
- }
232
- }
233
- #endif
234
- else
235
- return print_help ();
236
- }
237
-
238
- if (argc == 0 )
239
- return print_help ();
240
-
241
- wasm_file = argv [0 ];
242
- app_argc = argc ;
243
- app_argv = argv ;
244
-
245
- memset (& init_args , 0 , sizeof (RuntimeInitArgs ));
246
-
247
- #if USE_GLOBAL_HEAP_BUF != 0
248
- init_args .mem_alloc_type = Alloc_With_Pool ;
249
- init_args .mem_alloc_option .pool .heap_buf = global_heap_buf ;
250
- init_args .mem_alloc_option .pool .heap_size = sizeof (global_heap_buf );
251
- #else
252
- init_args .mem_alloc_type = Alloc_With_Allocator ;
253
- init_args .mem_alloc_option .allocator .malloc_func = malloc ;
254
- init_args .mem_alloc_option .allocator .realloc_func = realloc ;
255
- init_args .mem_alloc_option .allocator .free_func = free ;
256
- #endif
257
-
258
- /* initialize runtime environment */
259
- if (!wasm_runtime_full_init (& init_args )) {
260
- printf ("Init runtime environment failed.\n" );
261
- return -1 ;
262
- }
263
-
264
- bh_log_set_verbose_level (log_verbose_level );
265
-
266
- /* load WASM byte buffer from WASM bin file */
267
- if (!(wasm_file_buf = (uint8 * ) bh_read_file_to_buffer (wasm_file ,
268
- & wasm_file_size )))
269
- goto fail1 ;
270
-
271
- /* load WASM module */
272
- if (!(wasm_module = wasm_runtime_load (wasm_file_buf , wasm_file_size ,
273
- error_buf , sizeof (error_buf )))) {
274
- printf ("%s\n" , error_buf );
275
- goto fail2 ;
276
- }
277
-
278
- #if WASM_ENABLE_LIBC_WASI != 0
279
- wasm_runtime_set_wasi_args (wasm_module ,
280
- dir_list , dir_list_size ,
281
- NULL , 0 ,
282
- env_list , env_list_size ,
283
- argv , argc );
284
- #endif
285
-
286
- /* instantiate the module */
287
- if (!(wasm_module_inst = wasm_runtime_instantiate (wasm_module ,
288
- stack_size ,
289
- heap_size ,
290
- error_buf ,
291
- sizeof (error_buf )))) {
292
- printf ("%s\n" , error_buf );
293
- goto fail3 ;
294
- }
295
-
296
- if (is_repl_mode )
297
- app_instance_repl (wasm_module_inst );
298
- else if (func_name )
299
- app_instance_func (wasm_module_inst , func_name );
300
- else
301
- app_instance_main (wasm_module_inst );
302
-
303
- /* destroy the module instance */
304
- wasm_runtime_deinstantiate (wasm_module_inst );
305
-
306
- fail3 :
307
- /* unload the module */
308
- wasm_runtime_unload (wasm_module );
309
-
310
- fail2 :
311
- /* free the file buffer */
312
- wasm_runtime_free (wasm_file_buf );
313
-
314
- fail1 :
315
- /* destroy runtime environment */
316
- wasm_runtime_destroy ();
317
- return 0 ;
318
- }
319
-
1
+ #include "../posix/main.c"
0 commit comments