From 51c94a1217423ba365f48b80570de21ba6cd5a02 Mon Sep 17 00:00:00 2001 From: Karl Fessel Date: Fri, 21 Jan 2022 21:02:23 +0100 Subject: [PATCH] example/wasm: simplify example extend sample * uneventise example --- examples/wasm/Makefile | 17 ++-- examples/wasm/README.md | 2 +- examples/wasm/config.cmake | 3 + examples/wasm/iwasmt.c | 135 +++++++------------------ examples/wasm/{main.wasm => test.wasm} | Bin examples/wasm/wasm-main.c | 31 ++++-- examples/wasm/wasm_sample/Makefile | 18 ++-- examples/wasm/wasm_sample/hello.c | 14 ++- 8 files changed, 89 insertions(+), 131 deletions(-) rename examples/wasm/{main.wasm => test.wasm} (100%) diff --git a/examples/wasm/Makefile b/examples/wasm/Makefile index 66961b7e25..49ec5ba448 100644 --- a/examples/wasm/Makefile +++ b/examples/wasm/Makefile @@ -7,16 +7,13 @@ RIOTBASE ?= $(CURDIR)/../.. USEPKG += wamr -USEMODULE += xtimer -USEMODULE += sema -USEMODULE += event +ifneq ($(BOARD),native) +CFLAGS += -DTHREAD_STACKSIZE_MAIN='(6 * 1024)' +endif export WAMR_CONFIG := $(abspath config.cmake) -WPEDANTIC := 0 -WERROR := 0 - -BLOBS += main.wasm hello.wasm +BLOBS += test.wasm hello.wasm # Comment this out to disable code in RIOT that does safety checking # which is not needed in a production environment but helps in the @@ -26,6 +23,12 @@ DEVELHELP ?= 1 # Change this to 0 show compiler invocation lines by default: QUIET ?= 1 +all: hello.wasm + +hello.wasm: wasm_sample/hello.c + make -C wasm_sample hello.wasm + mv wasm_sample/hello.wasm . + ####################################################### # Load the rest of the usual RIOT make infrastructure # ####################################################### diff --git a/examples/wasm/README.md b/examples/wasm/README.md index 5cfa4dc633..c1e920c8cd 100644 --- a/examples/wasm/README.md +++ b/examples/wasm/README.md @@ -1,6 +1,6 @@ # building WASM -The source for main.wasm can be found in +The source for test.wasm can be found in /build/pkg/wamr/product-mini/app-samples/hello-world/ https://github.com/bytecodealliance/wasm-micro-runtime/tree/main/product-mini/app-samples/hello-world diff --git a/examples/wasm/config.cmake b/examples/wasm/config.cmake index 601794add0..900eb6a1c8 100644 --- a/examples/wasm/config.cmake +++ b/examples/wasm/config.cmake @@ -19,3 +19,6 @@ # set (WAMR_APP_THREAD_STACK_SIZE_MAX ${WAMR_APP_THREAD_STACK_SIZE_MAX}) #set maximum thread stack size # set (WAMR_BUILD_CUSTOM_NAME_SECTION 1) #enable Custom name section # set (WAMR_BUILD_TAIL_CALL 1) #enable Tail call + +# the builtin wamr libc is enabled by default +# set (WAMR_BUILD_LIBC_BUILTIN 0) #disable builtin libc diff --git a/examples/wasm/iwasmt.c b/examples/wasm/iwasmt.c index 4e8895a18b..cf4e08947b 100644 --- a/examples/wasm/iwasmt.c +++ b/examples/wasm/iwasmt.c @@ -4,26 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception */ -// -#include -#include -#include #include - +#include +#include +#include #include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstrict-prototypes" #include "wasm_export.h" -#pragma GCC diagnostic pop - -#include - - - -#define DEFAULT_THREAD_STACKSIZE (6 * 1024) -#define DEFAULT_THREAD_PRIORITY 50 - /* execs the main function in an instantiated module */ static int iwasm_instance_exec_main(wasm_module_inst_t module_inst, int argc, char **argv) @@ -32,16 +19,18 @@ static int iwasm_instance_exec_main(wasm_module_inst_t module_inst, int argc, ch const char *exception = 0; int ret = 0; wasm_application_execute_main(module_inst, argc, argv); - if ((exception = wasm_runtime_get_exception(module_inst))){ + if ((exception = wasm_runtime_get_exception(module_inst))) { puts(exception); return -1; } - if(argc > 0) ret = *((int*)argv); + if (argc > 0) { + ret = *((int*)argv); + } return ret; } /* execs the main function of a loaded module */ -int iwasm_module_exec_main(wasm_module_t wasm_module , int argc, char **argv) +int iwasm_module_exec_main(wasm_module_t wasm_module, int argc, char **argv) { wasm_module_inst_t wasm_module_inst = NULL; int ret = 0; @@ -61,14 +50,15 @@ int iwasm_module_exec_main(wasm_module_t wasm_module , int argc, char **argv) } /* bytecode needs to be writeable*/ -int iwasm_bytecode_exec_main(uint8_t * bytecode, size_t bytecode_len, int argc, char **argv){ +int iwasm_bytecode_exec_main(uint8_t *bytecode, size_t bytecode_len, int argc, char **argv) +{ int ret = 0; wasm_module_t wasm_module = NULL; { /* load WASM module */ char error_buf[128]; if (!(wasm_module = wasm_runtime_load(bytecode, bytecode_len, - error_buf, sizeof(error_buf)))) { + error_buf, sizeof(error_buf)))) { puts(error_buf); return -1; } @@ -85,7 +75,7 @@ bool iwasm_runtime_init(void) RuntimeInitArgs init_args; /* chose allocator non defaults to system allocator */ #define FUNC_ALLOC -//#define POOL_ALLOC +// #define POOL_ALLOC memset(&init_args, 0, sizeof(RuntimeInitArgs)); #ifdef POOL_ALLOC @@ -115,90 +105,28 @@ bool iwasm_runtime_init(void) return true; } -#include "event.h" -event_queue_t iwasm_q = EVENT_QUEUE_INIT_DETACHED; - -void * iwasm_thread(void *arg1) +void iwasm_runtime_destroy(void) { - (void) arg1; /*unused*/ - - if(!iwasm_runtime_init()) - return (void *)-1; - - event_queue_claim(&iwasm_q); - event_loop(&iwasm_q); - - /*next lines should not be reached*/ wasm_runtime_destroy(); - return NULL; -} - -bool iwasm_start_thread(void) -{ - struct{ - char * stack; - int stacksize; - uint8_t priority; - int flags; - thread_task_func_t task_func; - void * arg; - const char * name; - } b = { - .stacksize = DEFAULT_THREAD_STACKSIZE, - .priority = 8, - .flags = 0, - .task_func = iwasm_thread, - .arg = NULL, - .name = "simple_wamr" - }; - event_queue_init_detached(&iwasm_q); - b.stack=malloc(b.stacksize); - kernel_pid_t tpid = thread_create (b.stack, b.stacksize, b.priority, b.flags, b.task_func, b.arg, b.name); - - return tpid != 0 ? true : false;; -} - -#include "mutex.h" - -typedef struct run_bytecode_event { event_t super; - void *bytecode; - size_t bytecode_len; - int argc; - char **argv; - mutex_t finish; -} run_bytecode_event_t; - -void _wamr_run_call(event_t *event){ - run_bytecode_event_t * e = (run_bytecode_event_t *) event; - e->argc = iwasm_bytecode_exec_main((uint8_t * )e->bytecode, e->bytecode_len, e->argc, e->argv); - mutex_unlock(&e->finish); } /* this seems to be a very direct interpretation of "i like to have a wamr_run" */ -int wamr_run(void *bytecode, size_t bytecode_len, int argc, char **argv){ - run_bytecode_event_t * e = malloc(sizeof(run_bytecode_event_t)); - if (!e) return -1; - - *e = (run_bytecode_event_t){ .super.handler = _wamr_run_call, - .bytecode = bytecode, - .bytecode_len = bytecode_len, - .argc = argc, .argv = argv, - .finish = MUTEX_INIT_LOCKED}; - event_post(&iwasm_q, (event_t*) e); - - mutex_lock(&e->finish); - - int ret = e->argc; - free(e); - return ret; +int wamr_run(void *bytecode, size_t bytecode_len, int argc, char **argv) +{ + return iwasm_bytecode_exec_main((uint8_t *)bytecode, bytecode_len, argc, argv); } - -int wamr_run_cp(const void *bytecode, size_t bytecode_len, int argc, char *argv[]){ +/* this creates a copy of bytecode and argv + * if argc is 0 it is set to 1 and argv[0] is set to "" + * to create some space for a return value */ +int wamr_run_cp(const void *bytecode, size_t bytecode_len, int argc, char *argv[]) +{ /* we need the bytecode to be writable while loading * loading adds size information to stack POPs */ uint8_t * wasm_buf = malloc(bytecode_len); - if (!wasm_buf) return -1; + if (!wasm_buf) { + return -1; + } memcpy(wasm_buf, bytecode, bytecode_len); /* no copy need if architecture has const in writable mem */ @@ -206,17 +134,22 @@ int wamr_run_cp(const void *bytecode, size_t bytecode_len, int argc, char *argv[ unsigned wasm_buf_size = bytecode_len; - /* iwasm uses argv[0] casted to an int to store mains return value */ + /* iwasm uses argv[0] cast to an int to store mains return value */ static char * empty = ""; char ** parv; - if(argc > 0){ + if (argc > 0) { parv = malloc(sizeof(argv[0]) * argc); - if (!parv) return -1; + if (!parv){ + return -1; + } memcpy(parv, argv, sizeof(argv[0]) * argc); - }else{ + } + else { argc = 1; parv = malloc(sizeof(argv[0]) * argc); - if (!parv) return -1; + if (!parv) { + return -1; + } parv[0] = empty; } int ret = wamr_run(wasm_buf, wasm_buf_size, argc, parv); diff --git a/examples/wasm/main.wasm b/examples/wasm/test.wasm similarity index 100% rename from examples/wasm/main.wasm rename to examples/wasm/test.wasm diff --git a/examples/wasm/wasm-main.c b/examples/wasm/wasm-main.c index 45a5c7f344..37b9922872 100644 --- a/examples/wasm/wasm-main.c +++ b/examples/wasm/wasm-main.c @@ -1,16 +1,27 @@ +/* + * Copyright (C) 2020 TU Bergakademie Freiberg Karl Fessel + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + #include #include #include #include /*provide some test program*/ -#include "blob/main.wasm.h" +#include "blob/test.wasm.h" #include "blob/hello.wasm.h" -bool iwasm_start_thread(void); -/* this seems to be a very direct interpretation of "i like to have a wamr_run" */ +bool iwasm_runtime_init(void); +void iwasm_runtime_destroy(void); + +/* wamr_run is a very direct interpretation of "i like to have a wamr_run" */ int wamr_run(void *bytecode, size_t bytecode_len, int argc, char **argv); -/* this creates a copy bytecode and argv + +/* wamr_run_cp creates a copy bytecode and argv * if argc is 0 it is set to 1 and argv[0] is set to "" * to create some space for a return value */ int wamr_run_cp(const void *bytecode, size_t bytecode_len, int argc, const char **argv); @@ -19,13 +30,15 @@ int wamr_run_cp(const void *bytecode, size_t bytecode_len, int argc, const char int main(void) { - printf("iwasm_thread_initilised: %s\n", telltruth(iwasm_start_thread())); + printf("iwasm_initilised: %s\n", telltruth(iwasm_runtime_init())); - int app_argc = 0; - const char *app_argv1 = "test"; - const char **app_argv = 0; - int ret = wamr_run_cp(main_wasm, main_wasm_len, app_argc, app_argv); + int app_argc = 2; + const char *app_argv[] = {"test", "bob"}; + int ret = wamr_run_cp(test_wasm, test_wasm_len, app_argc, app_argv); printf("ret = %d\n", ret); ret = wamr_run_cp(hello_wasm, hello_wasm_len, app_argc, app_argv); printf("ret = %d\n", ret); + + iwasm_runtime_destroy(); + } diff --git a/examples/wasm/wasm_sample/Makefile b/examples/wasm/wasm_sample/Makefile index badc880096..15befee6bc 100644 --- a/examples/wasm/wasm_sample/Makefile +++ b/examples/wasm/wasm_sample/Makefile @@ -5,16 +5,16 @@ ifneq ($(shell (command -v wasm-ld)),) WASM-LD ?= wasm-ld else ifneq ($(shell (command -v wasm-ld-11)),) - LLVM_VERSION = 11 + LLVM_VERSION := 11 else ifneq ($(shell (command -v wasm-ld-10)),) - LLVM_VERSION = 10 + LLVM_VERSION := 10 else ifneq ($(shell (command -v wasm-ld-9)),) - LLVM_VERSION = 9 + LLVM_VERSION := 9 else ifneq ($(shell (command -v wasm-ld-8)),) - LLVM_VERSION = 8 + LLVM_VERSION := 8 endif endif endif @@ -30,9 +30,9 @@ else CLANGPP ?= clang++ endif -WASM-LD ?= echo !! NO wasm-ld(-VERSION) found !!; false +WASM-LD ?= echo "!! NO wasm-ld(-VERSION) found !!"; false -LINK_FLAGS = -z stack-size=4096 \ +LINK_FLAGS := -z stack-size=4096 \ --export main \ --export=__heap_base \ --export=__data_end \ @@ -49,14 +49,14 @@ LINK_FLAGS = -z stack-size=4096 \ # --initial-memory may only be set in 64kB steps (pagesize of WASM) # even though this one page is 64kB # - data starts at 0, (1024 is chosen by lld) -# - stack starts at 4kB down -# - heap at 4kB up (see stack-size option) +# - stack starts at 4kB growing down +# - heap at 4kB growing up (see stack-size option) # -> memory can be smaller than first page # without stack-size option stack will start at 64kB # -> heap needs a second page # wasm-ld 8 and 11 do not need --initial-memory=64kB -COMPILE_FLAGS = -Wall \ +COMPILE_FLAGS := -Wall \ --target=wasm32-unknown-unknown-wasm \ -emit-llvm \ -Os \ diff --git a/examples/wasm/wasm_sample/hello.c b/examples/wasm/wasm_sample/hello.c index f454ff86d9..7dba042af5 100644 --- a/examples/wasm/wasm_sample/hello.c +++ b/examples/wasm/wasm_sample/hello.c @@ -1,15 +1,21 @@ -/* a native printf is provided by the builtin libc of wamr */ +/* Copyright (C) World + * a native printf is provided by the builtin libc of wamr */ #ifdef __cplusplus -extern "C" int printf( const char * ,...); +extern "C" int printf( const char *, ...); #define WASM_EXPORT __attribute__((visibility("default"))) extern "C" #else -extern int printf( const char * ,...); +extern int printf( const char *, ...); #define WASM_EXPORT __attribute__((visibility("default"))) #endif WASM_EXPORT int main(int argc, char **argv) { - printf("Hello RIOT %i\n" , 2001); + if (argc > 1) { + printf("Hello %s %i\n", argv[1], 2001); + } + else { + printf("Hello %s %i\n", "RIOT", 2001); + } return 2468; }