1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #15329 from kfessel/p-add-wamr

pkg/wamr: add WAMR to provide WASM support in RIOT
This commit is contained in:
Marian Buschsieweke 2022-03-02 19:58:31 +01:00 committed by GitHub
commit a5b91362cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 713 additions and 0 deletions

36
examples/wasm/Makefile Normal file
View File

@ -0,0 +1,36 @@
APPLICATION = wasm-example
# If no BOARD is defined in the environment, use this default:
BOARD ?= native
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..
USEPKG += wamr
ifneq ($(BOARD),native)
CFLAGS += -DTHREAD_STACKSIZE_MAIN='(6 * 1024)'
endif
export WAMR_CONFIG := $(abspath config.cmake)
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
# development process:
DEVELHELP ?= 1
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1
all: hello.wasm
hello.wasm: wasm_sample/hello.c wasm_sample/Makefile
make -C wasm_sample hello.wasm
mv wasm_sample/hello.wasm .
#######################################################
# Load the rest of the usual RIOT make infrastructure #
#######################################################
include $(RIOTBASE)/Makefile.include

37
examples/wasm/Makefile.ci Normal file
View File

@ -0,0 +1,37 @@
BOARD_INSUFFICIENT_MEMORY64K :=\
blackpill \
bluepill \
bluepill-stm32f030c8 \
i-nucleo-lrwan1 \
nucleo-f030r8 \
nucleo-f302r8 \
nucleo-f303k8 \
nucleo-f334r8 \
nucleo-l053r8 \
stm32f0discovery \
stm32l0538-disco\
stm32mp157c-dk2 \
#
BOARD_INSUFFICIENT_MEMORY32K :=\
nucleo-f031k6 \
nucleo-f042k6 \
nucleo-l031k6 \
stm32g0316-disco \
#
BOARD_INSUFFICIENT_MEMORY16K :=\
nucleo-l011k4 \
stm32f030f4-demo \
#
BOARD_INSUFFICIENT_MEMORY := \
slstk3400a \
stk3200 \
samd10-xmini \
saml10-xpro \
saml11-xpro \
$(BOARD_INSUFFICIENT_MEMORY64K) \
$(BOARD_INSUFFICIENT_MEMORY32K) \
$(BOARD_INSUFFICIENT_MEMORY16K) \
#

6
examples/wasm/README.md Normal file
View File

@ -0,0 +1,6 @@
# building WASM
The source for test.wasm can be found in
<RIOT>/build/pkg/wamr/product-mini/app-samples/hello-world/
https://github.com/bytecodealliance/wasm-micro-runtime/tree/main/product-mini/app-samples/hello-world

View File

@ -0,0 +1,24 @@
# following line a hints for build options mostly untested
# some are not matching RIOTs application targets
# they default to off
# set (WAMR_BUILD_LIBC_WASI 1) #enable libc wasi support
# set (WAMR_BUILD_THREAD_MGR 1) #enable thread manager support
# set (WAMR_BUILD_APP_FRAMEWORK 1) #enable WAMR app framework support
# set (WAMR_BUILD_LIB_PTHREAD 1) #enable pthread support
# set (WAMR_BUILD_JIT 1) #enable WAMR JIT
# set (WAMR_BUILD_FAST_INTERP 1) #enable Fast interpreter
# set (WAMR_BUILD_MULTI_MODULE 1) #enable Multiple modules
# set (WAMR_BUILD_SPEC_TEST 1) #enable spec test compatible mode is on
# set (WAMR_BUILD_BULK_MEMORY 1) #enable Bulk memory feature
# set (WAMR_BUILD_SHARED_MEMORY 1) #enable Shared memory
# set (WAMR_BUILD_MINI_LOADER 1) #enable WASM mini loader
# set (WAMR_DISABLE_HW_BOUND_CHECK 1) #enable Hardware boundary check disabled
# set (WAMR_BUILD_MEMORY_PROFILING 1) #enable Memory profiling
# 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

142
examples/wasm/iwasmt.c Normal file
View File

@ -0,0 +1,142 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* Copyright (C) 2020 TU Bergakademie Freiberg Karl Fessel
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wasm_export.h"
/* execs the main function in an instantiated module */
static int iwasm_instance_exec_main(wasm_module_inst_t module_inst, int argc, char **argv)
{
/* exception memory is part of instance -> no buffer need */
const char *exception = 0;
int ret = 0;
wasm_application_execute_main(module_inst, argc, argv);
if ((exception = wasm_runtime_get_exception(module_inst))) {
puts(exception);
return -1;
}
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)
{
wasm_module_inst_t wasm_module_inst = NULL;
int ret = 0;
{ /* instantiate the module */
char error_buf[128];
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, 8 * 1024,
8 * 1024, error_buf, sizeof(error_buf)))) {
puts(error_buf);
return -1;
}
}
ret = iwasm_instance_exec_main(wasm_module_inst, argc, argv);
/* destroy the module instance */
wasm_runtime_deinstantiate(wasm_module_inst);
return ret;
}
/* bytecode needs to be writeable*/
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)))) {
puts(error_buf);
return -1;
}
}
ret = iwasm_module_exec_main(wasm_module, argc, argv);
/* unload WASM module */
wasm_runtime_unload(wasm_module);
return ret;
}
/* running this initialises the wamr runtime*/
bool iwasm_runtime_init(void)
{
RuntimeInitArgs init_args;
memset(&init_args, 0, sizeof(RuntimeInitArgs));
/* using default system allocator, pool allocator and
* and allocator function hooks are available
* see <wamr>/core/iwasm/include/wasm_export.h l99..*/
init_args.mem_alloc_type = Alloc_With_System_Allocator;
/* initialize runtime environment */
if (!wasm_runtime_full_init(&init_args)) {
puts("Init runtime environment failed.");
return false;
}
return true;
}
void iwasm_runtime_destroy(void)
{
wasm_runtime_destroy();
}
/* 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)
{
return iwasm_bytecode_exec_main((uint8_t *)bytecode, bytecode_len, argc, 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;
}
memcpy(wasm_buf, bytecode, bytecode_len);
/* no copy need if architecture has const in writable mem */
/* wasm_buf = (uint8_t *) main_wasm; */
unsigned wasm_buf_size = bytecode_len;
/* iwasm uses argv[0] cast to an int to store mains return value */
static char * empty = "";
char ** parv;
if (argc > 0) {
parv = malloc(sizeof(argv[0]) * argc);
if (!parv){
return -1;
}
memcpy(parv, argv, sizeof(argv[0]) * argc);
}
else {
argc = 1;
parv = malloc(sizeof(argv[0]) * argc);
if (!parv) {
return -1;
}
parv[0] = empty;
}
int ret = wamr_run(wasm_buf, wasm_buf_size, argc, parv);
free(parv);
free(wasm_buf);
return ret;
}

BIN
examples/wasm/test.wasm Executable file

Binary file not shown.

44
examples/wasm/wasm-main.c Normal file
View File

@ -0,0 +1,44 @@
/*
* 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 <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
/*provide some test program*/
#include "blob/test.wasm.h"
#include "blob/hello.wasm.h"
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);
/* 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);
#define telltruth(X) ((X) ? "true" : "false")
int main(void)
{
printf("iwasm_initilised: %s\n", telltruth(iwasm_runtime_init()));
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();
}

View File

@ -0,0 +1,117 @@
#sometimes there might not be a wasm-ld (Ubuntu:focal)
#lets check if we can find a specific version
#this is a kind of crazy which from
#https://www.gnu.org/software/make/manual/html_node/Call-Function.html#Call-Function
#see https://github.com/RIOT-OS/RIOT/pull/16806 and /16807 and /16776 for why
search_fn = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))))
ifneq ($(call search_fn,wasm-ld),)
WASM-LD ?= wasm-ld
else
ifneq ($(call search_fn,wasm-ld-11),)
LLVM_VERSION := 11
else
ifneq ($(call search_fn,wasm-ld-10),)
LLVM_VERSION := 10
else
ifneq ($(call search_fn,wasm-ld-9),)
LLVM_VERSION := 9
else
ifneq ($(call search_fn,wasm-ld-8),)
LLVM_VERSION := 8
endif
endif
endif
endif
endif
ifneq ($(LLVM_VERSION),)
CLANG ?= clang-$(LLVM_VERSION)
CLANGPP ?= clang++-$(LLVM_VERSION)
WASM-LD ?= wasm-ld-$(LLVM_VERSION)
else
CLANG ?= clang
CLANGPP ?= clang++
endif
ifeq ($(WASM-LD),)
WASM-LD ?= echo "!! NO wasm-ld(-VERSION) found !!"; false
COPY_HELLO := YES
endif
LINK_FLAGS := -z stack-size=4096 \
--export main \
--export=__heap_base \
--export=__data_end \
--allow-undefined \
--no-entry \
--strip-all \
--export-dynamic \
-error-limit=0 \
--lto-O3 \
-O3 \
--gc-sections\
--initial-memory=65536 \
# --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 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 \
--target=wasm32-unknown-unknown-wasm \
-emit-llvm \
-Os \
-flto \
-fvisibility=hidden \
-ffunction-sections \
-fdata-sections \
#one might consider adding these
# -nostartfiles \
# --nostdlib \
# --nostdinc \
# -std=c++14 \
%.show: %.wasm
wasm2wat $<
%.wasm: %.o Makefile
$(WASM-LD) -o $@ $(LINK_FLAGS) $<
%.o: %.cpp Makefile FORCE
$(CLANGPP) \
-c \
$(COMPILE_FLAGS) \
-o $@ \
$<
%.o: %.c Makefile FORCE
$(CLANG)\
-c \
$(COMPILE_FLAGS) \
-o $@ \
$<
%.wat: %.wasm Makefile
wasm2wat -o $@ $<
ifeq ($(COPY_HELLO),YES)
hello.wasm: hello_prebuild.wasm
@echo "!! NO wasm-ld(-VERSION) found !!"
@echo "!! copying hello_prebuild.wasm !! "
cp hello_prebuild.wasm hello.wasm
else
hello_prebuild.wasm: hello.wasm
cp hello.wasm hello_prebuild.wasm
endif
.PHONY: FORCE

View File

@ -0,0 +1,21 @@
/* Copyright (C) World
* a native printf is provided by the builtin libc of wamr */
#ifdef __cplusplus
extern "C" int printf( const char *, ...);
#define WASM_EXPORT __attribute__((visibility("default"))) extern "C"
#else
extern int printf( const char *, ...);
#define WASM_EXPORT __attribute__((visibility("default")))
#endif
WASM_EXPORT int main(int argc, char **argv)
{
if (argc > 1) {
printf("Hello %s %i\n", argv[1], 2001);
}
else {
printf("Hello %s %i\n", "RIOT", 2001);
}
return 2468;
}

Binary file not shown.

60
pkg/wamr/CMakeLists.txt Normal file
View File

@ -0,0 +1,60 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 3.8.2)
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
project(NONE)
enable_language (ASM)
set (WAMR_BUILD_PLATFORM "riot")
if (DEFINED WAMR_CONFIG)
include (${WAMR_CONFIG})
endif ()
# Build as X86_32 by default, change to "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", "MIPS" or "XTENSA"
# if we want to support arm, thumb, mips or xtensa
if (NOT DEFINED WAMR_BUILD_TARGET)
set (WAMR_BUILD_TARGET "X86_32")
endif ()
if (NOT DEFINED WAMR_BUILD_INTERP)
# Enable Interpreter by default
set (WAMR_BUILD_INTERP 1)
endif ()
if (NOT DEFINED WAMR_BUILD_AOT)
# Disable AOT by default.
set (WAMR_BUILD_AOT 0)
endif ()
if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
# Enable libc builtin support by default
set (WAMR_BUILD_LIBC_BUILTIN 1)
endif ()
if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
# Disable libc wasi support by default
set (WAMR_BUILD_LIBC_WASI 0)
endif ()
if (NOT DEFINED WAMR_ROOT_DIR)
# this assumption is true if this file is copied to WAMR_ROOT
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
endif ()
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
# need includes from RIOT
string(REGEX MATCHALL "([^\ ]+\ |[^\ ]+$)" RIOT_INCLUDES_LIST "${RIOT_INCLUDES}")
include_directories(SYSTEM ${RIOT_INCLUDES_LIST})
# target_sources( ${WAMR_RUNTIME_LIB_SOURCE} )
# executable linking is done by RIOT build system this just builds libwamr.a
add_library( wamr ${WAMR_RUNTIME_LIB_SOURCE})

95
pkg/wamr/Makefile Normal file
View File

@ -0,0 +1,95 @@
PKG_NAME=wamr
PKG_URL=https://github.com/bytecodealliance/wasm-micro-runtime.git
ifeq ($(PKG_BLEADING),1)
PKG_VERSION=main
else
PKG_VERSION=a22a5da40d7c81ebf3ebb26b457439712f5dde56
#main 2022-02-09
endif
PKG_LICENSE=Apache-2.0
PKG_CUSTOM_PREPARED = CHECK_VERSION
include $(RIOTBASE)/pkg/pkg.mk
#less Wall TODO: get things fixed upstream
CFLAGS := $(filter-out -Wcast-align, $(CFLAGS))
CFLAGS := $(filter-out -Werror, $(CFLAGS))
CFLAGS += -Wno-format
CFLAGS += -Wno-strict-prototypes
CFLAGS += -Wno-old-style-definition
CFLAGS += -Wno-cast-function-type
#Prepapre includes for cmake
RIOT_INCLUDES = $(filter-out -%,$(subst -I,,$(INCLUDES)))
#translate (CPU_ARCH) to Build Target
#WAMR_BUILD_TARGET is "X86_32" "AARCH64[sub]", "ARM[sub]",
# "THUMB[sub]", "MIPS" or "XTENSA"
#no msp430, no AVR support for now
ifeq ($(CPU),native)
ifeq ($(findstring x86,$(OS_ARCH)),x86)
WAMR_BUILD_TARGET = X86_32
endif
ifeq ($(findstring arm,$(OS_ARCH)),arm)
WAMR_BUILD_TARGET = ARM
endif
ifeq ($(findstring aarch,$(OS_ARCH)),aarch)
#using 32Bit arm on native aarch
WAMR_BUILD_TARGET = ARM
endif
else ifeq ($(findstring arm,$(CPU_ARCH)),arm)
WAMR_BUILD_TARGET = THUMB
else ifeq ($(CPU_ARCH),mips32r2)
WAMR_BUILD_TARGET = MIPS
else ifeq ($(CPU_ARCH),xtensa)
WAMR_BUILD_TARGET = XTENSA
else ifeq ($(CPU_ARCH),rv32)
WAMR_BUILD_TARGET = RISCV32
else
$(error "WASM is not supported for architecture $(CPU_ARCH)")
endif
ifeq ($(QUIET),0)
CMAKEMAKEFLAGS += VERBOSE=1
endif
#WAMR_CONFIG will be included into the cmake
ifneq ($(WAMR_CONFIG),)
WAMR_CMAKE_FLAGS += "-DWAMR_CONFIG=$(WAMR_CONFIG)"
endif
WAMR_CMAKE_FLAGS += "-DRIOT_INCLUDES=$(RIOT_INCLUDES)"\
-DWAMR_BUILD_TARGET=$(WAMR_BUILD_TARGET)\
-DWAMR_ROOT_DIR=$(PKG_SOURCE_DIR)/ \
-DCMAKE_SYSTEM_NAME=Generic \
-DCMAKE_SYSTEM_PROCESSOR="$(MCPU)" \
-DCMAKE_C_COMPILER=$(CC) \
-DCMAKE_C_COMPILER_WORKS=TRUE \
#
all: $(BINDIR)/libwamr.a
$(BINDIR)/libwamr.a: $(PKG_BUILD_DIR)/libwamr.a
cp $< $@
$(PKG_BUILD_DIR)/libwamr.a: $(PKG_BUILD_DIR)/Makefile
+$(MAKE) -C $(PKG_BUILD_DIR) $(CMAKEMAKEFLAGS)
$(PKG_BUILD_DIR)/Makefile: $(PKG_PREPARED) print_build_target
ASMFLAGS="${CFLAGS}" cmake -B$(PKG_BUILD_DIR) $(WAMR_CMAKE_FLAGS)
print_build_target:
@echo PKG_VERSION: $(PKG_VERSION)
@echo native OS_ARCH: $(OS_ARCH)
@echo CPU_ARCH: $(CPU_ARCH)
@echo CPU: $(CPU)
@echo CFLAGS: $(CFLAGS)
@echo WAMR_BUILD_TARGET: $(WAMR_BUILD_TARGET)
@echo WAMR_CONFIG: $(WAMR_CONFIG)
@echo RIOT_INCLUDES: $(RIOT_INCLUDES)
CHECK_VERSION:
test -f $(PKG_DOWNLOADED) && (test `cat $(PKG_DOWNLOADED)` = $(PKG_VERSION) || rm $(PKG_DOWNLOADED));true

9
pkg/wamr/Makefile.dep Normal file
View File

@ -0,0 +1,9 @@
USEMODULE += sema
USEMODULE += ztimer64_msec
USEMODULE += ztimer_usec
#WAMR supports "X86_32/64", "AARCH64", "ARM", "THUMB", "MIPS", "XTENSA" and RISCV
FEATURES_REQUIRED_ANY += arch_native|arch_esp32|arch_riscv|cortexm_svc
#arch_arm|arch_mips32r2|arch_esp need modified
# build/pkg/wamr/core/iwasm/common/arch/invokeNative_<arch>.s

12
pkg/wamr/Makefile.include Normal file
View File

@ -0,0 +1,12 @@
IWASM_CORE := $(PKGDIRBASE)/wamr/core
IWASM_ROOT := $(IWASM_CORE)/iwasm
SHARED_LIB_ROOT := $(IWASM_CORE)/shared
IWASM_INCLUDES += ${IWASM_ROOT}/include \
${SHARED_LIB_ROOT}/platform/include \
${SHARED_LIB_ROOT}/platform/riot \
#
INCLUDES += $(addprefix -I,${IWASM_INCLUDES})
ARCHIVES += $(BINDIR)/libwamr.a

24
pkg/wamr/config.cmake Normal file
View File

@ -0,0 +1,24 @@
# following lines are hints for build options (mostly untested)
# some are not matching RIOTs application targets
# they default to off
# set (WAMR_BUILD_LIBC_WASI 1) #enable libc wasi support
# set (WAMR_BUILD_THREAD_MGR 1) #enable thread manager support
# set (WAMR_BUILD_APP_FRAMEWORK 1) #enable WAMR app framework support
# set (WAMR_BUILD_LIB_PTHREAD 1) #enable pthread support
# set (WAMR_BUILD_JIT 1) #enable WAMR JIT
# set (WAMR_BUILD_FAST_INTERP 1) #enable Fast interpreter
# set (WAMR_BUILD_MULTI_MODULE 1) #enable Multiple modules
# set (WAMR_BUILD_SPEC_TEST 1) #enable spec test compatible mode is on
# set (WAMR_BUILD_BULK_MEMORY 1) #enable Bulk memory feature
# set (WAMR_BUILD_SHARED_MEMORY 1) #enable Shared memory
# set (WAMR_BUILD_MINI_LOADER 1) #enable WASM mini loader
# set (WAMR_DISABLE_HW_BOUND_CHECK 1) #enable Hardware boundary check disabled
# set (WAMR_BUILD_MEMORY_PROFILING 1) #enable Memory profiling
# 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

86
pkg/wamr/doc.txt Normal file
View File

@ -0,0 +1,86 @@
/**
* @defgroup pkg_wamr WebAssembly Micro Runtime
* @ingroup pkg
* @brief Provides WebAssembly support for RIOT
* @see https://github.com/bytecodealliance/wasm-micro-runtime
*
* # WebAssembly Micro Runtime Riot Package
*
* "WebAssembly Micro Runtime (WAMR) is a standalone WebAssembly (WASM)
* runtime with a small footprint."
*
* @see https://github.com/bytecodealliance/wasm-micro-runtime
*
* ## Status
*
* WAMR integration into RIOT should be considered experimental.
* Changes that had to be done in WAMR are send to and integrated into upstream.
* WAMR provides support for numerous architectures:
* "X86_32/64", "AARCH64", "ARM", "THUMB", "MIPS", "XTENSA" and "RISCV"
* this Package will build for native (x86,arm, aarch(using arm)), cortex-m, esp32 and riscv
*
* support for other architectures might provideable using the generic
* `core/iwasm/common/arch/invokeNative_general.c` this is not tested
*
* tested : Cortex-M - "THUMB", native - "X86_32"
*
* ## Memory usage
*
* WebAssembly defines its pages to be 64kB -> WAMR needs a good amount of RAM to run.
*
* WASM files can be linked to use just a part of the first page.
* In this case the VM can be run with less ram.
* (see `wasm_sample/Makefile` in `examples/wasm` for linker options to help with this)
* While running the example configured with 8KiB Heap and 8KiB Stack,
* ~24KiB of System Heap are used.
* The thread, the WAMR interpreter (iwasm) is executed in,
* should be configured to have more than 3KiB of Stack,
* this also depend on the architecture and the native functions that are called.
*
* ## building wasm-bytecode
*
* `clang` and `wasm-ld` of the *same version* must be used
* The Makefile in `examples/wasm/wasm_sample/Makefile` will try to guess
* a matching clang, wasm-ld pair, if they do not match linking will fail.
*
* ## Configuration
*
* WAMR compilation is configured using a CMAKE config file (see `pkg/wamr/config.cmake`)
* Add `export WAMR_CONFIG := $(abspath config.cmake)` to Makefile to apply a specific config.
* Most options (e.g. WASI) are not supported in RIOT since they have OS requirements,
* that are no yet fulfilled.
*
* ## Usage Details
*
* WAMR should be used using the functions provided by the WAMR project their API-headers
* they can be found in `<RIOT>/build/pkg/wamr/core/iwasm/include/`.
* pkg/wamr adds no RIOT specific API to that.
* For simple usages like in the example `iwasm.c` in `examples/wasm` might be useful and
* if used should be copied and adapt to the application need.
*
* While WebAssembly does not define a set native functions. WAMR provides its own builtin-libc.
* Other native functions may be provided by registering native_api to WAMR.
* @see https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/export_native_api.md
*
* ### Why is there no RIOT specific API?
*
* many use cases more complex than: take that Bytecode and run its main would require
* a application specific usage pattern of the WAMR-API
* (memory setup, function search, parameter, module-loading/unloading)
* the WAMR-API does this well and they provide a second wasm-c-api compatible API.
*
* `iwasm.c` might therefore be a good starting point (copy) but it is no good
* generic interface to WAMR. Making it good and generic would lead to the API
* provided by WAMR.
*
* ## Upstream Documentation
*
* @see https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/README.md
* @see https://github.com/bytecodealliance/wasm-micro-runtime/tree/main/doc
* @see https://github.com/bytecodealliance/wasm-micro-runtime/wiki
*
* @see https://github.com/WebAssembly/wasm-c-api
* Include Headers:
* @see https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/core/iwasm/include/
*
*/