Implement native function pointer check, addr conversion and register, update documents (#185)

Modified WASM runtime API:
- wasm_runtime_module_malloc()
- wasm_runtime_lookup_function()
Introduced runtime API
- wasm_runtime_register_natives()
This commit is contained in:
wenyongh
2020-03-04 20:12:38 +08:00
committed by GitHub
parent 2e36149e32
commit 0d3f304191
96 changed files with 2293 additions and 2317 deletions

View File

@ -0,0 +1,125 @@
Application framework
=======
## Directory structure
This folder "app-native-shared" is for the source files shared by both WASM APP and native runtime
- The c files in this directory are compiled into both the WASM APP and runtime.
- The header files for distributing to SDK are placed in the "bi-inc" folder.
This folder "template" contains a pre-defined directory structure for a framework component. The developers can copy the template folder to create new components to the application framework.
Every other subfolder is framework component. Each component contains two library parts: **app and native**.
- The "base" component provide timer API and inter-app communication support. It must be enabled if other components are selected.
- Under the "app" folder of a component, the subfolder "wa_inc" holds all header files that should be included by the WASM applications
## Application framework basic model
The app framework is built on top of two fundamental operations:
- [Native calls into WASM function](../../doc/embed_wamr.md)
- [WASM app calls into native API](../../doc/export_native_api.md)
Asynchronized programming model is supported for WASM applications
- Every WASM app has its own sandbox and thread
- Queue and messaging
<img src="../../doc/pics/app_framework.PNG" style="zoom:67%;" />
## Customized building of app framework
A component can be compilation configurable to the runtime. The wamr SDK tool "build_sdk.sh" supports menu config to select app components for building a customized runtime.
A number of CMAKE variables are defined to control build of framework and components. You can create a cmake file for defining these variables and include it in the CMakeList.txt for your software, or pass it in "-x" argument when run the [build_sdk.sh](../../wamr-sdk/build_sdk.sh) for building the runtime SDK.
```cmake
set (WAMR_BUILD_APP_FRAMEWORK 1)
set (WAMR_BUILD_APP_LIST WAMR_APP_BUILD_BASE)
```
Variables:
- **WAMR_BUILD_APP_FRAMEWORK**: enable the application framework
- **WAMR_BUILD_APP_LIST**: the selected components to be built into the final runtime
The configuration file can be generated through the wamr-sdk menu config:
```bash
cd wamr-sdk
./build_sdk -n [profile] -i
```
## Create new components
Generally you should follow following steps to create a new component:
- Copy the “template” for creating a new folder
- Implement the app part
- If your component exports native function to WASM, ensure your created a header file under app for declaring the function prototype.
- If you component provides header files for the WASM applications to include, ensure it is placed under subfolder "wa_inc".
- Implement the native part
- If your native function is exported to WASM, you need to create an inl file for the registration. It can be any file name, assuming the file name is "my_component.inl" here:
```c
//use right signature for your functions
EXPORT_WASM_API_WITH_SIG(wasm_my_component_api_1, "(i*~)i"),
EXPORT_WASM_API_WITH_SIG(wasm_my_component_api_2, "(i)i"),
```
- Ensure "wasm_lib.cmake" is provided as it will be included by the WAMR SDK building script
- Add a definition in "wasm_lib.cmake" for your component, e.g.
```cmake
add_definitions (-DAPP_FRAMEWORK_MY_COMPONENT)
```
- Modify the file [app_ext_lib_export.c](./app_ext_lib_export.c) to register native APIs exported for the new introduced component. Skip it if not exporting native functions.
```
#include "lib_export.h"
...
#ifdef APP_FRAMEWORK_MY_COMPONENT // this definition is created in wasm_lib.cmake
#include "my_component_native_api.h"
#endif
static NativeSymbol extended_native_symbol_defs[] = {
...
#ifdef APP_FRAMEWORK_MY_COMPONENT
#include "my_component.inl"
#endif
};
```
## Sensor component working flow
![](../../doc/pics/sensor_callflow.PNG)

View File

@ -26,8 +26,8 @@
#define addr_native_to_app(ptr) \
wasm_runtime_addr_native_to_app(module_inst, ptr)
#define module_malloc(size) \
wasm_runtime_module_malloc(module_inst, size)
#define module_malloc(size, p_native_addr) \
wasm_runtime_module_malloc(module_inst, size, p_native_addr)
#define module_free(offset) \
wasm_runtime_module_free(module_inst, offset)

View File

@ -0,0 +1,39 @@
#include "lib_export.h"
#ifdef APP_FRAMEWORK_SENSOR
#include "sensor_native_api.h"
#endif
#ifdef APP_FRAMEWORK_CONNECTION
#include "connection_native_api.h"
#endif
#ifdef APP_FRAMEWORK_WGL
#include "gui_native_api.h"
#endif
/* More header file here */
static NativeSymbol extended_native_symbol_defs[] = {
#ifdef APP_FRAMEWORK_SENSOR
#include "runtime_sensor.inl"
#endif
#ifdef APP_FRAMEWORK_CONNECTION
#include "connection.inl"
#endif
#ifdef APP_FRAMEWORK_WGL
#include "wamr_gui.inl"
#endif
/* More inl file here */
};
int
get_ext_lib_export_apis(NativeSymbol **p_ext_lib_apis)
{
*p_ext_lib_apis = extended_native_symbol_defs;
return sizeof(extended_native_symbol_defs) / sizeof(NativeSymbol);
}

View File

@ -1,8 +1,15 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
add_definitions (-DWASM_ENABLE_APP_FRAMEWORK=1)
set (APP_FRAMEWORK_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR})
if ( NOT DEFINED APP_FRAMEWORK_INCLUDE_TYPE )
LIST (APPEND WASM_APP_LIB_SOURCE_ALL ${CMAKE_CURRENT_LIST_DIR}/app_ext_lib_export.c)
endif()
# app-native-shared and base are required
include (${APP_FRAMEWORK_ROOT_DIR}/app-native-shared/native_interface.cmake)
LIST (APPEND WASM_APP_SOURCE_ALL ${NATIVE_INTERFACE_SOURCE})
@ -31,10 +38,6 @@ function (add_module_native arg)
LIST (APPEND WASM_APP_LIB_SOURCE_ALL ${WASM_APP_LIB_CURRENT_SOURCE})
set (WASM_APP_LIB_SOURCE_ALL ${WASM_APP_LIB_SOURCE_ALL} PARENT_SCOPE)
# VARIABLES in function are only used in this scope,
# set PARENT_SCOPE to pass to top CMakeLists
set (WASM_LIB_BASE_SOURCE ${WASM_LIB_BASE_SOURCE} PARENT_SCOPE)
endfunction ()
function (add_module_app arg)
@ -83,4 +86,4 @@ else ()
endif ()
ENDFOREACH (dir)
endif()
endif()

View File

@ -3,12 +3,12 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
EXPORT_WASM_API(wasm_register_resource),
EXPORT_WASM_API(wasm_response_send),
EXPORT_WASM_API(wasm_post_request),
EXPORT_WASM_API(wasm_sub_event),
EXPORT_WASM_API(wasm_create_timer),
EXPORT_WASM_API(wasm_timer_destroy),
EXPORT_WASM_API(wasm_timer_cancel),
EXPORT_WASM_API(wasm_timer_restart),
EXPORT_WASM_API(wasm_get_sys_tick_ms),
EXPORT_WASM_API_WITH_SIG(wasm_register_resource, "($)"),
EXPORT_WASM_API_WITH_SIG(wasm_response_send, "(*~)i"),
EXPORT_WASM_API_WITH_SIG(wasm_post_request, "(*~)"),
EXPORT_WASM_API_WITH_SIG(wasm_sub_event, "($)"),
EXPORT_WASM_API_WITH_SIG(wasm_create_timer, "(iii)i"),
EXPORT_WASM_API_WITH_SIG(wasm_timer_destroy, "(i)"),
EXPORT_WASM_API_WITH_SIG(wasm_timer_cancel, "(i)"),
EXPORT_WASM_API_WITH_SIG(wasm_timer_restart, "(ii)"),
EXPORT_WASM_API_WITH_SIG(wasm_get_sys_tick_ms, "()i"),

View File

@ -14,19 +14,13 @@ extern "C" {
#endif
bool
wasm_response_send(wasm_exec_env_t exec_env,
int32 buffer_offset, int size);
wasm_response_send(wasm_exec_env_t exec_env, char *buffer, int size);
void
wasm_register_resource(wasm_exec_env_t exec_env,
int32 url_offset);
wasm_register_resource(wasm_exec_env_t exec_env, char *url);
void
wasm_post_request(wasm_exec_env_t exec_env,
int32 buffer_offset, int size);
wasm_post_request(wasm_exec_env_t exec_env, char *buffer, int size);
void
wasm_sub_event(wasm_exec_env_t exec_env,
int32 url_offset);
wasm_sub_event(wasm_exec_env_t exec_env, char *url);
#ifdef __cplusplus
}

View File

@ -11,17 +11,8 @@
extern void module_request_handler(request_t *request, void *user_data);
bool
wasm_response_send(wasm_exec_env_t exec_env,
int32 buffer_offset, int size)
wasm_response_send(wasm_exec_env_t exec_env, char *buffer, int size)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *buffer = NULL;
if (!validate_app_addr(buffer_offset, size))
return false;
buffer = addr_app_to_native(buffer_offset);
if (buffer != NULL) {
response_t response[1];
@ -37,15 +28,9 @@ wasm_response_send(wasm_exec_env_t exec_env,
}
void
wasm_register_resource(wasm_exec_env_t exec_env, int32 url_offset)
wasm_register_resource(wasm_exec_env_t exec_env, char *url)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *url = NULL;
if (!validate_app_str_addr(url_offset))
return;
url = addr_app_to_native(url_offset);
if (url != NULL) {
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,
@ -56,16 +41,9 @@ wasm_register_resource(wasm_exec_env_t exec_env, int32 url_offset)
}
void
wasm_post_request(wasm_exec_env_t exec_env,
int32 buffer_offset, int size)
wasm_post_request(wasm_exec_env_t exec_env, char *buffer, int size)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *buffer = NULL;
if (!validate_app_addr(buffer_offset, size))
return;
buffer = addr_app_to_native(buffer_offset);
if (buffer != NULL) {
request_t req[1];
@ -91,15 +69,9 @@ wasm_post_request(wasm_exec_env_t exec_env,
}
void
wasm_sub_event(wasm_exec_env_t exec_env, int32 url_offset)
wasm_sub_event(wasm_exec_env_t exec_env, char *url)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *url = NULL;
if (!validate_app_str_addr(url_offset))
return;
url = addr_app_to_native(url_offset);
if (url != NULL) {
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
EXPORT_WASM_API(wasm_open_connection),
EXPORT_WASM_API(wasm_close_connection),
EXPORT_WASM_API(wasm_send_on_connection),
EXPORT_WASM_API(wasm_config_connection),
EXPORT_WASM_API_WITH_SIG(wasm_open_connection, "($*~)i"),
EXPORT_WASM_API_WITH_SIG(wasm_close_connection, "(i)"),
EXPORT_WASM_API_WITH_SIG(wasm_send_on_connection, "(i*~)i"),
EXPORT_WASM_API_WITH_SIG(wasm_config_connection, "(i*~)i"),

View File

@ -20,16 +20,16 @@ extern "C" {
uint32
wasm_open_connection(wasm_exec_env_t exec_env,
int32 name_offset, int32 args_offset, uint32 len);
char *name, char *args_buf, uint32 len);
void
wasm_close_connection(wasm_exec_env_t exec_env,
uint32 handle);
int
wasm_send_on_connection(wasm_exec_env_t exec_env,
uint32 handle, int32 data_offset, uint32 len);
uint32 handle, char *data, uint32 len);
bool
wasm_config_connection(wasm_exec_env_t exec_env,
uint32 handle, int32 cfg_offset, uint32 len);
uint32 handle, char *cfg_buf, uint32 len);

View File

@ -16,17 +16,10 @@
uint32
wasm_open_connection(wasm_exec_env_t exec_env,
int32 name_offset, int32 args_offset, uint32 len)
char *name, char *args_buf, uint32 len)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
attr_container_t *args;
char *name, *args_buf;
if (!validate_app_str_addr(name_offset) ||
!validate_app_addr(args_offset, len) ||
!(name = addr_app_to_native(name_offset)) ||
!(args_buf = addr_app_to_native(args_offset)))
return -1;
args = (attr_container_t *)args_buf;
@ -45,15 +38,8 @@ wasm_close_connection(wasm_exec_env_t exec_env, uint32 handle)
int
wasm_send_on_connection(wasm_exec_env_t exec_env,
uint32 handle, int32 data_offset, uint32 len)
uint32 handle, char *data, uint32 len)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *data;
if (!validate_app_addr(data_offset, len) ||
!(data = addr_app_to_native(data_offset)))
return -1;
if (connection_impl._send != NULL)
return connection_impl._send(handle, data, len);
@ -62,16 +48,10 @@ wasm_send_on_connection(wasm_exec_env_t exec_env,
bool
wasm_config_connection(wasm_exec_env_t exec_env,
uint32 handle, int32 cfg_offset, uint32 len)
uint32 handle, char *cfg_buf, uint32 len)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *cfg_buf;
attr_container_t *cfg;
if (!validate_app_addr(cfg_offset, len) ||
!(cfg_buf = addr_app_to_native(cfg_offset)))
return false;
cfg = (attr_container_t *)cfg_buf;
if (connection_impl._config != NULL)

View File

@ -5,6 +5,9 @@ set (WASM_LIB_CONN_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${WASM_LIB_CONN_DIR})
add_definitions (-DAPP_FRAMEWORK_CONNECTION)
include (${CMAKE_CURRENT_LIST_DIR}/${WAMR_BUILD_PLATFORM}/connection_mgr.cmake)
file (GLOB source_all

View File

@ -135,15 +135,9 @@ wasm_sensor_config(wasm_exec_env_t exec_env,
uint32
wasm_sensor_open(wasm_exec_env_t exec_env,
int32 name_offset, int instance)
char *name, int instance)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *name = NULL;
if (!validate_app_str_addr(name_offset))
return -1;
name = addr_app_to_native(name_offset);
if (name != NULL) {
sensor_client_t *c;
@ -192,17 +186,8 @@ wasm_sensor_open(wasm_exec_env_t exec_env,
bool
wasm_sensor_config_with_attr_container(wasm_exec_env_t exec_env,
uint32 sensor, int32 buffer_offset,
int len)
uint32 sensor, char *buffer, int len)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
char *buffer = NULL;
if (!validate_app_addr(buffer_offset, len))
return false;
buffer = addr_app_to_native(buffer_offset);
if (buffer != NULL) {
attr_container_t *cfg = (attr_container_t *)buffer;
sensor_obj_t s = find_sys_sensor_id(sensor);

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
EXPORT_WASM_API(wasm_sensor_open),
EXPORT_WASM_API(wasm_sensor_config),
EXPORT_WASM_API(wasm_sensor_config_with_attr_container),
EXPORT_WASM_API(wasm_sensor_close),
EXPORT_WASM_API_WITH_SIG(wasm_sensor_open, "($i)i"),
EXPORT_WASM_API_WITH_SIG(wasm_sensor_config, "(iiii)i"),
EXPORT_WASM_API_WITH_SIG(wasm_sensor_config_with_attr_container, "(i*~)i"),
EXPORT_WASM_API_WITH_SIG(wasm_sensor_close, "(i)i"),

View File

@ -19,12 +19,11 @@ wasm_sensor_config(wasm_exec_env_t exec_env,
int bit_cfg, int delay);
uint32
wasm_sensor_open(wasm_exec_env_t exec_env,
int32 name_offset, int instance);
char *name, int instance);
bool
wasm_sensor_config_with_attr_container(wasm_exec_env_t exec_env,
uint32 sensor, int32 buffer_offset,
int len);
uint32 sensor, char *buffer, int len);
bool
wasm_sensor_close(wasm_exec_env_t exec_env, uint32 sensor);

View File

@ -3,6 +3,8 @@
set (WASM_LIB_SENSOR_DIR ${CMAKE_CURRENT_LIST_DIR})
add_definitions (-DAPP_FRAMEWORK_SENSOR)
include_directories(${WASM_LIB_SENSOR_DIR})

View File

@ -20,23 +20,23 @@ extern "C" {
void
wasm_obj_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc);
int32 func_id, uint32 *argv, uint32 argc);
void
wasm_btn_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc);
int32 func_id, uint32 *argv, uint32 argc);
void
wasm_label_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc);
int32 func_id, uint32 *argv, uint32 argc);
void
wasm_cb_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc);
int32 func_id, uint32 *argv, uint32 argc);
void
wasm_list_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc);
int32 func_id, uint32 *argv, uint32 argc);
#ifdef __cplusplus
}

View File

@ -4,25 +4,25 @@
*/
/* button */
EXPORT_WASM_API(wasm_btn_native_call),
EXPORT_WASM_API_WITH_SIG(wasm_btn_native_call, "(i*i)"),
/* obj */
EXPORT_WASM_API(wasm_obj_native_call),
EXPORT_WASM_API_WITH_SIG(wasm_obj_native_call, "(i*i)"),
/* label */
EXPORT_WASM_API(wasm_label_native_call),
EXPORT_WASM_API_WITH_SIG(wasm_label_native_call, "(i*i)"),
/* cont */
//EXPORT_WASM_API(wasm_cont_native_call),
//EXPORT_WASM_API_WITH_SIG(wasm_cont_native_call, "(i*i)"),
/* page */
//EXPORT_WASM_API(wasm_page_native_call),
//EXPORT_WASM_API_WITH_SIG(wasm_page_native_call, "(i*i)"),
/* list */
EXPORT_WASM_API(wasm_list_native_call),
EXPORT_WASM_API_WITH_SIG(wasm_list_native_call, "(i*i)"),
/* drop down list */
//EXPORT_WASM_API(wasm_ddlist_native_call),
//EXPORT_WASM_API_WITH_SIG(wasm_ddlist_native_call, "(i*i)"),
/* check box */
EXPORT_WASM_API(wasm_cb_native_call),
EXPORT_WASM_API_WITH_SIG(wasm_cb_native_call, "(i*i)"),

View File

@ -6,6 +6,7 @@ set (WASM_LIB_GUI_DIR ${CMAKE_CURRENT_LIST_DIR})
set (DEPS_DIR ${WASM_LIB_GUI_DIR}/../../../deps)
add_definitions(-DLV_CONF_INCLUDE_SIMPLE)
add_definitions (-DAPP_FRAMEWORK_WGL)
include_directories(${WASM_LIB_GUI_DIR}
${DEPS_DIR}

View File

@ -126,7 +126,7 @@ static WGLNativeFuncDef btn_native_func_defs[] = {
/*************** Native Interface to Wasm App ***********/
void
wasm_btn_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc)
int32 func_id, uint32 *argv, uint32 argc)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 size = sizeof(btn_native_func_defs) / sizeof(WGLNativeFuncDef);
@ -135,6 +135,6 @@ wasm_btn_native_call(wasm_exec_env_t exec_env,
btn_native_func_defs,
size,
func_id,
argv_offset,
argv,
argc);
}

View File

@ -73,7 +73,7 @@ static WGLNativeFuncDef cb_native_func_defs[] = {
/*************** Native Interface to Wasm App ***********/
void
wasm_cb_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc)
int32 func_id, uint32 *argv, uint32 argc)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 size = sizeof(cb_native_func_defs) / sizeof(WGLNativeFuncDef);
@ -82,6 +82,6 @@ wasm_cb_native_call(wasm_exec_env_t exec_env,
cb_native_func_defs,
size,
func_id,
argv_offset,
argv,
argc);
}

View File

@ -64,7 +64,7 @@ static WGLNativeFuncDef label_native_func_defs[] = {
/*************** Native Interface to Wasm App ***********/
void
wasm_label_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc)
int32 func_id, uint32 *argv, uint32 argc)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 size = sizeof(label_native_func_defs) / sizeof(WGLNativeFuncDef);
@ -73,6 +73,6 @@ wasm_label_native_call(wasm_exec_env_t exec_env,
label_native_func_defs,
size,
func_id,
argv_offset,
argv,
argc);
}

View File

@ -49,7 +49,7 @@ static WGLNativeFuncDef list_native_func_defs[] = {
/*************** Native Interface to Wasm App ***********/
void
wasm_list_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc)
int32 func_id, uint32 *argv, uint32 argc)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 size = sizeof(list_native_func_defs) / sizeof(WGLNativeFuncDef);
@ -58,6 +58,6 @@ wasm_list_native_call(wasm_exec_env_t exec_env,
list_native_func_defs,
size,
func_id,
argv_offset,
argv,
argc);
}

View File

@ -109,17 +109,11 @@ void wgl_native_func_call(wasm_module_inst_t module_inst,
WGLNativeFuncDef *funcs,
uint32 size,
int32 func_id,
uint32 argv_offset,
uint32 *argv,
uint32 argc)
{
WGLNativeFuncDef *func_def = funcs;
WGLNativeFuncDef *func_def_end = func_def + size;
uint32 *argv;
if (!validate_app_addr(argv_offset, argc * sizeof(uint32)))
return;
argv = addr_app_to_native(argv_offset);
while (func_def < func_def_end) {
if (func_def->func_id == func_id) {

View File

@ -74,7 +74,7 @@ void wgl_native_func_call(wasm_module_inst_t module_inst,
WGLNativeFuncDef *funcs,
uint32 size,
int32 func_id,
uint32 argv_offset,
uint32 *argv,
uint32 argc);
#ifdef __cplusplus

View File

@ -378,7 +378,7 @@ static WGLNativeFuncDef obj_native_func_defs[] = {
/*************** Native Interface to Wasm App ***********/
void
wasm_obj_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc)
int32 func_id, uint32 *argv, uint32 argc)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 size = sizeof(obj_native_func_defs) / sizeof(WGLNativeFuncDef);
@ -387,6 +387,6 @@ wasm_obj_native_call(wasm_exec_env_t exec_env,
obj_native_func_defs,
size,
func_id,
argv_offset,
argv,
argc);
}