| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- /*
- * Copyright (c) 2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- */
- #include <rtthread.h>
- #include "wasm_export.h"
- #include "platform_api_vmcore.h"
- #include <dfs.h>
- #include <dfs_file.h>
- #include <dfs_fs.h>
- #include <dfs_posix.h>
- #ifdef WAMR_ENABLE_RTT_EXPORT
- #ifdef WAMR_RTT_EXPORT_VPRINTF
- static int wasm_vprintf(wasm_exec_env_t env, const char* fmt, va_list va)
- {
- return vprintf(fmt, va);
- }
- static int wasm_vsprintf(wasm_exec_env_t env, char* buf, const char* fmt, va_list va)
- {
- return vsprintf(buf, fmt, va);
- }
- static int wasm_vsnprintf(wasm_exec_env_t env, char *buf, int n, const char *fmt, va_list va)
- {
- return vsnprintf(buf, n, fmt, va);
- }
- #endif /* WAMR_RTT_EXPORT_VPRINTF */
- #ifdef WAMR_RTT_EXPORT_DEVICE_OPS
- static rt_device_t wasm_rt_device_find(wasm_exec_env_t env, const char *name)
- {
- return rt_device_find(name);
- }
- static rt_err_t wasm_rt_device_open(wasm_exec_env_t env, rt_device_t dev, rt_uint16_t o_flag)
- {
- return rt_device_open(dev , o_flag);
- }
- static rt_size_t wasm_rt_device_write(wasm_exec_env_t env, rt_device_t dev, rt_off_t offset, const void*buf, rt_size_t size)
- {
- return rt_device_write(dev, offset, buf, size);
- }
- static rt_size_t wasm_rt_device_read(wasm_exec_env_t env, rt_device_t dev, rt_off_t offset, void *buf, rt_size_t size)
- {
- return rt_device_read(dev, offset, buf, size);
- }
- static rt_err_t wasm_rt_device_close(wasm_exec_env_t env, rt_device_t dev)
- {
- return rt_device_close(dev);
- }
- static rt_err_t wasm_rt_device_control(wasm_exec_env_t env, rt_device_t dev, int cmd, void *arg)
- {
- return rt_device_control(dev, cmd, arg);
- }
- #endif /* WAMR_RTT_EXPORT_DEVICE_OPS */
- static NativeSymbol native_export_symbols[] = {
- #ifdef WAMR_RTT_EXPORT_VPRINTF
- {
- "vprintf",
- wasm_vprintf,
- "($*)i"
- },
- {
- "vsprintf",
- wasm_vsprintf,
- "($$*)i"
- },
- {
- "vsnprintf",
- wasm_vsnprintf,
- "($i$*)i"
- },
- #endif /* WAMR_RTT_EXPORT_VPRINTF */
- #ifdef WAMR_RTT_EXPORT_DEVICE_OPS
- {
- "rt_device_find",
- wasm_rt_device_find,
- "($)i"
- },
- {
- "rt_device_open",
- wasm_rt_device_open,
- "(ii)i"
- },
- {
- "rt_device_write",
- wasm_rt_device_write,
- "(ii*~)i"
- },
- {
- "rt_device_read",
- wasm_rt_device_read,
- "(ii*~)i"
- },
- {
- "rt_device_close",
- wasm_rt_device_close,
- "(i)i"
- },
- {
- "rt_device_control",
- wasm_rt_device_control,
- "(ii*)i"
- },
- #ifdef WAMR_RTT_EXPORT_DEVICE_OPS_CPP
- {
- "_Z15rt_device_closeP9rt_device",
- wasm_rt_device_close,
- "(i)i"
- },
- {
- "_Z14rt_device_readP9rt_devicejPvj",
- wasm_rt_device_read,
- "(ii*~)i"
- },
- {
- "_Z15rt_device_writeP9rt_devicejPKvj",
- wasm_rt_device_write,
- "(ii*~)i"
- },
- {
- "_Z14rt_device_openP9rt_devicet",
- wasm_rt_device_open,
- "(ii)i"
- },
- {
- "_Z14rt_device_findPKc",
- wasm_rt_device_find,
- "($)i"
- },
- #endif /* WAMR_RTT_EXPORT_DEVICE_OPS_CPP */
- #endif /* WAMR_RTT_EXPORT_DEVICE_OPS */
- };
- #endif /* WAMR_ENABLE_RTT_EXPORT */
- /**
- * run WASM module instance.
- * @param module_inst instance of wasm module
- * @param app_argc wasm argument count
- * @param app_argv wasm arguments
- * @return NULL
- */
- static void *
- app_instance_main(wasm_module_inst_t module_inst, int app_argc, char **app_argv)
- {
- const char *exception;
- wasm_application_execute_main(module_inst, app_argc, app_argv);
- if ((exception = wasm_runtime_get_exception(module_inst)))
- rt_kprintf("%s\n", exception);
- return NULL;
- }
- rt_uint8_t *my_read_file_to_buffer(char* filename, rt_uint32_t *size)
- {
- struct stat f_stat;
- dfs_file_stat(filename, &f_stat);
- struct dfs_fd fd;
- rt_uint8_t* buff = rt_malloc(f_stat.st_size);
- *size = 0;
- if (!buff)
- {
- rt_set_errno(-ENOMEM);
- return RT_NULL;
- }
- int ret = dfs_file_open(&fd, filename, O_RDONLY);
- if (ret)
- {
- rt_free(buff);
- rt_set_errno(ret);
- return RT_NULL;
- }
- *size = dfs_file_read(&fd, buff, f_stat.st_size);
- dfs_file_close(&fd);
- if (*size != f_stat.st_size)
- {
- rt_free(buff);
- rt_set_errno(-EBADF);
- return RT_NULL;
- }
- return buff;
- }
- void iwasm_help(void)
- {
- #ifdef WAMR_ENABLE_IWASM_PARAMS
- rt_kputs("wrong input: iwasm [-t] [-m] [-s] <*.wasm> <wasm_args ...>\n iwasm [-h]\n");
- rt_kputs("\t -h: show this tips.\n");
- rt_kputs("\t -t: show time taking to run this app.\n");
- rt_kputs("\t -m: show memory taking to run this app\n");
- rt_kputs("\t wasm file name and exec params must behind of all vm-param\n");
- #else
- rt_kputs("wrong input: iwasm <*.wasm> <wasm_args ...>\n");
- #endif /* WAMR_ENABLE_PARAMS */
- }
- int iwasm(int argc, char **argv)
- {
- rt_uint8_t *wasm_file_buf = NULL;
- rt_uint32_t wasm_file_size;
- rt_uint32_t stack_size = 4 * 1024, heap_size = 4 * 1024;
- wasm_module_t wasm_module = NULL;
- wasm_module_inst_t wasm_module_inst = NULL;
- RuntimeInitArgs init_args;
- static char error_buf[128] = { 0 };
- // avoid stack overflow
- #ifdef WAMR_ENABLE_IWASM_PARAMS
- int i_arg_begin;
- bool show_mem = false;
- bool show_stack = false;
- bool show_time_exec = false;
- for(i_arg_begin=1; i_arg_begin < argc; i_arg_begin++)
- {
- if (argv[i_arg_begin][0] != '-')
- {
- break;
- }
- if (argv[i_arg_begin][1] == 'm')
- {
- show_mem = true;
- }
- else if (argv[i_arg_begin][1] == 's')
- {
- show_stack = true;
- }
- else if (argv[i_arg_begin][1] == 't')
- {
- show_time_exec = true;
- }
- else if (argv[i_arg_begin][1] == 'h')
- {
- iwasm_help();
- return 0;
- }
- else if (argv[i_arg_begin][1] == 0x00)
- {
- continue;
- }
- else
- {
- rt_kprintf("[iwasm] unknown param: %s\n", argv[i_arg_begin]);
- }
- }
- #else /* WAMR_ENABLE_PARAMS */
- #define i_arg_begin 1
- #endif /* WAMR_ENABLE_PARAMS */
- if (argc - i_arg_begin < 1)
- {
- iwasm_help();
- return -1;
- }
- rt_memset(&init_args, 0, sizeof(RuntimeInitArgs));
- init_args.mem_alloc_type = Alloc_With_Allocator;
- init_args.mem_alloc_option.allocator.malloc_func = os_malloc;
- init_args.mem_alloc_option.allocator.realloc_func = os_realloc;
- init_args.mem_alloc_option.allocator.free_func = os_free;
- #ifdef WAMR_ENABLE_RTT_EXPORT
- init_args.native_symbols = native_export_symbols;
- init_args.n_native_symbols = sizeof(native_export_symbols) / sizeof(NativeSymbol);
- init_args.native_module_name = "env";
- #endif /* WAMR_ENABLE_RTT_EXPORT */
- #ifdef WAMR_ENABLE_IWASM_PARAMS
- #if defined(RT_USING_HEAP) && defined(RT_USING_MEMHEAP_AS_HEAP)
- extern long list_memheap(void);
- if (show_mem)
- {
- list_memheap();
- }
- #else
- rt_uint32_t total, max, used;
- if (show_mem)
- {
- rt_memory_info(&total, &used, &max);
- }
- #endif
- rt_thread_t tid;
- if (show_stack)
- {
- tid = rt_thread_self();
- printf("thread stack addr: %p, size: %u, sp: %p\n", tid->stack_addr, tid->stack_size, tid->sp);
- }
- #endif /* WAMR_ENABLE_PARAMS */
- if (wasm_runtime_full_init(&init_args) == false)
- {
- rt_kprintf("Init WASM runtime environment failed.\n");
- return -1;
- }
- wasm_file_buf = my_read_file_to_buffer (argv[i_arg_begin], &wasm_file_size);
- if (!wasm_file_buf)
- {
- rt_err_t err = rt_get_errno();
- rt_kprintf("WASM load file to RAM failed: %d\n", err);
- goto fail1;
- }
- rt_memset(error_buf, 0x00, sizeof(error_buf));
- wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf, sizeof(error_buf));
- if (!wasm_module)
- {
- rt_kprintf("%s\n", error_buf);
- goto fail2;
- }
- rt_memset(error_buf, 0x00, sizeof(error_buf));
- wasm_module_inst = wasm_runtime_instantiate(wasm_module, stack_size, heap_size, error_buf, sizeof(error_buf));
- if (!wasm_module_inst)
- {
- rt_kprintf("%s\n", error_buf);
- goto fail3;
- }
- #ifdef WAMR_ENABLE_IWASM_PARAMS
- rt_tick_t ticks_exec;
- if (show_time_exec) {
- ticks_exec = rt_tick_get();
- }
- #endif /* WAMR_ENABLE_PARAMS */
- app_instance_main(wasm_module_inst, argc - i_arg_begin, &argv[i_arg_begin]);
- #ifdef WAMR_ENABLE_IWASM_PARAMS
- if (show_time_exec)
- {
- ticks_exec = rt_tick_get() - ticks_exec;
- printf("[iwasm] execute ticks took: %u [ticks/s = %u]\n", ticks_exec, RT_TICK_PER_SECOND);
- }
- #if defined(RT_USING_HEAP) && defined(RT_USING_MEMHEAP_AS_HEAP)
- if (show_mem)
- {
- list_memheap();
- }
- #else
- rt_uint32_t total_after, max_after, used_after;
- if (show_mem)
- {
- rt_memory_info(&total_after, &used_after, &max_after);
- rt_kprintf("[iwasm] memory took: %u\n", used_after - used);
- }
- #endif
- if (show_stack)
- {
- printf("[iwasm] thread stack addr: %p, size: %u, sp: %p\n", tid->stack_addr, tid->stack_size, tid->sp);
- }
- #endif /* WAMR_ENABLE_PARAMS */
- /* destroy the module instance */
- wasm_runtime_deinstantiate(wasm_module_inst);
- fail3:
- /* unload the module */
- wasm_runtime_unload(wasm_module);
- fail2:
- /* free the file buffer */
- rt_free(wasm_file_buf);
- fail1:
- /* destroy runtime environment */
- wasm_runtime_destroy();
- return 0;
- }
- MSH_CMD_EXPORT(iwasm, Embeded VM of WebAssembly);
|