Merge pull request #2 from intel/master

Sync up with repo master.
This commit is contained in:
wenyongh 2019-05-10 08:21:02 +08:00 committed by GitHub
commit cd188ade7d
4 changed files with 70 additions and 59 deletions

View File

@ -5,11 +5,18 @@ WebAssembly Micro Runtime (WAMR) is standalone WebAssembly (WASM) runtime with s
- WASM application programming API (code available, but compilation is depending on the app manager component) - WASM application programming API (code available, but compilation is depending on the app manager component)
- Dynamic WASM application management (Not available in github yet. It will be released soon) - Dynamic WASM application management (Not available in github yet. It will be released soon)
Why should we use a WASM runtime out of browser? There are a few points which might be meaningful:
1. WASM is already the LLVM official backend target. That means WASM can run any programming languages which can be compiled to LLVM IR. It is a huge advantage comparing to those language bound runtimes like JS, Lua.
2. WASM is an open standard and the growing trend is so fast as it is supported by the whole web ecosystem
3. WASM is designed to be very friendly for compiling to native binary and gaining the native speed.
4. Potentially change the development practices. Imaging we can do both the WASM application development and validation in a browser, then just download the wasm binary code into the target device.
5. WASM can work without garbage collection. It can be designed to support execution determinics for the time sensitive requirement.
Features Features
========================= =========================
- WASM interpreter (AOT is planned) - WASM interpreter (AOT is planned)
- Provide built-in Libc subset, support side_module=1 EMCC compilation option only - Provide built-in Libc subset, support "side_module=1" EMCC compilation option
- Provide APIs for embedding runtime into production software - Provide APIs for embedding runtime into production software
- Provide mechanism for exporting native APIs to WASM applications - Provide mechanism for exporting native APIs to WASM applications
- Support programming firmware apps in multi languages (C/C++/Java/Rust/Go/TypeScript etc.) - Support programming firmware apps in multi languages (C/C++/Java/Rust/Go/TypeScript etc.)
@ -21,12 +28,17 @@ Features
Architecture Architecture
========================= =========================
WAMR is basically consist of three portions, WASM runtime engine, memory management, messaging and micro service support module. The application manager component handles the packets that the platform recieved from external through any communication buses such as socket, serial port, PSI. A packet type can be either request, response or event. It will service the request with URI "/applet" and call the runtime glue layer interfaces for installing/uninstalling the application. For other URIs, it will filter the resource registeration table and router the request to internal queue of responsible application.
The WebAssembly runtime is the execution environment for WASM applications.
The messaging layer can suppor the API for WASM applications communicate to each other and also the host environment.
When Ahead of Time compilation is enabled, the WASM application can be either bytecode or compiled native binary.
<img src="./doc/pics/architecture.PNG" width="80%" height="80%"> <img src="./doc/pics/architecture.PNG" width="80%" height="80%">
The core function of WAMR is loading and running WASM application binary from local, and WASM applicaiton execution starts from the main entry. Belowing sections are about how to build WAMR core and WASM app, as well as run the WASM app by loading into WASM core.
Build WAMR Core Build WAMR Core
========================= =========================
@ -131,11 +143,10 @@ ninja run
Embed WAMR into software production Embed WAMR into software production
===================================== =====================================
WAMR provided methodology to embed WAMR into your own software product, and defines APIs to enable software code (native) to invoke embedded WASM code. WAMR can be built into a standalone executable which takes WASM application file name as input, and then execute it. To use it in the embedded environment, you should embed WAMR into your own software product. WASM provides a set of APIs for embedders code to load WASM module, instansiate module and invoke WASM function from native call.
<img src="./doc/pics/embed.PNG" width="60%" height="60%"> <img src="./doc/pics/embed.PNG" width="60%" height="60%">
The native code and WASM code execution flows are connected, but the stacks are seperated. WAMR enables the native code to invoke WASM code as invoking own native code transparently. Meanwhile WAMR guarantees the WASM code running inside sandbox.
A typical WAMR APIs usage is as below: A typical WAMR APIs usage is as below:
``` C ``` C
@ -162,7 +173,7 @@ A typical WAMR APIs usage is as below:
WASM application library WASM application library
======================== ========================
In general, WAMR provides 3 levels of APIs for programming the WASM application: In general, there are 3 kinds of APIs for programming the WASM application:
- Built-in APIs: WAMR has already provided a minimal API set for developers. - Built-in APIs: WAMR has already provided a minimal API set for developers.
- 3rd party APIs: Programmer can download include any 3rd party C source code, and added into their own WASM app source tree. - 3rd party APIs: Programmer can download include any 3rd party C source code, and added into their own WASM app source tree.
- Platform native APIs: The board vendors define these APIs during their making board firmware. They are provided WASM application to invoke like built-in and 3rd party APIs. In this way board vendors extend APIs which can make programmers develop more complicated WASM apps. - Platform native APIs: The board vendors define these APIs during their making board firmware. They are provided WASM application to invoke like built-in and 3rd party APIs. In this way board vendors extend APIs which can make programmers develop more complicated WASM apps.
@ -195,7 +206,7 @@ char *strncpy(char *dest, const char *src, unsigned long n);
``` ```
**Base library**<br/> **Base library**<br/>
the basic support like communication, timers etc. The header files is ```lib/app-libs/base/wasm-app.h```, it includes request and response APIs, event pub/sub APIs and timer APIs. Please be noted that they may not work if you have no corresponding framework to work with them. The basic support like communication, timers etc is already available. The header files is ```lib/app-libs/base/wasm-app.h```, it includes request and response APIs, event pub/sub APIs and timer APIs. Please be noted that they may not work if you have no corresponding framework to work with them.
The API set is listed as below: The API set is listed as below:
``` C ``` C
typedef void(*request_handler_f)(request_t *) ; typedef void(*request_handler_f)(request_t *) ;
@ -231,8 +242,8 @@ bool sensor_config_with_attr_container(sensor_t sensor, attr_container_t *cfg);
bool sensor_close(sensor_t sensor); bool sensor_close(sensor_t sensor);
``` ```
Exporting Native API mechanism The mechanism of exporting Native API to WASM application
============================== =======================================================
The basic working flow for WASM application calling into the native API is described as following diagram. The basic working flow for WASM application calling into the native API is described as following diagram.
<img src="./doc/pics/extend_library.PNG" width="60%" height="60%"> <img src="./doc/pics/extend_library.PNG" width="60%" height="60%">

View File

@ -46,30 +46,30 @@ extern "C" {
/* Standalone GC is used for testing.*/ /* Standalone GC is used for testing.*/
#ifndef GC_EMBEDDED #ifndef GC_EMBEDDED
# ifndef GC_STANDALONE # ifndef GC_STANDALONE
# define GC_STANDALONE # define GC_STANDALONE
# endif # endif
#endif #endif
#if defined(GC_EMBEDDED) && defined(GC_STANDALONE) #if defined(GC_EMBEDDED) && defined(GC_STANDALONE)
# error "Can not define GC_EMBEDDED and GC_STANDALONE at the same time" # error "Can not define GC_EMBEDDED and GC_STANDALONE at the same time"
#endif #endif
#ifdef BH_TEST #ifdef BH_TEST
# ifndef GC_TEST # ifndef GC_TEST
# define GC_TEST # define GC_TEST
# endif # endif
#endif #endif
#ifdef BH_DEBUG #ifdef BH_DEBUG
/*instrument mode ignore GC_DEBUG feature, for instrument testing gc_alloc_vo_i_heap only has func_name parameter*/ /*instrument mode ignore GC_DEBUG feature, for instrument testing gc_alloc_vo_i_heap only has func_name parameter*/
#if !defined INSTRUMENT_TEST_ENABLED && !defined GC_DEBUG #if !defined INSTRUMENT_TEST_ENABLED && !defined GC_DEBUG
# define GC_DEBUG # define GC_DEBUG
#endif #endif
#endif #endif
#if defined(GC_EMBEDDED) && defined(GC_TEST) #if defined(GC_EMBEDDED) && defined(GC_TEST)
# error "Can not defined GC_EMBEDDED and GC_TEST at the same time" # error "Can not defined GC_EMBEDDED and GC_TEST at the same time"
#endif #endif
typedef void *gc_handle_t; typedef void *gc_handle_t;
@ -200,17 +200,17 @@ extern int gc_set_threshold_factor(void *heap, unsigned int factor);
/* internally. Functions without _i suffix are just wrappers with the corresponded functions with*/ /* internally. Functions without _i suffix are just wrappers with the corresponded functions with*/
/* _i suffix. Allocation operation code position are record under DEBUG model for debugging.*/ /* _i suffix. Allocation operation code position are record under DEBUG model for debugging.*/
#ifdef GC_DEBUG #ifdef GC_DEBUG
# define ALLOC_EXTRA_PARAMETERS ,const char*file_name,int line_number # define ALLOC_EXTRA_PARAMETERS ,const char*file_name,int line_number
# define ALLOC_EXTRA_ARGUMENTS , __FILE__, __LINE__ # define ALLOC_EXTRA_ARGUMENTS , __FILE__, __LINE__
# define ALLOC_PASSDOWN_EXTRA_ARGUMENTS , file_name, line_number # define ALLOC_PASSDOWN_EXTRA_ARGUMENTS , file_name, line_number
# define gc_alloc_vo_h(heap, size) gc_alloc_vo_i_heap(heap, size, __FILE__, __LINE__) # define gc_alloc_vo_h(heap, size) gc_alloc_vo_i_heap(heap, size, __FILE__, __LINE__)
# define gc_free_h(heap, obj) gc_free_i_heap(heap, obj, __FILE__, __LINE__) # define gc_free_h(heap, obj) gc_free_i_heap(heap, obj, __FILE__, __LINE__)
#else #else
# define ALLOC_EXTRA_PARAMETERS # define ALLOC_EXTRA_PARAMETERS
# define ALLOC_EXTRA_ARGUMENTS # define ALLOC_EXTRA_ARGUMENTS
# define ALLOC_PASSDOWN_EXTRA_ARGUMENTS # define ALLOC_PASSDOWN_EXTRA_ARGUMENTS
# define gc_alloc_vo_h gc_alloc_vo_i_heap # define gc_alloc_vo_h gc_alloc_vo_i_heap
# define gc_free_h gc_free_i_heap # define gc_free_h gc_free_i_heap
#endif #endif
/** /**

View File

@ -98,10 +98,10 @@ extern void hmu_verify(hmu_t *hmu);
#define GETBIT(v, offset) ((v) & (1 << (offset)) ? 1 : 0) #define GETBIT(v, offset) ((v) & (1 << (offset)) ? 1 : 0)
#define CLRBIT(v, offset) (v) &= ~(1 << (offset)) #define CLRBIT(v, offset) (v) &= ~(1 << (offset))
#define SETBITS(v, offset, size, value) do { \ #define SETBITS(v, offset, size, value) do { \
(v) &= ~(((1 << size) - 1) << offset); \ (v) &= ~(((1 << size) - 1) << offset); \
(v) |= value << offset; \ (v) |= value << offset; \
} while(0) } while(0)
#define CLRBITS(v, offset, size) (v) &= ~(((1 << size) - 1) << offset) #define CLRBITS(v, offset, size) (v) &= ~(((1 << size) - 1) << offset)
#define GETBITS(v, offset, size) (((v) & (((1 << size) - 1) << offset)) >> offset) #define GETBITS(v, offset, size) (((v) & (((1 << size) - 1) << offset)) >> offset)
@ -112,8 +112,8 @@ extern void hmu_verify(hmu_t *hmu);
#define hmu_to_obj(hmu) (gc_object_t)(SKIP_OBJ_PREFIX((hmu_t*) (hmu) + 1)) #define hmu_to_obj(hmu) (gc_object_t)(SKIP_OBJ_PREFIX((hmu_t*) (hmu) + 1))
#define obj_to_hmu(obj) ((hmu_t *)((gc_uint8*)(obj) - OBJ_PREFIX_SIZE) - 1) #define obj_to_hmu(obj) ((hmu_t *)((gc_uint8*)(obj) - OBJ_PREFIX_SIZE) - 1)
#define HMU_UT_SIZE 2 #define HMU_UT_SIZE 2
#define HMU_UT_OFFSET 30 #define HMU_UT_OFFSET 30
#define hmu_get_ut(hmu) GETBITS ((hmu)->header, HMU_UT_OFFSET, HMU_UT_SIZE) #define hmu_get_ut(hmu) GETBITS ((hmu)->header, HMU_UT_OFFSET, HMU_UT_SIZE)
#define hmu_set_ut(hmu, type) SETBITS ((hmu)->header, HMU_UT_OFFSET, HMU_UT_SIZE, type) #define hmu_set_ut(hmu, type) SETBITS ((hmu)->header, HMU_UT_OFFSET, HMU_UT_SIZE, type)
@ -126,7 +126,7 @@ extern void hmu_verify(hmu_t *hmu);
#define hmu_unmark_pinuse(hmu) CLRBIT ((hmu)->header, HMU_P_OFFSET) #define hmu_unmark_pinuse(hmu) CLRBIT ((hmu)->header, HMU_P_OFFSET)
#define hmu_get_pinuse(hmu) GETBIT ((hmu)->header, HMU_P_OFFSET) #define hmu_get_pinuse(hmu) GETBIT ((hmu)->header, HMU_P_OFFSET)
#define HMU_JO_VT_SIZE 27 #define HMU_JO_VT_SIZE 27
#define HMU_JO_VT_OFFSET 0 #define HMU_JO_VT_OFFSET 0
#define HMU_JO_MB_OFFSET 28 #define HMU_JO_MB_OFFSET 28
@ -151,7 +151,7 @@ extern void hmu_verify(hmu_t *hmu);
#define HMU_FC_NORMAL_MAX_SIZE ((HMU_NORMAL_NODE_CNT - 1) << 3) #define HMU_FC_NORMAL_MAX_SIZE ((HMU_NORMAL_NODE_CNT - 1) << 3)
#define HMU_IS_FC_NORMAL(size) ((size) < HMU_FC_NORMAL_MAX_SIZE) #define HMU_IS_FC_NORMAL(size) ((size) < HMU_FC_NORMAL_MAX_SIZE)
#if HMU_FC_NORMAL_MAX_SIZE >= GC_MAX_HEAP_SIZE #if HMU_FC_NORMAL_MAX_SIZE >= GC_MAX_HEAP_SIZE
# error "Too small GC_MAX_HEAP_SIZE" #error "Too small GC_MAX_HEAP_SIZE"
#endif #endif
typedef struct _hmu_normal_node typedef struct _hmu_normal_node
@ -264,14 +264,14 @@ extern gc_handle_t (*gct_vm_get_gc_handle_for_current_instance)(void);
extern int (*gct_vm_begin_rootset_enumeration)(void* heap); extern int (*gct_vm_begin_rootset_enumeration)(void* heap);
extern int (*gct_vm_gc_finished)(void); extern int (*gct_vm_gc_finished)(void);
#else #else
#define gct_vm_get_java_object_ref_list bh_get_java_object_ref_list #define gct_vm_get_java_object_ref_list bh_get_java_object_ref_list
#define gct_vm_mutex_init vm_mutex_init #define gct_vm_mutex_init vm_mutex_init
#define gct_vm_mutex_destroy vm_mutex_destroy #define gct_vm_mutex_destroy vm_mutex_destroy
#define gct_vm_mutex_lock vm_mutex_lock #define gct_vm_mutex_lock vm_mutex_lock
#define gct_vm_mutex_unlock vm_mutex_unlock #define gct_vm_mutex_unlock vm_mutex_unlock
#define gct_vm_get_gc_handle_for_current_instance app_manager_get_cur_applet_heap #define gct_vm_get_gc_handle_for_current_instance app_manager_get_cur_applet_heap
#define gct_vm_begin_rootset_enumeration vm_begin_rootset_enumeration #define gct_vm_begin_rootset_enumeration vm_begin_rootset_enumeration
#define gct_vm_gc_finished jeff_runtime_gc_finished #define gct_vm_gc_finished jeff_runtime_gc_finished
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -21,16 +21,16 @@
#include "bh_platform.h" #include "bh_platform.h"
#ifdef BH_TEST #ifdef BH_TEST
# ifndef BH_DEBUG # ifndef BH_DEBUG
# error "BH_TEST should be defined under BH_DEBUG" # error "BH_TEST should be defined under BH_DEBUG"
# endif # endif
#endif #endif
#ifdef BH_TEST #ifdef BH_TEST
# if defined(WIN32) || defined(__linux__) # if defined(WIN32) || defined(__linux__)
# else # else
# error "Test case can not run on the current platform" # error "Test case can not run on the current platform"
# endif # endif
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -44,14 +44,14 @@ extern void bh_assert_internal(int v, const char *file_name, int line_number, co
extern void bh_debug_internal(const char *file_name, int line_number, const char *fmt, ...); extern void bh_debug_internal(const char *file_name, int line_number, const char *fmt, ...);
#if defined(WIN32) || defined(EMU) #if defined(WIN32) || defined(EMU)
# define bh_debug(fmt, ...) bh_debug_internal(__FILE__, __LINE__, fmt, __VA_ARGS__) # define bh_debug(fmt, ...) bh_debug_internal(__FILE__, __LINE__, fmt, __VA_ARGS__)
#elif defined(__linux__) #elif defined(__linux__)
/*# define bh_debug(...) bh_debug_internal(__FILE__, __LINE__, ## __VA_ARGS__)*/ /*# define bh_debug(...) bh_debug_internal(__FILE__, __LINE__, ## __VA_ARGS__)*/
# define bh_debug bh_debug_internal(__FILE__, __LINE__, "");printf # define bh_debug bh_debug_internal(__FILE__, __LINE__, "");printf
#elif defined(PLATFORM_SEC) #elif defined(PLATFORM_SEC)
# define bh_debug(fmt, ...) bh_debug_internal(__FILE__, __LINE__, fmt, __VA_ARGS__) # define bh_debug(fmt, ...) bh_debug_internal(__FILE__, __LINE__, fmt, __VA_ARGS__)
#else #else
# error "Unsupported platform" # error "Unsupported platform"
#endif #endif
#else #else
@ -63,12 +63,12 @@ extern void bh_debug_internal(const char *file_name, int line_number, const char
#define bh_assert_abort(x) do { \ #define bh_assert_abort(x) do { \
if (!x) \ if (!x) \
abort(); \ abort(); \
} while (0) } while (0)
#ifdef BH_TEST #ifdef BH_TEST
# define BH_STATIC # define BH_STATIC
#else #else
# define BH_STATIC static # define BH_STATIC static
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus