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
This commit is contained in:
wenyongh
2020-01-21 13:26:14 +08:00
committed by Wang Xin
parent 2a4528c749
commit 46b93b9d22
464 changed files with 25137 additions and 7911 deletions

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _GUI_API_H_
#define _GUI_API_H_
#include "bh_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
void
wasm_obj_native_call(int32 func_id, int32 argv_offset, uint32 argc);
void
wasm_btn_native_call(int32 func_id, int32 argv_offset, uint32 argc);
void
wasm_label_native_call(int32 func_id, int32 argv_offset, uint32 argc);
void
wasm_cb_native_call(int32 func_id, int32 argv_offset, uint32 argc);
void
wasm_list_native_call(int32 func_id, int32 argv_offset, uint32 argc);
#ifdef __cplusplus
}
#endif
#endif /* end of _GUI_API_H_ */

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
/* button */
EXPORT_WASM_API(wasm_btn_native_call),
/* obj */
EXPORT_WASM_API(wasm_obj_native_call),
/* label */
EXPORT_WASM_API(wasm_label_native_call),
/* cont */
//EXPORT_WASM_API(wasm_cont_native_call),
/* page */
//EXPORT_WASM_API(wasm_page_native_call),
/* list */
EXPORT_WASM_API(wasm_list_native_call),
/* drop down list */
//EXPORT_WASM_API(wasm_ddlist_native_call),
/* check box */
EXPORT_WASM_API(wasm_cb_native_call),

View File

@ -0,0 +1,18 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
set (WASM_LIB_GUI_DIR ${CMAKE_CURRENT_LIST_DIR})
set (DEPS_DIR ${WASM_LIB_GUI_DIR}/../../../deps)
add_definitions(-DLV_CONF_INCLUDE_SIMPLE)
include_directories(${WASM_LIB_GUI_DIR}
${DEPS_DIR}
${DEPS_DIR}/lvgl
${DEPS_DIR}/lvgl/src)
file (GLOB_RECURSE lvgl_source ${DEPS_DIR}/lvgl/*.c)
file (GLOB_RECURSE wrapper_source ${WASM_LIB_GUI_DIR}/*.c)
set (WASM_APP_LIB_CURRENT_SOURCE ${wrapper_source} ${lvgl_source})

View File

@ -0,0 +1,20 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef WAMR_GRAPHIC_LIBRARY_H
#define WAMR_GRAPHIC_LIBRARY_H
#ifdef __cplusplus
extern "C" {
#endif
void wgl_init(void);
void wgl_exit(void);
#ifdef __cplusplus
}
#endif
#endif /* WAMR_GRAPHIC_LIBRARY_H */

View File

@ -0,0 +1,140 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "native_interface.h"
#include "lvgl.h"
#include "module_wasm_app.h"
#include "wgl_native_utils.h"
/* -------------------------------------------------------------------------
* Button widget native function wrappers
* -------------------------------------------------------------------------*/
static int32
lv_btn_create_wrapper(wasm_module_inst_t module_inst,
lv_obj_t *par, lv_obj_t *copy)
{
return wgl_native_wigdet_create(WIDGET_TYPE_BTN, par, copy, module_inst);
}
static void
lv_btn_set_toggle_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * btn, bool tgl)
{
(void)module_inst;
lv_btn_set_toggle(btn, tgl);
}
static void
lv_btn_set_state_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * btn, lv_btn_state_t state)
{
(void)module_inst;
lv_btn_set_state(btn, state);
}
static void
lv_btn_set_ink_in_time_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * btn, uint16_t time)
{
(void)module_inst;
lv_btn_set_ink_in_time(btn, time);
}
static void
lv_btn_set_ink_out_time_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * btn, uint16_t time)
{
(void)module_inst;
lv_btn_set_ink_out_time(btn, time);
}
static void
lv_btn_set_ink_wait_time_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * btn, uint16_t time)
{
(void)module_inst;
lv_btn_set_ink_wait_time(btn, time);
}
static uint16_t
lv_btn_get_ink_in_time_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * btn)
{
(void)module_inst;
return lv_btn_get_ink_in_time(btn);
}
static uint16_t
lv_btn_get_ink_out_time_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * btn)
{
(void)module_inst;
return lv_btn_get_ink_out_time(btn);
}
static uint16_t
lv_btn_get_ink_wait_time_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * btn)
{
(void)module_inst;
return lv_btn_get_ink_wait_time(btn);
}
static lv_btn_state_t
lv_btn_get_state_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * btn)
{
(void)module_inst;
return lv_btn_get_state(btn);
}
static bool
lv_btn_get_toggle_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * btn)
{
(void)module_inst;
return lv_btn_get_toggle(btn);
}
static void
lv_btn_toggle_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * btn)
{
(void)module_inst;
lv_btn_toggle(btn);
}
static WGLNativeFuncDef btn_native_func_defs[] = {
{ BTN_FUNC_ID_CREATE, lv_btn_create_wrapper, HAS_RET, 3, {1 | NULL_OK, 2 | NULL_OK, -1}, {-1} },
{ BTN_FUNC_ID_SET_TOGGLE, lv_btn_set_toggle_wrapper, NO_RET, 3, {1, -1}, {-1} },
{ BTN_FUNC_ID_SET_STATE, lv_btn_set_state_wrapper, NO_RET, 3, {1, -1}, {-1} },
// { BTN_FUNC_ID_SET_STYLE, _btn_set_style, NO_RET, 2, {0, -1}, {-1} },
{ BTN_FUNC_ID_SET_INK_IN_TIME, lv_btn_set_ink_in_time_wrapper, NO_RET, 3, {1, -1}, {-1} },
{ BTN_FUNC_ID_SET_INK_OUT_TIME, lv_btn_set_ink_out_time_wrapper, NO_RET, 3, {1, -1}, {-1} },
{ BTN_FUNC_ID_SET_INK_WAIT_TIME, lv_btn_set_ink_wait_time_wrapper, NO_RET, 3, {1, -1}, {-1} },
{ BTN_FUNC_ID_GET_INK_IN_TIME, lv_btn_get_ink_in_time_wrapper, HAS_RET, 2, {1, -1}, {-1} },
{ BTN_FUNC_ID_GET_INK_OUT_TIME, lv_btn_get_ink_out_time_wrapper, HAS_RET, 2, {1, -1}, {-1} },
{ BTN_FUNC_ID_GET_INK_WAIT_TIME, lv_btn_get_ink_wait_time_wrapper, HAS_RET, 2, {1, -1}, {-1} },
{ BTN_FUNC_ID_GET_STATE, lv_btn_get_state_wrapper, HAS_RET, 2, {1, -1}, {-1} },
{ BTN_FUNC_ID_GET_TOGGLE, lv_btn_get_toggle_wrapper, HAS_RET, 2, {1, -1}, {-1} },
{ BTN_FUNC_ID_TOGGLE, lv_btn_toggle_wrapper, NO_RET, 2, {1, -1}, {-1} },
};
/*************** Native Interface to Wasm App ***********/
void
wasm_btn_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 size = sizeof(btn_native_func_defs) / sizeof(WGLNativeFuncDef);
wgl_native_func_call(module_inst,
btn_native_func_defs,
size,
func_id,
argv_offset,
argc);
}

View File

@ -0,0 +1,87 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "lvgl.h"
#include "wasm_export.h"
#include "native_interface.h"
#include "module_wasm_app.h"
#include "wgl_native_utils.h"
/* -------------------------------------------------------------------------
* Label widget native function wrappers
* -------------------------------------------------------------------------*/
static int32
lv_cb_create_wrapper(wasm_module_inst_t module_inst,
lv_obj_t *par, lv_obj_t *copy)
{
return wgl_native_wigdet_create(WIDGET_TYPE_CB, par, copy, module_inst);
}
static void
lv_cb_set_text_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * cb, const char * txt)
{
(void)module_inst;
lv_cb_set_text(cb, txt);
}
static void
lv_cb_set_static_text_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * cb, const char * txt)
{
(void)module_inst;
lv_cb_set_static_text(cb, txt);
}
static int32
lv_cb_get_text_length_wrapper(wasm_module_inst_t module_inst,
lv_obj_t *cb)
{
const char *text = lv_cb_get_text(cb);
if (text == NULL)
return 0;
return strlen(text);
}
static char *
lv_cb_get_text_wrapper(wasm_module_inst_t module_inst,
lv_obj_t *cb, char *buffer, int buffer_len)
{
const char *text = lv_cb_get_text(cb);
if (text == NULL)
return 0;
strncpy(buffer, text, buffer_len - 1);
buffer[buffer_len - 1] = '\0';
return buffer;
}
static WGLNativeFuncDef cb_native_func_defs[] = {
{ CB_FUNC_ID_CREATE, lv_cb_create_wrapper, HAS_RET, 3, {1 | NULL_OK, 2 | NULL_OK, -1}, {-1} },
{ CB_FUNC_ID_SET_TEXT, lv_cb_set_text_wrapper, NO_RET, 3, {1, -1}, {2, -1} },
{ CB_FUNC_ID_SET_STATIC_TEXT, lv_cb_set_static_text_wrapper, NO_RET, 3, {1, -1}, {2, -1} },
{ CB_FUNC_ID_GET_TEXT_LENGTH, lv_cb_get_text_length_wrapper, HAS_RET, 2, {1, -1}, {-1} },
{ CB_FUNC_ID_GET_TEXT, lv_cb_get_text_wrapper, RET_PTR, 4, {1, -1}, {2, -1} },
};
/*************** Native Interface to Wasm App ***********/
void
wasm_cb_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 size = sizeof(cb_native_func_defs) / sizeof(WGLNativeFuncDef);
wgl_native_func_call(module_inst,
cb_native_func_defs,
size,
func_id,
argv_offset,
argc);
}

View File

@ -0,0 +1,7 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "lvgl.h"
#include "module_wasm_app.h"

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "lvgl.h"
#include "wasm_export.h"
#include "native_interface.h"
#include "module_wasm_app.h"
#include "wgl_native_utils.h"
/* -------------------------------------------------------------------------
* Label widget native function wrappers
* -------------------------------------------------------------------------*/
static int32
lv_label_create_wrapper(wasm_module_inst_t module_inst,
lv_obj_t *par, lv_obj_t *copy)
{
return wgl_native_wigdet_create(WIDGET_TYPE_LABEL, par, copy, module_inst);
}
static void
lv_label_set_text_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * label, const char * text)
{
(void)module_inst;
lv_label_set_text(label, text);
}
static int32
lv_label_get_text_length_wrapper(wasm_module_inst_t module_inst,
lv_obj_t *label)
{
char *text = lv_label_get_text(label);
if (text == NULL)
return 0;
return strlen(text);
}
static char *
lv_label_get_text_wrapper(wasm_module_inst_t module_inst,
lv_obj_t *label, char *buffer, int buffer_len)
{
char *text = lv_label_get_text(label);
if (text == NULL)
return 0;
strncpy(buffer, text, buffer_len - 1);
buffer[buffer_len - 1] = '\0';
return buffer;
}
static WGLNativeFuncDef label_native_func_defs[] = {
{ LABEL_FUNC_ID_CREATE, lv_label_create_wrapper, HAS_RET, 3, {1 | NULL_OK, 2 | NULL_OK, -1}, {-1} },
{ LABEL_FUNC_ID_SET_TEXT, lv_label_set_text_wrapper, NO_RET, 3, {1, -1}, {2, -1} },
{ LABEL_FUNC_ID_GET_TEXT_LENGTH, lv_label_get_text_length_wrapper, HAS_RET, 2, {1, -1}, {-1} },
{ LABEL_FUNC_ID_GET_TEXT, lv_label_get_text_wrapper, RET_PTR, 4, {1, -1}, {2, -1} },
};
/*************** Native Interface to Wasm App ***********/
void
wasm_label_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 size = sizeof(label_native_func_defs) / sizeof(WGLNativeFuncDef);
wgl_native_func_call(module_inst,
label_native_func_defs,
size,
func_id,
argv_offset,
argc);
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "native_interface.h"
#include "lvgl.h"
#include "module_wasm_app.h"
#include "wgl_native_utils.h"
#include "bh_assert.h"
/* -------------------------------------------------------------------------
* List widget native function wrappers
* -------------------------------------------------------------------------*/
static int32
lv_list_create_wrapper(wasm_module_inst_t module_inst,
lv_obj_t *par, lv_obj_t *copy)
{
return wgl_native_wigdet_create(WIDGET_TYPE_LIST, par, copy, module_inst);
}
static int32
lv_list_add_btn_wrapper(wasm_module_inst_t module_inst,
lv_obj_t *list, const char *text)
{
uint32 btn_obj_id;
lv_obj_t *btn;
uint32 mod_id;
btn = lv_list_add_btn(list, NULL, text);
if (btn == NULL)
return 0;
mod_id = app_manager_get_module_id(Module_WASM_App, module_inst);
bh_assert(mod_id != ID_NONE);
if (wgl_native_add_object(btn, mod_id, &btn_obj_id))
return btn_obj_id; /* success return */
return 0;
}
static WGLNativeFuncDef list_native_func_defs[] = {
{ LIST_FUNC_ID_CREATE, lv_list_create_wrapper, HAS_RET, 3, {1 | NULL_OK, 2 | NULL_OK, -1}, {-1} },
{ LIST_FUNC_ID_ADD_BTN, lv_list_add_btn_wrapper, HAS_RET, 3, {1, -1}, {2, -1} },
};
/*************** Native Interface to Wasm App ***********/
void
wasm_list_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 size = sizeof(list_native_func_defs) / sizeof(WGLNativeFuncDef);
wgl_native_func_call(module_inst,
list_native_func_defs,
size,
func_id,
argv_offset,
argc);
}

View File

@ -0,0 +1,215 @@
#include "wgl_native_utils.h"
#include "lvgl.h"
#include "module_wasm_app.h"
#include "wasm_export.h"
#include "bh_assert.h"
#include <stdint.h>
#define THROW_EXC(msg) wasm_runtime_set_exception(module_inst, msg);
void
wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
uint32 wgl_native_wigdet_create(int8 widget_type, lv_obj_t *par, lv_obj_t *copy,
wasm_module_inst_t module_inst)
{
uint32 obj_id;
lv_obj_t *wigdet = NULL;
uint32 mod_id;
//TODO: limit total widget number
if (par == NULL)
par = lv_disp_get_scr_act(NULL);
if (widget_type == WIDGET_TYPE_BTN)
wigdet = lv_btn_create(par, copy);
else if (widget_type == WIDGET_TYPE_LABEL)
wigdet = lv_label_create(par, copy);
else if (widget_type == WIDGET_TYPE_CB)
wigdet = lv_cb_create(par, copy);
else if (widget_type == WIDGET_TYPE_LIST)
wigdet = lv_list_create(par, copy);
else if (widget_type == WIDGET_TYPE_DDLIST)
wigdet = lv_ddlist_create(par, copy);
if (wigdet == NULL)
return 0;
mod_id = app_manager_get_module_id(Module_WASM_App, module_inst);
bh_assert(mod_id != ID_NONE);
if (wgl_native_add_object(wigdet, mod_id, &obj_id))
return obj_id; /* success return */
return 0;
}
static void invokeNative(intptr_t argv[], uint32 argc, void (*native_code)())
{
bh_assert(argc >= 1);
switch(argc) {
case 1:
native_code(argv[0]);
break;
case 2:
native_code(argv[0], argv[1]);
break;
case 3:
native_code(argv[0], argv[1], argv[2]);
break;
case 4:
native_code(argv[0], argv[1], argv[2], argv[3]);
break;
case 5:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4]);
break;
case 6:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
break;
case 7:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
argv[6]);
break;
case 8:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
argv[6], argv[7]);
break;
case 9:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
argv[6], argv[7], argv[8]);
break;
case 10:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
argv[6], argv[7], argv[8], argv[9]);
break;
default:
{
/* FIXME: If this happen, add more cases. */
wasm_module_inst_t module_inst = (wasm_module_inst_t)argv[0];
THROW_EXC("the argument number of native function exceeds maximum");
return;
}
}
}
typedef void (*GenericFunctionPointer)();
typedef int32 (*Int32FuncPtr)(intptr_t *, uint32, GenericFunctionPointer);
typedef void (*VoidFuncPtr)(intptr_t *, uint32, GenericFunctionPointer);
static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative;
static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
void wgl_native_func_call(wasm_module_inst_t module_inst,
WGLNativeFuncDef *funcs,
uint32 size,
int32 func_id,
uint32 argv_offset,
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) {
int i, obj_arg_num = 0, ptr_arg_num = 0, argc1 = 0;
intptr_t argv_copy_buf[16];
intptr_t *argv_copy = argv_copy_buf;
argc1++; /* module_inst */
argc1 += func_def->arg_num;
if (argc1 > 16) {
argv_copy = (intptr_t *)bh_malloc(func_def->arg_num *
sizeof(intptr_t));
if (argv_copy == NULL)
return;
}
/* Init argv_copy */
argv_copy[0] = (intptr_t)module_inst;
for (i = 0; i < func_def->arg_num; i++)
argv_copy[i + 1] = (intptr_t)argv[i];
/* Validate object arguments */
i = 0;
for (; i < OBJ_ARG_NUM_MAX && func_def->obj_arg_indexes[i] != 0xff;
i++, obj_arg_num++) {
uint8 index = func_def->obj_arg_indexes[i];
bool null_ok = index & NULL_OK;
index = index & (~NULL_OK);
/* Some API's allow to pass NULL obj, such as xxx_create() */
if (argv_copy[index] == 0) {
if (!null_ok) {
THROW_EXC("the object id is 0 and invalid");
goto fail;
}
/* Continue so that to pass null object validation */
continue;
}
if (!wgl_native_validate_object(argv_copy[index],
(lv_obj_t **)&argv_copy[index])) {
THROW_EXC("the object is invalid");
goto fail;
}
}
/* Validate address arguments */
i = 0;
for (; i < PTR_ARG_NUM_MAX && func_def->ptr_arg_indexes[i] != 0xff;
i++, ptr_arg_num++) {
uint8 index = func_def->ptr_arg_indexes[i];
/* The index+1 arg is the data size to be validated */
if (!validate_app_addr(argv_copy[index], argv_copy[index + 1]))
goto fail;
/* Convert to native address before call lvgl function */
argv_copy[index] = (intptr_t)addr_app_to_native(argv_copy[index]);
}
if (func_def->has_ret == NO_RET)
invokeNative_Void(argv_copy,
argc1,
func_def->func_ptr);
else {
argv[0] = invokeNative_Int32(argv_copy,
argc1,
func_def->func_ptr);
/* Convert to app memory offset if return value is a
* native address pointer */
if (func_def->has_ret == RET_PTR)
argv[0] = addr_native_to_app((char *)(intptr_t)argv[0]);
}
if (argv_copy != argv_copy_buf)
bh_free(argv_copy);
/* success return */
return;
fail:
if (argv_copy != argv_copy_buf)
bh_free(argv_copy);
return;
}
func_def++;
}
THROW_EXC("the native widget function is not found!");
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef WAMR_GRAPHIC_LIBRARY_NATIVE_UTILS_H
#define WAMR_GRAPHIC_LIBRARY_NATIVE_UTILS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_platform.h"
#include "lvgl.h"
#include "wasm_export.h"
#include "bi-inc/wgl_shared_utils.h"
#define OBJ_ARG_NUM_MAX 4
#define PTR_ARG_NUM_MAX 4
#define NULL_OK 0x80
enum {
/* The function has a normal return value (not a pointer) */
HAS_RET,
/* The function doesn't have return value */
NO_RET,
/* The function's return value is a native address pointer */
RET_PTR
};
enum {
WIDGET_TYPE_BTN,
WIDGET_TYPE_LABEL,
WIDGET_TYPE_CB,
WIDGET_TYPE_LIST,
WIDGET_TYPE_DDLIST,
_WIDGET_TYPE_NUM,
};
typedef struct WGLNativeFuncDef {
/* Function id */
int32 func_id;
/* Native function pointer */
void *func_ptr;
/* whether has return value */
uint8 has_ret;
/* argument number */
uint8 arg_num;
/* low 7 bit: obj argument index
* highest 1 bit: allow obj be null or not
* -1 means the end of this array */
uint8 obj_arg_indexes[OBJ_ARG_NUM_MAX];
/* pointer argument indexes, -1 means the end of this array */
uint8 ptr_arg_indexes[PTR_ARG_NUM_MAX];
} WGLNativeFuncDef;
bool wgl_native_validate_object(int32 obj_id, lv_obj_t **obj);
bool wgl_native_add_object(lv_obj_t *obj, uint32 module_id, uint32 *obj_id);
uint32 wgl_native_wigdet_create(int8 widget_type,
lv_obj_t *par,
lv_obj_t *copy,
wasm_module_inst_t module_inst);
void wgl_native_func_call(wasm_module_inst_t module_inst,
WGLNativeFuncDef *funcs,
uint32 size,
int32 func_id,
uint32 argv_offset,
uint32 argc);
#ifdef __cplusplus
}
#endif
#endif /* WAMR_GRAPHIC_LIBRARY_NATIVE_UTILS_H */

View File

@ -0,0 +1,389 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "lvgl.h"
#include "app_manager_export.h"
#include "module_wasm_app.h"
#include "bh_list.h"
#include "bh_thread.h"
#include "wgl_native_utils.h"
#include "wgl.h"
typedef struct {
bh_list_link l;
/* The object id. */
uint32 obj_id;
/* The lv object */
lv_obj_t *obj;
/* Module id that the obj belongs to */
uint32 module_id;
} object_node_t;
typedef struct {
int32 obj_id;
lv_event_t event;
} object_event_t;
/* Max obj id */
static uint32 g_obj_id_max = 0;
static bh_list g_object_list;
static korp_mutex g_object_list_mutex;
static bool lv_task_handler_thread_run = true;
static void app_mgr_object_event_callback(module_data *m_data, bh_message_t msg)
{
uint32 argv[2];
wasm_function_inst_t func_on_object_event;
bh_assert(WIDGET_EVENT_WASM == bh_message_type(msg));
wasm_data *wasm_app_data = (wasm_data*)m_data->internal_data;
wasm_module_inst_t inst = wasm_app_data->wasm_module_inst;
object_event_t *object_event
= (object_event_t *)bh_message_payload(msg);
if (object_event == NULL)
return;
func_on_object_event = wasm_runtime_lookup_function(inst, "_on_widget_event",
"(i32i32)");
if (!func_on_object_event)
func_on_object_event = wasm_runtime_lookup_function(inst, "on_widget_event",
"(i32i32)");
if (!func_on_object_event) {
printf("Cannot find function on_widget_event\n");
return;
}
argv[0] = object_event->obj_id;
argv[1] = object_event->event;
if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_on_object_event,
2, argv)) {
const char *exception = wasm_runtime_get_exception(inst);
bh_assert(exception);
printf(":Got exception running wasm code: %s\n",
exception);
wasm_runtime_clear_exception(inst);
return;
}
}
static void cleanup_object_list(uint32 module_id)
{
object_node_t *elem;
vm_mutex_lock(&g_object_list_mutex);
while (true) {
bool found = false;
elem = (object_node_t *)bh_list_first_elem(&g_object_list);
while (elem) {
/* delete the leaf node belongs to the module firstly */
if (module_id == elem->module_id &&
lv_obj_count_children(elem->obj) == 0) {
object_node_t *next = (object_node_t *)bh_list_elem_next(elem);
found = true;
lv_obj_del(elem->obj);
bh_list_remove(&g_object_list, elem);
bh_free(elem);
elem = next;
} else {
elem = (object_node_t *)bh_list_elem_next(elem);
}
}
if (!found)
break;
}
vm_mutex_unlock(&g_object_list_mutex);
}
static bool init_object_event_callback_framework()
{
if (!wasm_register_cleanup_callback(cleanup_object_list)) {
goto fail;
}
if (!wasm_register_msg_callback(WIDGET_EVENT_WASM,
app_mgr_object_event_callback)) {
goto fail;
}
return true;
fail:
return false;
}
bool wgl_native_validate_object(int32 obj_id, lv_obj_t **obj)
{
object_node_t *elem;
vm_mutex_lock(&g_object_list_mutex);
elem = (object_node_t *)bh_list_first_elem(&g_object_list);
while (elem) {
if (obj_id == elem->obj_id) {
if (obj != NULL)
*obj = elem->obj;
vm_mutex_unlock(&g_object_list_mutex);
return true;
}
elem = (object_node_t *) bh_list_elem_next(elem);
}
vm_mutex_unlock(&g_object_list_mutex);
return false;
}
bool wgl_native_add_object(lv_obj_t *obj, uint32 module_id, uint32 *obj_id)
{
object_node_t *node;
node = (object_node_t *) bh_malloc(sizeof(object_node_t));
if (node == NULL)
return false;
/* Generate an obj id */
g_obj_id_max++;
if (g_obj_id_max == -1)
g_obj_id_max = 1;
memset(node, 0, sizeof(*node));
node->obj = obj;
node->obj_id = g_obj_id_max;
node->module_id = module_id;
vm_mutex_lock(&g_object_list_mutex);
bh_list_insert(&g_object_list, node);
vm_mutex_unlock(&g_object_list_mutex);
if (obj_id != NULL)
*obj_id = node->obj_id;
return true;
}
static void _obj_del_recursive(lv_obj_t *obj)
{
object_node_t *elem;
lv_obj_t * i;
lv_obj_t * i_next;
i = lv_ll_get_head(&(obj->child_ll));
while (i != NULL) {
/*Get the next object before delete this*/
i_next = lv_ll_get_next(&(obj->child_ll), i);
/*Call the recursive del to the child too*/
_obj_del_recursive(i);
/*Set i to the next node*/
i = i_next;
}
vm_mutex_lock(&g_object_list_mutex);
elem = (object_node_t *)bh_list_first_elem(&g_object_list);
while (elem) {
if (obj == elem->obj) {
bh_list_remove(&g_object_list, elem);
bh_free(elem);
vm_mutex_unlock(&g_object_list_mutex);
return;
}
elem = (object_node_t *) bh_list_elem_next(elem);
}
vm_mutex_unlock(&g_object_list_mutex);
}
static void _obj_clean_recursive(lv_obj_t *obj)
{
lv_obj_t * i;
lv_obj_t * i_next;
i = lv_ll_get_head(&(obj->child_ll));
while (i != NULL) {
/*Get the next object before delete this*/
i_next = lv_ll_get_next(&(obj->child_ll), i);
/*Call the recursive del to the child too*/
_obj_del_recursive(i);
/*Set i to the next node*/
i = i_next;
}
}
static void post_widget_msg_to_module(object_node_t *object_node, lv_event_t event)
{
module_data *module = module_data_list_lookup_id(object_node->module_id);
object_event_t *object_event;
if (module == NULL)
return;
object_event = (object_event_t *)bh_malloc(sizeof(*object_event));
if (object_event == NULL)
return;
memset(object_event, 0, sizeof(*object_event));
object_event->obj_id = object_node->obj_id;
object_event->event = event;
bh_post_msg(module->queue,
WIDGET_EVENT_WASM,
object_event,
sizeof(*object_event));
}
static void internal_lv_obj_event_cb(lv_obj_t *obj, lv_event_t event)
{
object_node_t *elem;
vm_mutex_lock(&g_object_list_mutex);
elem = (object_node_t *)bh_list_first_elem(&g_object_list);
while (elem) {
if (obj == elem->obj) {
post_widget_msg_to_module(elem, event);
vm_mutex_unlock(&g_object_list_mutex);
return;
}
elem = (object_node_t *) bh_list_elem_next(elem);
}
vm_mutex_unlock(&g_object_list_mutex);
}
static void* lv_task_handler_thread_routine (void *arg)
{
korp_sem sem;
vm_sem_init(&sem, 0);
while (lv_task_handler_thread_run) {
vm_sem_reltimedwait(&sem, 100);
lv_task_handler();
}
vm_sem_destroy(&sem);
return NULL;
}
void wgl_init(void)
{
korp_thread tid;
lv_init();
bh_list_init(&g_object_list);
vm_recursive_mutex_init(&g_object_list_mutex);
init_object_event_callback_framework();
/* new a thread, call lv_task_handler periodically */
vm_thread_create(&tid,
lv_task_handler_thread_routine,
NULL,
BH_APPLET_PRESERVED_STACK_SIZE);
}
void wgl_exit(void)
{
lv_task_handler_thread_run = false;
}
/* -------------------------------------------------------------------------
* Obj native function wrappers
* -------------------------------------------------------------------------*/
static lv_res_t
lv_obj_del_wrapper(wasm_module_inst_t module_inst, lv_obj_t *obj)
{
(void)module_inst;
/* Recursively delete object node in the list belong to this
* parent object including itself */
_obj_del_recursive(obj);
return lv_obj_del(obj);
}
static void
lv_obj_del_async_wrapper(wasm_module_inst_t module_inst, lv_obj_t * obj)
{
(void)module_inst;
lv_obj_del_async(obj);
}
static void
lv_obj_clean_wrapper(wasm_module_inst_t module_inst, lv_obj_t *obj)
{
(void)module_inst;
/* Recursively delete child object node in the list belong to this
* parent object */
_obj_clean_recursive(obj);
/* Delete all of its children */
lv_obj_clean(obj);
}
static void
lv_obj_align_wrapper(wasm_module_inst_t module_inst,
lv_obj_t * obj,
const lv_obj_t * base,
lv_align_t align,
lv_coord_t x_mod,
lv_coord_t y_mod)
{
(void)module_inst;
lv_obj_align(obj, base, align, x_mod, y_mod);
}
static void
lv_obj_set_event_cb_wrapper(wasm_module_inst_t module_inst, lv_obj_t *obj)
{
(void)module_inst;
lv_obj_set_event_cb(obj, internal_lv_obj_event_cb);
}
/* ------------------------------------------------------------------------- */
static WGLNativeFuncDef obj_native_func_defs[] = {
{ OBJ_FUNC_ID_DEL, lv_obj_del_wrapper, HAS_RET, 2, {1, -1}, {-1} },
{ OBJ_FUNC_ID_DEL_ASYNC, lv_obj_del_async_wrapper, NO_RET, 2, {1, -1}, {-1} },
{ OBJ_FUNC_ID_CLEAN, lv_obj_clean_wrapper, NO_RET, 2, {1, -1}, {-1} },
{ OBJ_FUNC_ID_ALIGN, lv_obj_align_wrapper, NO_RET, 6, {1, 2 | NULL_OK, -1}, {-1} },
{ OBJ_FUNC_ID_SET_EVT_CB, lv_obj_set_event_cb_wrapper, NO_RET, 2, {1, -1}, {-1} },
};
/*************** Native Interface to Wasm App ***********/
void
wasm_obj_native_call(wasm_exec_env_t exec_env,
int32 func_id, uint32 argv_offset, uint32 argc)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
uint32 size = sizeof(obj_native_func_defs) / sizeof(WGLNativeFuncDef);
wgl_native_func_call(module_inst,
obj_native_func_defs,
size,
func_id,
argv_offset,
argc);
}