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