This repository has been archived on 2023-11-05. You can view files and clone it, but cannot push or open issues or pull requests.
wasm-micro-runtime/product-mini/platforms/linux/main.c
wenyongh 46b93b9d22 Enable AoT and wamr-sdk, and change arguments of call wasm API (#157)
* Implement memory profiler, optimize memory usage, modify code indent

* Implement memory.grow and limit heap space base offset to 1G; modify iwasm build type to Release and 64 bit by default

* Add a new extension library: connection

* Fix bug of reading magic number and version in big endian platform

* Re-org platform APIs: move most platform APIs from iwasm to shared-lib

* Enhance wasm loader to fix some security issues

* Fix issue about illegal load of EXC_RETURN into PC on stm32 board

* Updates that let a restricted version of the interpreter run in SGX

* Enable native/app address validation and conversion for wasm app

* Remove wasm_application_exectue_* APIs from wasm_export.h which makes confused

* Refine binary size and fix several minor issues

Optimize interpreter LOAD/STORE opcodes to decrease the binary size
Fix issues when using iwasm library: _bh_log undefined, bh_memory.h not found
Remove unused _stdin/_stdout/_stderr global variables resolve in libc wrapper
Add macros of global heap size, stack size, heap size for Zephyr main.c
Clear compile warning of wasm_application.c

* Add more strict security checks for libc wrapper API's

* Use one libc wrapper copy for sgx and other platforms; remove bh_printf macro for other platform header files

* Enhance security of libc strcpy/sprintf wrapper function

* Fix issue of call native for x86_64/arm/mips, add module inst parameter for native wrapper functions

* Remove get_module_inst() and fix issue of call native

* Refine wgl lib: remove module_inst parameter from widget functions; move function index check to runtime instantiate

* Refine interpreter call native process, refine memory boudary check

* Fix issues of invokeNative function of arm/mips/general version

* Add a switch to build simple sample without gui support

* Add BUILD_TARGET setting in makefile to replace cpu compiler flags in source code

* Re-org shared lib header files, remove unused info; fix compile issues of vxworks

* Add build target general

* Remove unused files

* Update license header

* test push

* Restore file

* Sync up with internal/feature

* Sync up with internal/feature

* Rename build_wamr_app to build_wasm_app

* Fix small issues of README

* Enhance malformed wasm file checking
Fix issue of print hex int and implement utf8 string check
Fix wasi file read/write right issue
Fix minor issue of build wasm app doc

* Sync up with internal/feature

* Sync up with internal/feature: fix interpreter arm issue, fix read leb issue

* Sync up with internal/feature

* Fix bug of config.h and rename wasi config.h to ssp_config.h

* Sync up with internal/feature

* Import wamr aot

* update document

* update document

* Update document, disable WASI in 32bit

* update document

* remove files

* update document

* Update document

* update document

* update document

* update samples

* Sync up with internal repo
2020-01-21 13:26:14 +08:00

307 lines
8.7 KiB
C

/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdlib.h>
#include <string.h>
#include "bh_platform.h"
#include "bh_assert.h"
#include "bh_log.h"
#include "bh_memory.h"
#include "wasm_export.h"
static int app_argc;
static char **app_argv;
static int print_help()
{
bh_printf("Usage: iwasm [-options] wasm_file [args...]\n");
bh_printf("options:\n");
bh_printf(" -f|--function name Specify function name to run in module\n"
" rather than main\n");
#if WASM_ENABLE_LOG != 0
bh_printf(" -v=X Set log verbose level (0 to 5, default is 2),\n"
" larger level with more log\n");
#endif
bh_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
" that runs commands in the form of `FUNC ARG...`\n");
#if WASM_ENABLE_LIBC_WASI != 0
bh_printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n");
bh_printf(" to the program, for example:\n");
bh_printf(" --env=\"key1=value1\" --env=\"key2=value2\"\n");
bh_printf(" --dir=<dir> Grant wasi access to the given host directories\n");
bh_printf(" to the program, for example:\n");
bh_printf(" --dir=<dir1> --dir=<dir2>\n");
#endif
return 1;
}
static void*
app_instance_main(wasm_module_inst_t module_inst)
{
const char *exception;
wasm_application_execute_main(module_inst, app_argc, app_argv);
if ((exception = wasm_runtime_get_exception(module_inst)))
bh_printf("%s\n", exception);
return NULL;
}
static void*
app_instance_func(wasm_module_inst_t module_inst, const char *func_name)
{
wasm_application_execute_func(module_inst, func_name, app_argc - 1,
app_argv + 1);
/* The result of wasm function or exception info was output inside
wasm_application_execute_func(), here we don't output them again. */
return NULL;
}
/**
* Split a space separated strings into an array of strings
* Returns NULL on failure
* Memory must be freed by caller
* Based on: http://stackoverflow.com/a/11198630/471795
*/
static char **
split_string(char *str, int *count)
{
char **res = NULL;
char *p;
int idx = 0;
/* split string and append tokens to 'res' */
do {
p = strtok(str, " ");
str = NULL;
res = (char**) realloc(res, sizeof(char*) * (uint32)(idx + 1));
if (res == NULL) {
return NULL;
}
res[idx++] = p;
} while (p);
if (count) {
*count = idx - 1;
}
return res;
}
static void*
app_instance_repl(wasm_module_inst_t module_inst)
{
char *cmd = NULL;
size_t len = 0;
ssize_t n;
while ((bh_printf("webassembly> "), n = getline(&cmd, &len, stdin)) != -1) {
bh_assert(n > 0);
if (cmd[n - 1] == '\n') {
if (n == 1)
continue;
else
cmd[n - 1] = '\0';
}
app_argv = split_string(cmd, &app_argc);
if (app_argv == NULL) {
LOG_ERROR("Wasm prepare param failed: split string failed.\n");
break;
}
if (app_argc != 0) {
wasm_application_execute_func(module_inst, app_argv[0],
app_argc - 1, app_argv + 1);
}
free(app_argv);
}
free(cmd);
return NULL;
}
#if WASM_ENABLE_LIBC_WASI != 0
static bool
validate_env_str(char *env)
{
char *p = env;
int key_len = 0;
while (*p != '\0' && *p != '=') {
key_len++;
p++;
}
if (*p != '=' || key_len == 0)
return false;
return true;
}
#endif
#define USE_GLOBAL_HEAP_BUF 0
#if USE_GLOBAL_HEAP_BUF != 0
static char global_heap_buf[10 * 1024 * 1024] = { 0 };
#endif
int main(int argc, char *argv[])
{
char *wasm_file = NULL;
const char *func_name = NULL;
uint8 *wasm_file_buf = NULL;
uint32 wasm_file_size;
wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL;
char error_buf[128] = { 0 };
#if WASM_ENABLE_LOG != 0
int log_verbose_level = 2;
#endif
bool is_repl_mode = false;
#if WASM_ENABLE_LIBC_WASI != 0
const char *dir_list[8] = { NULL };
uint32 dir_list_size = 0;
const char *env_list[8] = { NULL };
uint32 env_list_size = 0;
#endif
/* Process options. */
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) {
argc--, argv++;
if (argc < 2) {
print_help();
return 0;
}
func_name = argv[0];
}
#if WASM_ENABLE_LOG != 0
else if (!strncmp(argv[0], "-v=", 3)) {
log_verbose_level = atoi(argv[0] + 3);
if (log_verbose_level < 0 || log_verbose_level > 5)
return print_help();
}
#endif
else if (!strcmp(argv[0], "--repl"))
is_repl_mode = true;
#if WASM_ENABLE_LIBC_WASI != 0
else if (!strncmp(argv[0], "--dir=", 6)) {
if (argv[0][6] == '\0')
return print_help();
if (dir_list_size >= sizeof(dir_list) / sizeof(char*)) {
bh_printf("Only allow max dir number %d\n",
(int)(sizeof(dir_list) / sizeof(char*)));
return -1;
}
dir_list[dir_list_size++] = argv[0] + 6;
}
else if (!strncmp(argv[0], "--env=", 6)) {
char *tmp_env;
if (argv[0][6] == '\0')
return print_help();
if (env_list_size >= sizeof(env_list) / sizeof(char*)) {
bh_printf("Only allow max env number %d\n",
(int)(sizeof(env_list) / sizeof(char*)));
return -1;
}
tmp_env = argv[0] + 6;
if (validate_env_str(tmp_env))
env_list[env_list_size++] = tmp_env;
else {
bh_printf("Wasm parse env string failed: expect \"key=value\", got \"%s\"\n",
tmp_env);
return print_help();
}
}
#endif
else
return print_help();
}
if (argc == 0)
return print_help();
wasm_file = argv[0];
app_argc = argc;
app_argv = argv;
#if USE_GLOBAL_HEAP_BUF != 0
if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf))
!= 0) {
bh_printf("Init memory with global heap buffer failed.\n");
return -1;
}
#else
if (bh_memory_init_with_allocator(malloc, free)) {
bh_printf("Init memory with memory allocator failed.\n");
return -1;
}
#endif
/* initialize runtime environment */
if (!wasm_runtime_init())
goto fail1;
bh_log_set_verbose_level(log_verbose_level);
/* load WASM byte buffer from WASM bin file */
if (!(wasm_file_buf = (uint8*) bh_read_file_to_buffer(wasm_file,
&wasm_file_size)))
goto fail2;
/* load WASM module */
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
error_buf, sizeof(error_buf)))) {
bh_printf("%s\n", error_buf);
goto fail3;
}
#if WASM_ENABLE_LIBC_WASI != 0
wasm_runtime_set_wasi_args(wasm_module,
dir_list, dir_list_size,
NULL, 0,
env_list, env_list_size,
argv, argc);
#endif
/* instantiate the module */
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
64 * 1024, /* stack size */
64 * 1024, /* heap size */
error_buf,
sizeof(error_buf)))) {
bh_printf("%s\n", error_buf);
goto fail4;
}
if (is_repl_mode)
app_instance_repl(wasm_module_inst);
else if (func_name)
app_instance_func(wasm_module_inst, func_name);
else
app_instance_main(wasm_module_inst);
/* destroy the module instance */
wasm_runtime_deinstantiate(wasm_module_inst);
fail4:
/* unload the module */
wasm_runtime_unload(wasm_module);
fail3:
/* free the file buffer */
bh_free(wasm_file_buf);
fail2:
/* destroy runtime environment */
wasm_runtime_destroy();
fail1:
bh_memory_destroy();
return 0;
}